2025-03-18 17:57:07 +08:00
|
|
|
package services
|
|
|
|
|
|
|
|
|
|
import (
|
|
|
|
|
"context"
|
|
|
|
|
"errors"
|
|
|
|
|
"platform/web/models"
|
|
|
|
|
)
|
|
|
|
|
|
|
|
|
|
var Auth = &authService{}
|
|
|
|
|
|
|
|
|
|
type AuthServiceError string
|
|
|
|
|
|
|
|
|
|
func (e AuthServiceError) Error() string {
|
|
|
|
|
return string(e)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type AuthServiceOauthError string
|
|
|
|
|
|
|
|
|
|
func (e AuthServiceOauthError) Error() string {
|
|
|
|
|
return string(e)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var (
|
|
|
|
|
ErrOauthInvalidRequest = AuthServiceOauthError("invalid_request")
|
|
|
|
|
ErrOauthInvalidClient = AuthServiceOauthError("invalid_client")
|
|
|
|
|
ErrOauthInvalidGrant = AuthServiceOauthError("invalid_grant")
|
|
|
|
|
ErrOauthInvalidScope = AuthServiceOauthError("invalid_scope")
|
|
|
|
|
ErrOauthUnauthorizedClient = AuthServiceOauthError("unauthorized_client")
|
|
|
|
|
ErrOauthUnsupportedGrantType = AuthServiceOauthError("unsupported_grant_type")
|
|
|
|
|
)
|
|
|
|
|
|
2025-03-22 16:37:24 +08:00
|
|
|
type authService struct{}
|
|
|
|
|
|
2025-03-18 17:57:07 +08:00
|
|
|
// OauthAuthorizationCode 验证授权码
|
|
|
|
|
func (s *authService) OauthAuthorizationCode(ctx context.Context, client *models.Client, code, redirectURI, codeVerifier string) (*TokenDetails, error) {
|
|
|
|
|
// TODO: 从数据库验证授权码
|
|
|
|
|
return nil, errors.New("TODO")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// OauthClientCredentials 验证客户端凭证
|
2025-03-22 16:37:24 +08:00
|
|
|
func (s *authService) OauthClientCredentials(ctx context.Context, client *models.Client, scope ...string) (*TokenDetails, error) {
|
2025-03-18 17:57:07 +08:00
|
|
|
|
|
|
|
|
var clientType PayloadType
|
|
|
|
|
switch client.Spec {
|
|
|
|
|
case 0:
|
|
|
|
|
clientType = PayloadClientConfidential
|
|
|
|
|
case 1:
|
|
|
|
|
clientType = PayloadClientPublic
|
|
|
|
|
case 2:
|
2025-03-22 16:37:24 +08:00
|
|
|
clientType = PayloadClientPublic
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
var permissions = make(map[string]struct{}, len(scope))
|
|
|
|
|
for _, item := range scope {
|
|
|
|
|
permissions[item] = struct{}{}
|
2025-03-18 17:57:07 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// 保存会话并返回令牌
|
|
|
|
|
auth := AuthContext{
|
2025-03-22 16:37:24 +08:00
|
|
|
Permissions: permissions,
|
2025-03-18 17:57:07 +08:00
|
|
|
Payload: Payload{
|
|
|
|
|
Id: client.ID,
|
2025-03-28 15:01:30 +08:00
|
|
|
Type: clientType,
|
|
|
|
|
Name: client.Name,
|
2025-03-18 17:57:07 +08:00
|
|
|
},
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// todo 数据库定义会话持续时间
|
|
|
|
|
token, err := Session.Create(ctx, auth)
|
|
|
|
|
if err != nil {
|
|
|
|
|
return nil, err
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return token, nil
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// OauthRefreshToken 验证刷新令牌
|
|
|
|
|
func (s *authService) OauthRefreshToken(ctx context.Context, client *models.Client, refreshToken string, scope ...[]string) (*TokenDetails, error) {
|
|
|
|
|
// TODO: 从数据库验证刷新令牌
|
|
|
|
|
return nil, errors.New("TODO")
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
type GrantType int
|
|
|
|
|
|
|
|
|
|
const (
|
|
|
|
|
GrantTypeAuthorizationCode GrantType = iota
|
|
|
|
|
GrantTypeClientCredentials
|
|
|
|
|
GrantTypeRefreshToken
|
|
|
|
|
)
|