232 lines
7.8 KiB
Go
232 lines
7.8 KiB
Go
/*
|
|
* Copyright 2025 coze-dev Authors
|
|
*
|
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
|
* you may not use this file except in compliance with the License.
|
|
* You may obtain a copy of the License at
|
|
*
|
|
* http://www.apache.org/licenses/LICENSE-2.0
|
|
*
|
|
* Unless required by applicable law or agreed to in writing, software
|
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
* See the License for the specific language governing permissions and
|
|
* limitations under the License.
|
|
*/
|
|
|
|
package openauth
|
|
|
|
import (
|
|
"context"
|
|
"strconv"
|
|
"time"
|
|
|
|
"github.com/pkg/errors"
|
|
|
|
"github.com/coze-dev/coze-studio/backend/api/model/app/bot_open_api"
|
|
openapimodel "github.com/coze-dev/coze-studio/backend/api/model/permission/openapiauth"
|
|
"github.com/coze-dev/coze-studio/backend/application/base/ctxutil"
|
|
openapi "github.com/coze-dev/coze-studio/backend/domain/openauth/openapiauth"
|
|
"github.com/coze-dev/coze-studio/backend/domain/openauth/openapiauth/entity"
|
|
"github.com/coze-dev/coze-studio/backend/pkg/lang/ptr"
|
|
"github.com/coze-dev/coze-studio/backend/pkg/lang/slices"
|
|
"github.com/coze-dev/coze-studio/backend/pkg/logs"
|
|
)
|
|
|
|
type OpenAuthApplicationService struct {
|
|
OpenAPIDomainSVC openapi.APIAuth
|
|
}
|
|
|
|
var OpenAuthApplication = &OpenAuthApplicationService{}
|
|
|
|
func (s *OpenAuthApplicationService) GetPersonalAccessTokenAndPermission(ctx context.Context, req *openapimodel.GetPersonalAccessTokenAndPermissionRequest) (*openapimodel.GetPersonalAccessTokenAndPermissionResponse, error) {
|
|
|
|
resp := new(openapimodel.GetPersonalAccessTokenAndPermissionResponse)
|
|
|
|
userID := ctxutil.GetUIDFromCtx(ctx)
|
|
|
|
appReq := &entity.GetApiKey{
|
|
ID: req.ID,
|
|
}
|
|
apiKeyResp, err := openapiAuthDomainSVC.Get(ctx, appReq)
|
|
|
|
if err != nil {
|
|
logs.CtxErrorf(ctx, "OpenAuthApplicationService.GetPersonalAccessTokenAndPermission failed, err=%v", err)
|
|
return resp, errors.New("GetPersonalAccessTokenAndPermission failed")
|
|
}
|
|
if apiKeyResp == nil {
|
|
return resp, errors.New("GetPersonalAccessTokenAndPermission failed")
|
|
}
|
|
|
|
if apiKeyResp.UserID != *userID {
|
|
return resp, errors.New("permission not match")
|
|
}
|
|
resp.Data = &openapimodel.GetPersonalAccessTokenAndPermissionResponseData{
|
|
PersonalAccessToken: &openapimodel.PersonalAccessToken{
|
|
ID: apiKeyResp.ID,
|
|
Name: apiKeyResp.Name,
|
|
ExpireAt: apiKeyResp.ExpiredAt,
|
|
CreatedAt: apiKeyResp.CreatedAt,
|
|
UpdatedAt: apiKeyResp.UpdatedAt,
|
|
},
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
func (s *OpenAuthApplicationService) CreatePersonalAccessToken(ctx context.Context, req *openapimodel.CreatePersonalAccessTokenAndPermissionRequest) (*openapimodel.CreatePersonalAccessTokenAndPermissionResponse, error) {
|
|
resp := new(openapimodel.CreatePersonalAccessTokenAndPermissionResponse)
|
|
userID := ctxutil.GetUIDFromCtx(ctx)
|
|
|
|
appReq := &entity.CreateApiKey{
|
|
Name: req.Name,
|
|
Expire: req.ExpireAt,
|
|
UserID: *userID,
|
|
AkType: entity.AkTypeCustomer,
|
|
}
|
|
|
|
if req.DurationDay == "customize" {
|
|
appReq.Expire = req.ExpireAt
|
|
} else {
|
|
expireDay, err := strconv.ParseInt(req.DurationDay, 10, 64)
|
|
if err != nil {
|
|
return resp, errors.New("invalid expireDay")
|
|
}
|
|
appReq.Expire = time.Now().Add(time.Duration(expireDay) * time.Hour * 24).Unix()
|
|
}
|
|
|
|
apiKeyResp, err := openapiAuthDomainSVC.Create(ctx, appReq)
|
|
if err != nil {
|
|
logs.CtxErrorf(ctx, "OpenAuthApplicationService.CreatePersonalAccessToken failed, err=%v", err)
|
|
return resp, errors.New("CreatePersonalAccessToken failed")
|
|
}
|
|
resp.Data = &openapimodel.CreatePersonalAccessTokenAndPermissionResponseData{
|
|
PersonalAccessToken: &openapimodel.PersonalAccessToken{
|
|
ID: apiKeyResp.ID,
|
|
Name: apiKeyResp.Name,
|
|
ExpireAt: apiKeyResp.ExpiredAt,
|
|
|
|
CreatedAt: apiKeyResp.CreatedAt,
|
|
UpdatedAt: apiKeyResp.UpdatedAt,
|
|
},
|
|
Token: apiKeyResp.ApiKey,
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
func (s *OpenAuthApplicationService) ImpersonateCozeUserAccessToken(ctx context.Context, req *bot_open_api.ImpersonateCozeUserRequest) (*bot_open_api.ImpersonateCozeUserResponse, error) {
|
|
resp := new(bot_open_api.ImpersonateCozeUserResponse)
|
|
userID := ctxutil.GetUIDFromCtx(ctx)
|
|
|
|
expiredSecond := time.Now().Add(time.Duration(time.Second * 60 * 15)).Unix()
|
|
|
|
appReq := &entity.CreateApiKey{
|
|
UserID: *userID,
|
|
AkType: entity.AkTypeTemporary,
|
|
Expire: expiredSecond,
|
|
Name: "temporary access token",
|
|
}
|
|
|
|
apiKeyResp, err := openapiAuthDomainSVC.Create(ctx, appReq)
|
|
if err != nil {
|
|
logs.CtxErrorf(ctx, "OpenAuthApplicationService.CreatePersonalAccessToken failed, err=%v", err)
|
|
return resp, errors.New("CreatePersonalAccessToken failed")
|
|
}
|
|
resp.Data = &bot_open_api.ImpersonateCozeUserResponseData{
|
|
AccessToken: apiKeyResp.ApiKey,
|
|
ExpiresIn: expiredSecond,
|
|
TokenType: "Bearer",
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
func (s *OpenAuthApplicationService) ListPersonalAccessTokens(ctx context.Context, req *openapimodel.ListPersonalAccessTokensRequest) (*openapimodel.ListPersonalAccessTokensResponse, error) {
|
|
|
|
resp := new(openapimodel.ListPersonalAccessTokensResponse)
|
|
|
|
userID := ctxutil.GetUIDFromCtx(ctx)
|
|
appReq := &entity.ListApiKey{
|
|
UserID: *userID,
|
|
Page: *req.Page,
|
|
Limit: *req.Size,
|
|
}
|
|
|
|
apiKeyResp, err := openapiAuthDomainSVC.List(ctx, appReq)
|
|
if err != nil {
|
|
logs.CtxErrorf(ctx, "OpenAuthApplicationService.ListPersonalAccessTokens failed, err=%v", err)
|
|
return resp, errors.New("ListPersonalAccessTokens failed")
|
|
}
|
|
|
|
if apiKeyResp == nil {
|
|
return resp, nil
|
|
}
|
|
resp.Data = &openapimodel.ListPersonalAccessTokensResponseData{
|
|
HasMore: apiKeyResp.HasMore,
|
|
PersonalAccessTokens: slices.Transform(apiKeyResp.ApiKeys, func(a *entity.ApiKey) *openapimodel.PersonalAccessTokenWithCreatorInfo {
|
|
lastUsedAt := a.LastUsedAt
|
|
if lastUsedAt == 0 {
|
|
lastUsedAt = -1
|
|
}
|
|
return &openapimodel.PersonalAccessTokenWithCreatorInfo{
|
|
ID: a.ID,
|
|
Name: a.Name,
|
|
ExpireAt: a.ExpiredAt,
|
|
CreatedAt: a.CreatedAt,
|
|
UpdatedAt: a.UpdatedAt,
|
|
LastUsedAt: lastUsedAt,
|
|
}
|
|
}),
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
func (s *OpenAuthApplicationService) DeletePersonalAccessTokenAndPermission(ctx context.Context, req *openapimodel.DeletePersonalAccessTokenAndPermissionRequest) (*openapimodel.DeletePersonalAccessTokenAndPermissionResponse, error) {
|
|
resp := new(openapimodel.DeletePersonalAccessTokenAndPermissionResponse)
|
|
|
|
userID := ctxutil.GetUIDFromCtx(ctx)
|
|
|
|
appReq := &entity.DeleteApiKey{
|
|
ID: req.ID,
|
|
UserID: *userID,
|
|
}
|
|
err := openapiAuthDomainSVC.Delete(ctx, appReq)
|
|
if err != nil {
|
|
logs.CtxErrorf(ctx, "OpenAuthApplicationService.DeletePersonalAccessTokenAndPermission failed, err=%v", err)
|
|
return resp, errors.New("DeletePersonalAccessTokenAndPermission failed")
|
|
}
|
|
return resp, nil
|
|
}
|
|
|
|
func (s *OpenAuthApplicationService) UpdatePersonalAccessTokenAndPermission(ctx context.Context, req *openapimodel.UpdatePersonalAccessTokenAndPermissionRequest) (*openapimodel.UpdatePersonalAccessTokenAndPermissionResponse, error) {
|
|
resp := new(openapimodel.UpdatePersonalAccessTokenAndPermissionResponse)
|
|
userID := ctxutil.GetUIDFromCtx(ctx)
|
|
|
|
upErr := openapiAuthDomainSVC.Save(ctx, &entity.SaveMeta{
|
|
ID: req.ID,
|
|
Name: ptr.Of(req.Name),
|
|
UserID: *userID,
|
|
})
|
|
|
|
return resp, upErr
|
|
}
|
|
|
|
func (s *OpenAuthApplicationService) UpdateLastUsedAt(ctx context.Context, apiID int64, userID int64) error {
|
|
upErr := openapiAuthDomainSVC.Save(ctx, &entity.SaveMeta{
|
|
ID: apiID,
|
|
LastUsedAt: ptr.Of(time.Now().Unix()),
|
|
UserID: userID,
|
|
})
|
|
return upErr
|
|
}
|
|
|
|
func (s *OpenAuthApplicationService) CheckPermission(ctx context.Context, token string) (*entity.ApiKey, error) {
|
|
appReq := &entity.CheckPermission{
|
|
ApiKey: token,
|
|
}
|
|
apiKey, err := openapiAuthDomainSVC.CheckPermission(ctx, appReq)
|
|
if err != nil {
|
|
logs.CtxErrorf(ctx, "OpenAuthApplicationService.CheckPermission failed, err=%v", err)
|
|
return nil, errors.New("CheckPermission failed")
|
|
}
|
|
return apiKey, nil
|
|
}
|