mirror of
https://github.com/WJQSERVER-STUDIO/ghproxy.git
synced 2026-02-03 08:11:11 +08:00
25w14t-2
This commit is contained in:
parent
bd666e08d1
commit
785a74dfeb
14 changed files with 241 additions and 126 deletions
12
auth/auth.go
12
auth/auth.go
|
|
@ -18,10 +18,18 @@ var (
|
|||
|
||||
func Init(cfg *config.Config) {
|
||||
if cfg.Blacklist.Enabled {
|
||||
InitBlacklist(cfg)
|
||||
err := InitBlacklist(cfg)
|
||||
if err != nil {
|
||||
logError(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
if cfg.Whitelist.Enabled {
|
||||
LoadWhitelist(cfg)
|
||||
err := InitWhitelist(cfg)
|
||||
if err != nil {
|
||||
logError(err.Error())
|
||||
return
|
||||
}
|
||||
}
|
||||
logDebug("Auth Init")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -2,58 +2,90 @@ package auth
|
|||
|
||||
import (
|
||||
"encoding/json"
|
||||
"fmt"
|
||||
"ghproxy/config"
|
||||
"os"
|
||||
"strings"
|
||||
"sync"
|
||||
)
|
||||
|
||||
type WhitelistConfig struct {
|
||||
Whitelist []string `json:"whitelist"`
|
||||
// Whitelist 用于存储白名单信息
|
||||
type Whitelist struct {
|
||||
userSet map[string]struct{} // 用户级白名单
|
||||
repoSet map[string]map[string]struct{} // 仓库级白名单
|
||||
initOnce sync.Once // 确保初始化只执行一次
|
||||
initialized bool // 初始化状态标识
|
||||
}
|
||||
|
||||
var (
|
||||
whitelistfile = "/data/ghproxy/config/whitelist.json"
|
||||
whitelist *WhitelistConfig
|
||||
whitelistInstance *Whitelist
|
||||
whitelistInitErr error
|
||||
)
|
||||
|
||||
func LoadWhitelist(cfg *config.Config) {
|
||||
whitelistfile = cfg.Whitelist.WhitelistFile
|
||||
whitelist = &WhitelistConfig{}
|
||||
// InitWhitelist 初始化白名单(线程安全,仅执行一次)
|
||||
func InitWhitelist(cfg *config.Config) error {
|
||||
whitelistInstance = &Whitelist{
|
||||
userSet: make(map[string]struct{}),
|
||||
repoSet: make(map[string]map[string]struct{}),
|
||||
}
|
||||
|
||||
data, err := os.ReadFile(whitelistfile)
|
||||
data, err := os.ReadFile(cfg.Whitelist.WhitelistFile)
|
||||
if err != nil {
|
||||
logError("Failed to read whitelist file: %v", err)
|
||||
return fmt.Errorf("failed to read whitelist: %w", err)
|
||||
}
|
||||
|
||||
err = json.Unmarshal(data, whitelist)
|
||||
if err != nil {
|
||||
logError("Failed to unmarshal whitelist JSON: %v", err)
|
||||
var list struct {
|
||||
Entries []string `json:"whitelist"`
|
||||
}
|
||||
}
|
||||
|
||||
func CheckWhitelist(fullrepo string, user string, repo string) bool {
|
||||
return forRangeCheckWhitelist(whitelist.Whitelist, fullrepo, user)
|
||||
}
|
||||
|
||||
func sliceRepoName_Whitelist(fullrepo string) (string, string) {
|
||||
s := strings.Split(fullrepo, "/")
|
||||
if len(s) != 2 {
|
||||
return "", ""
|
||||
if err := json.Unmarshal(data, &list); err != nil {
|
||||
return fmt.Errorf("invalid whitelist format: %w", err)
|
||||
}
|
||||
return s[0], s[1]
|
||||
}
|
||||
|
||||
func forRangeCheckWhitelist(wlist []string, fullrepo string, user string) bool {
|
||||
for _, passd := range wlist {
|
||||
users, _ := sliceRepoName_Whitelist(passd)
|
||||
if users == user {
|
||||
if strings.HasSuffix(passd, "/*") {
|
||||
return true
|
||||
}
|
||||
if fullrepo == passd {
|
||||
return true
|
||||
for _, entry := range list.Entries {
|
||||
user, repo := splitUserRepoWhitelist(entry)
|
||||
switch {
|
||||
case repo == "" || repo == "*":
|
||||
whitelistInstance.userSet[user] = struct{}{}
|
||||
default:
|
||||
if _, exists := whitelistInstance.repoSet[user]; !exists {
|
||||
whitelistInstance.repoSet[user] = make(map[string]struct{})
|
||||
}
|
||||
whitelistInstance.repoSet[user][repo] = struct{}{}
|
||||
}
|
||||
}
|
||||
|
||||
whitelistInstance.initialized = true
|
||||
return nil
|
||||
}
|
||||
|
||||
// CheckWhitelist 检查用户和仓库是否在白名单中(无锁设计)
|
||||
func CheckWhitelist(username, repo string) bool {
|
||||
if whitelistInstance == nil || !whitelistInstance.initialized {
|
||||
return false
|
||||
}
|
||||
|
||||
// 先检查用户级白名单
|
||||
if _, exists := whitelistInstance.userSet[username]; exists {
|
||||
return true
|
||||
}
|
||||
|
||||
// 再检查仓库级白名单
|
||||
if repos, userExists := whitelistInstance.repoSet[username]; userExists {
|
||||
// 允许仓库名为空时的全用户仓库匹配
|
||||
if repo == "" {
|
||||
return true
|
||||
}
|
||||
_, repoExists := repos[repo]
|
||||
return repoExists
|
||||
}
|
||||
|
||||
return false
|
||||
}
|
||||
|
||||
// splitUserRepoWhitelist 分割用户和仓库信息(仅初始化时使用)
|
||||
func splitUserRepoWhitelist(fullRepo string) (user, repo string) {
|
||||
if idx := strings.Index(fullRepo, "/"); idx > 0 {
|
||||
return fullRepo[:idx], fullRepo[idx+1:]
|
||||
}
|
||||
return fullRepo, ""
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue