gitea/models/organization/org_profile.go
logikonline b816ee4eec feat: add Phases 3-5 enhancements (org profiles, pages, wiki v2 API)
Phase 3: Organization Public Profile Page
- Pinned repositories with groups
- Public members display with roles
- API endpoints for pinned repos and groups

Phase 4: Gitea Pages Foundation
- Landing page templates (simple, docs, product, portfolio)
- Custom domain support with verification
- YAML configuration parser (.gitea/landing.yaml)
- Repository settings UI for pages

Phase 5: Enhanced Wiki System with V2 API
- Full CRUD operations via v2 API
- Full-text search with WikiIndex table
- Link graph visualization
- Wiki health metrics (orphaned, dead links, outdated)
- Designed for external AI plugin integration
- Developer guide for .NET integration

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-09 15:14:27 -05:00

171 lines
4.0 KiB
Go

// Copyright 2026 The Gitea Authors. All rights reserved.
// SPDX-License-Identifier: MIT
package organization
import (
"context"
"code.gitea.io/gitea/models/db"
user_model "code.gitea.io/gitea/models/user"
)
const (
// ProfileRepoName is the name of the special profile repository
ProfileRepoName = ".profile"
// ProfileReadmePath is the path to the profile README
ProfileReadmePath = "README.md"
// ProfileAssetsPath is the path to profile assets
ProfileAssetsPath = "assets/"
// ProfileStylePath is the path to custom CSS
ProfileStylePath = "style.css"
)
// PublicMember represents a public member of an organization for display
type PublicMember struct {
*user_model.User
Role string // "Owner", "Admin", "Member"
}
// GetPublicOrgMembers returns public members of an organization
func GetPublicOrgMembers(ctx context.Context, orgID int64, limit int) ([]*PublicMember, int64, error) {
// Count total public members
total, err := db.GetEngine(ctx).
Where("org_id = ? AND is_public = ?", orgID, true).
Count(new(OrgUser))
if err != nil {
return nil, 0, err
}
// Get public org users
orgUsers := make([]*OrgUser, 0, limit)
sess := db.GetEngine(ctx).
Where("org_id = ? AND is_public = ?", orgID, true)
if limit > 0 {
sess = sess.Limit(limit)
}
if err := sess.Find(&orgUsers); err != nil {
return nil, 0, err
}
if len(orgUsers) == 0 {
return []*PublicMember{}, total, nil
}
// Get user IDs
userIDs := make([]int64, len(orgUsers))
for i, ou := range orgUsers {
userIDs[i] = ou.UID
}
// Load users
users, err := user_model.GetUsersByIDs(ctx, userIDs)
if err != nil {
return nil, 0, err
}
userMap := make(map[int64]*user_model.User)
for _, u := range users {
userMap[u.ID] = u
}
// Get owners team to determine roles
org, err := GetOrgByID(ctx, orgID)
if err != nil {
return nil, 0, err
}
ownersTeam, err := org.GetOwnerTeam(ctx)
if err != nil {
return nil, 0, err
}
ownerIDs := make(map[int64]bool)
if ownersTeam != nil {
if err := ownersTeam.LoadMembers(ctx); err != nil {
return nil, 0, err
}
for _, m := range ownersTeam.Members {
ownerIDs[m.ID] = true
}
}
// Build result with roles
members := make([]*PublicMember, 0, len(orgUsers))
for _, ou := range orgUsers {
user := userMap[ou.UID]
if user == nil {
continue
}
role := "Member"
if ownerIDs[ou.UID] {
role = "Owner"
} else {
// Check if admin (has admin access to any team)
isAdmin, _ := IsOrganizationAdmin(ctx, orgID, ou.UID)
if isAdmin {
role = "Admin"
}
}
members = append(members, &PublicMember{
User: user,
Role: role,
})
}
return members, total, nil
}
// SetMemberPublicVisibility sets the public visibility of a member
func SetMemberPublicVisibility(ctx context.Context, orgID, userID int64, isPublic bool) error {
_, err := db.GetEngine(ctx).
Where("org_id = ? AND uid = ?", orgID, userID).
Cols("is_public").
Update(&OrgUser{IsPublic: isPublic})
return err
}
// GetMemberPublicVisibility gets the public visibility status of a member
func GetMemberPublicVisibility(ctx context.Context, orgID, userID int64) (bool, error) {
orgUser := new(OrgUser)
has, err := db.GetEngine(ctx).
Where("org_id = ? AND uid = ?", orgID, userID).
Get(orgUser)
if err != nil {
return false, err
}
if !has {
return false, nil
}
return orgUser.IsPublic, nil
}
// OrgOverviewStats represents statistics for the organization overview
type OrgOverviewStats struct {
MemberCount int64
RepoCount int64
PublicRepoCount int64
TeamCount int64
}
// GetOrgMemberAndTeamCounts returns member and team counts for an organization
func GetOrgMemberAndTeamCounts(ctx context.Context, orgID int64) (memberCount, teamCount int64, err error) {
memberCount, err = db.GetEngine(ctx).
Where("org_id = ?", orgID).
Count(new(OrgUser))
if err != nil {
return 0, 0, err
}
teamCount, err = db.GetEngine(ctx).
Where("org_id = ?", orgID).
Count(new(Team))
if err != nil {
return 0, 0, err
}
return memberCount, teamCount, nil
}