merge: 合入本地 Ops 扩展与 origin/main(ECR-009–016)
保留远程用户侧 ECR-009–016 与本地 Ops 目录/RBAC/CMS/危机等能力;文档标注分叉期间 ECR 编号冲突。 Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
@@ -6,7 +6,6 @@ import (
|
||||
"crypto/rand"
|
||||
"encoding/hex"
|
||||
"encoding/json"
|
||||
"errors"
|
||||
"time"
|
||||
|
||||
"github.com/google/uuid"
|
||||
@@ -54,13 +53,6 @@ type LoginResult struct {
|
||||
Admin AdminMe `json:"admin"`
|
||||
}
|
||||
|
||||
// AdminMe is the public admin profile.
|
||||
type AdminMe struct {
|
||||
ID uuid.UUID `json:"id"`
|
||||
Username string `json:"username"`
|
||||
Role string `json:"role"`
|
||||
}
|
||||
|
||||
var (
|
||||
ErrBadCredentials = errString("invalid credentials")
|
||||
ErrInvalidPlan = errString("invalid plan")
|
||||
@@ -91,10 +83,14 @@ func (s *Service) Login(ctx context.Context, username, password string) (*LoginR
|
||||
if err := s.Repo.CreateSession(ctx, acc.ID, token, exp); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
me, err := s.Me(ctx, acc.ID)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &LoginResult{
|
||||
Token: token,
|
||||
ExpiresAt: exp,
|
||||
Admin: AdminMe{ID: acc.ID, Username: acc.Username, Role: acc.Role},
|
||||
Admin: *me,
|
||||
}, nil
|
||||
}
|
||||
|
||||
@@ -111,15 +107,6 @@ func (s *Service) Logout(ctx context.Context, token string) error {
|
||||
return s.Repo.DeleteSession(ctx, token)
|
||||
}
|
||||
|
||||
// Me returns the current admin profile.
|
||||
func (s *Service) Me(ctx context.Context, adminID uuid.UUID) (*AdminMe, error) {
|
||||
acc, err := s.Repo.FindAccountByID(ctx, adminID)
|
||||
if err != nil || acc == nil {
|
||||
return nil, errors.New("admin not found")
|
||||
}
|
||||
return &AdminMe{ID: acc.ID, Username: acc.Username, Role: acc.Role}, nil
|
||||
}
|
||||
|
||||
// ListUsers lists terminal users.
|
||||
func (s *Service) ListUsers(ctx context.Context, q string, limit, offset int) ([]repository.UserListItem, error) {
|
||||
return s.Repo.ListUsers(ctx, q, limit, offset)
|
||||
@@ -198,10 +185,7 @@ type GrantInput struct {
|
||||
|
||||
// GrantMembership extends membership and writes audit.
|
||||
func (s *Service) GrantMembership(ctx context.Context, adminID, userID uuid.UUID, plan string) error {
|
||||
if err := s.RequireSuper(ctx, adminID); err != nil {
|
||||
return err
|
||||
}
|
||||
days, err := planDays(plan)
|
||||
days, err := s.PlanDurationDays(ctx, plan)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
@@ -225,9 +209,6 @@ var ErrInvalidAskDelta = errString("invalid ask quota delta")
|
||||
|
||||
// GrantAskQuota adds purchased ask quota and audits.
|
||||
func (s *Service) GrantAskQuota(ctx context.Context, adminID, userID uuid.UUID, delta int) (int, error) {
|
||||
if err := s.RequireSuper(ctx, adminID); err != nil {
|
||||
return 0, err
|
||||
}
|
||||
if delta <= 0 || delta > 1000 {
|
||||
return 0, ErrInvalidAskDelta
|
||||
}
|
||||
@@ -270,16 +251,7 @@ func (s *Service) ListAuditLogs(ctx context.Context, limit, offset int) ([]repos
|
||||
}
|
||||
|
||||
func planDays(plan string) (int, error) {
|
||||
switch plan {
|
||||
case "month":
|
||||
return 31, nil
|
||||
case "quarter":
|
||||
return 92, nil
|
||||
case "year":
|
||||
return 366, nil
|
||||
default:
|
||||
return 0, ErrInvalidPlan
|
||||
}
|
||||
return planDaysFallback(plan)
|
||||
}
|
||||
|
||||
func newToken() (string, error) {
|
||||
|
||||
Reference in New Issue
Block a user