// // Copyright (C) 2024 veypi // 2025-07-24 15:27:31 // Distributed under terms of the MIT license. // package oauth import ( "github.com/vyes-ai/vigo" "gorm.io/gorm" ) var Router = vigo.NewRouter() func init() { // OAuth 授权端点 var _ = Router.Get("/authorize", `OAuth授权端点 - 获取授权码`, AuthorizeRequest{}, handleAuthorize) // OAuth 令牌端点 var _ = Router.Post("/token", `OAuth令牌端点 - 用授权码换取令牌或刷新令牌`, TokenRequest{}, handleToken) // OAuth 撤销端点 var _ = Router.Post("/revoke", `OAuth撤销端点 - 撤销访问令牌或刷新令牌`, RevokeRequest{}, handleRevoke) } // InitializeOAuthData 初始化OAuth相关的基础数据 func InitializeOAuthData(db *gorm.DB) error { // 1. 创建默认的OAuth作用域 if err := createDefaultScopes(db); err != nil { return err } // 2. 创建默认的第三方OAuth提供商 if err := createDefaultProviders(db); err != nil { return err } // 3. 创建默认权限 if err := createDefaultPermissions(db); err != nil { return err } return nil } func createDefaultScopes(db *gorm.DB) error { for _, scopeData := range DefaultScopes { scope := &OAuthScope{ Name: scopeData.Name, DisplayName: scopeData.DisplayName, Description: scopeData.Description, IsDefault: scopeData.IsDefault, IsSystem: scopeData.IsSystem, } // 如果不存在则创建 var existingScope OAuthScope result := db.Where("name = ?", scope.Name).First(&existingScope) if result.Error == gorm.ErrRecordNotFound { if err := db.Create(scope).Error; err != nil { return err } } } return nil } func createDefaultProviders(db *gorm.DB) error { for _, providerData := range DefaultOAuthProviders { provider := &OAuthProvider{ Name: providerData.Name, DisplayName: providerData.DisplayName, AuthURL: providerData.AuthURL, TokenURL: providerData.TokenURL, UserInfoURL: providerData.UserInfoURL, Scope: providerData.Scope, IsActive: false, // 默认不激活,需要配置ClientID和ClientSecret后激活 } // 如果不存在则创建 var existingProvider OAuthProvider result := db.Where("name = ?", provider.Name).First(&existingProvider) if result.Error == gorm.ErrRecordNotFound { if err := db.Create(provider).Error; err != nil { return err } } } return nil } func createDefaultPermissions(db *gorm.DB) error { oauthPermissions := []struct { Name string DisplayName string Description string Resource string Action string IsSystem bool }{ { Name: "oauth.client.create", DisplayName: "创建OAuth客户端", Description: "允许创建新的OAuth客户端应用", Resource: "oauth_client", Action: "create", IsSystem: true, }, { Name: "oauth.client.read", DisplayName: "查看OAuth客户端", Description: "允许查看OAuth客户端信息", Resource: "oauth_client", Action: "read", IsSystem: true, }, { Name: "oauth.client.update", DisplayName: "更新OAuth客户端", Description: "允许更新OAuth客户端信息", Resource: "oauth_client", Action: "update", IsSystem: true, }, { Name: "oauth.client.delete", DisplayName: "删除OAuth客户端", Description: "允许删除OAuth客户端", Resource: "oauth_client", Action: "delete", IsSystem: true, }, { Name: "oauth.token.manage", DisplayName: "管理OAuth令牌", Description: "允许管理用户的OAuth令牌", Resource: "oauth_token", Action: "manage", IsSystem: true, }, { Name: "oauth.scope.manage", DisplayName: "管理OAuth作用域", Description: "允许管理OAuth作用域", Resource: "oauth_scope", Action: "manage", IsSystem: true, }, { Name: "oauth.provider.manage", DisplayName: "管理OAuth提供商", Description: "允许管理第三方OAuth提供商", Resource: "oauth_provider", Action: "manage", IsSystem: true, }, } for _, permData := range oauthPermissions { permission := &Permission{ Name: permData.Name, DisplayName: permData.DisplayName, Description: permData.Description, Resource: permData.Resource, Action: permData.Action, IsSystem: permData.IsSystem, } // 如果不存在则创建 var existingPerm Permission result := db.Where("name = ?", permission.Name).First(&existingPerm) if result.Error == gorm.ErrRecordNotFound { if err := db.Create(permission).Error; err != nil { return err } } } return nil } // CreateDefaultOAuthClient 创建默认的OAuth客户端(用于测试) func CreateDefaultOAuthClient(db *gorm.DB, ownerID string) (*OAuthClient, error) { client := &OAuthClient{ ClientID: "default-client-id", ClientSecret: "default-client-secret", // 实际使用时应该使用加密存储 ClientName: "Default Test Client", ClientURI: "http://localhost:3000", RedirectURIs: `["http://localhost:3000/callback", "http://localhost:8080/callback"]`, ResponseTypes: "code", GrantTypes: "authorization_code,refresh_token", Scope: "profile read write", IsPublic: false, IsActive: true, OwnerID: ownerID, } // 检查是否已存在 var existingClient OAuthClient result := db.Where("client_id = ?", client.ClientID).First(&existingClient) if result.Error == gorm.ErrRecordNotFound { if err := db.Create(client).Error; err != nil { return nil, err } return client, nil } return &existingClient, nil }