You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
OneAuth/oauth/init.go

211 lines
5.6 KiB
Go

3 months ago
//
// Copyright (C) 2024 veypi <i@veypi.com>
// 2025-07-24 15:27:31
// Distributed under terms of the MIT license.
//
package oauth
import (
"github.com/vyes/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
}