1e13af4d6e
Modified - Updated the example app.ini documentation for the new administrator management policies.
107 lines
2.5 KiB
Go
107 lines
2.5 KiB
Go
// Copyright 2026 The Gitea Authors. All rights reserved.
|
|
// SPDX-License-Identifier: MIT
|
|
|
|
package user
|
|
|
|
import (
|
|
"context"
|
|
"strconv"
|
|
)
|
|
|
|
const BootstrapAdminActorName = "GOOD"
|
|
|
|
func getUserSettingInt64(ctx context.Context, userID int64, key string) (int64, bool, error) {
|
|
value, err := GetUserSetting(ctx, userID, key)
|
|
if err != nil {
|
|
if IsErrUserSettingIsNotExist(err) {
|
|
return 0, false, nil
|
|
}
|
|
return 0, false, err
|
|
}
|
|
if value == "" {
|
|
return 0, false, nil
|
|
}
|
|
parsed, err := strconv.ParseInt(value, 10, 64)
|
|
if err != nil {
|
|
return 0, false, err
|
|
}
|
|
return parsed, true, nil
|
|
}
|
|
|
|
func GetAdminGrantorID(ctx context.Context, userID int64) (int64, bool, error) {
|
|
return getUserSettingInt64(ctx, userID, SettingsKeyAdminGrantedBy)
|
|
}
|
|
|
|
func GetSuperAdminGrantorID(ctx context.Context, userID int64) (int64, bool, error) {
|
|
return getUserSettingInt64(ctx, userID, SettingsKeySuperAdminGrantedBy)
|
|
}
|
|
|
|
func HasBootstrapAdminGrant(ctx context.Context, userID int64) (bool, error) {
|
|
for _, key := range []string{SettingsKeyAdminGrantedByName, SettingsKeySuperAdminGrantedByName} {
|
|
value, err := GetUserSetting(ctx, userID, key)
|
|
if err != nil {
|
|
if IsErrUserSettingIsNotExist(err) {
|
|
continue
|
|
}
|
|
return false, err
|
|
}
|
|
if value == BootstrapAdminActorName {
|
|
return true, nil
|
|
}
|
|
}
|
|
return false, nil
|
|
}
|
|
|
|
func IsGrantorOf(ctx context.Context, grantedUserID, possibleGrantorID int64) (bool, error) {
|
|
for _, getter := range []func(context.Context, int64) (int64, bool, error){GetAdminGrantorID, GetSuperAdminGrantorID} {
|
|
grantorID, has, err := getter(ctx, grantedUserID)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
if has && grantorID == possibleGrantorID {
|
|
return true, nil
|
|
}
|
|
}
|
|
return false, nil
|
|
}
|
|
|
|
func IsEligibleAdminGrantor(ctx context.Context, userID int64) (bool, error) {
|
|
u, err := GetUserByID(ctx, userID)
|
|
if err != nil {
|
|
if IsErrUserNotExist(err) {
|
|
return false, nil
|
|
}
|
|
return false, err
|
|
}
|
|
return u.IsAdmin && u.IsActive && !u.ProhibitLogin, nil
|
|
}
|
|
|
|
func GetEffectiveAdminGrantorID(ctx context.Context, userID int64) (int64, bool, error) {
|
|
visited := map[int64]struct{}{userID: {}}
|
|
currentUserID := userID
|
|
|
|
for {
|
|
grantorID, has, err := GetAdminGrantorID(ctx, currentUserID)
|
|
if err != nil {
|
|
return 0, false, err
|
|
}
|
|
if !has {
|
|
return 0, false, nil
|
|
}
|
|
if _, ok := visited[grantorID]; ok {
|
|
return 0, false, nil
|
|
}
|
|
visited[grantorID] = struct{}{}
|
|
|
|
eligible, err := IsEligibleAdminGrantor(ctx, grantorID)
|
|
if err != nil {
|
|
return 0, false, err
|
|
}
|
|
if eligible {
|
|
return grantorID, true, nil
|
|
}
|
|
|
|
currentUserID = grantorID
|
|
}
|
|
}
|