任务三
This commit is contained in:
parent
cd473c0e17
commit
b63a296144
|
|
@ -1,243 +0,0 @@
|
||||||
package service
|
|
||||||
|
|
||||||
import (
|
|
||||||
"context"
|
|
||||||
"crypto/md5"
|
|
||||||
"encoding/hex"
|
|
||||||
"time"
|
|
||||||
|
|
||||||
v1 "kra/api/kratos/admin/v1"
|
|
||||||
"kra/internal/biz"
|
|
||||||
"kra/pkg/auth"
|
|
||||||
"github.com/go-kratos/kratos/v2/errors"
|
|
||||||
|
|
||||||
"go.einride.tech/aip/fieldmask"
|
|
||||||
"go.einride.tech/aip/filtering"
|
|
||||||
"go.einride.tech/aip/ordering"
|
|
||||||
"go.einride.tech/aip/pagination"
|
|
||||||
"google.golang.org/protobuf/types/known/emptypb"
|
|
||||||
"google.golang.org/protobuf/types/known/timestamppb"
|
|
||||||
)
|
|
||||||
|
|
||||||
func encodePassword(password string) string {
|
|
||||||
sum := md5.Sum([]byte(password))
|
|
||||||
return hex.EncodeToString(sum[:])
|
|
||||||
}
|
|
||||||
|
|
||||||
func convertAdmin(m *biz.Admin) *v1.Admin {
|
|
||||||
return &v1.Admin{
|
|
||||||
Id: m.ID,
|
|
||||||
Name: m.Name,
|
|
||||||
Email: m.Email,
|
|
||||||
Avatar: m.Avatar,
|
|
||||||
Access: m.Access,
|
|
||||||
CreateTime: timestamppb.New(m.CreateTime),
|
|
||||||
UpdateTime: timestamppb.New(m.UpdateTime),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// AdminService is a greeter service.
|
|
||||||
type AdminService struct {
|
|
||||||
v1.UnimplementedAdminServiceServer
|
|
||||||
|
|
||||||
uc *biz.AdminUsecase
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewAdminService new a greeter service.
|
|
||||||
func NewAdminService(uc *biz.AdminUsecase) *AdminService {
|
|
||||||
return &AdminService{uc: uc}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Current implements auth current admin retrieval.
|
|
||||||
func (s *AdminService) Current(ctx context.Context, req *emptypb.Empty) (*v1.Admin, error) {
|
|
||||||
a, ok := auth.FromContext(ctx)
|
|
||||||
if !ok {
|
|
||||||
return nil, auth.ErrUnauthorized
|
|
||||||
}
|
|
||||||
admin, err := s.uc.GetAdmin(ctx, a.UserID)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return convertAdmin(admin), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Login implements auth login.
|
|
||||||
func (s *AdminService) Login(ctx context.Context, req *v1.LoginRequest) (*v1.Admin, error) {
|
|
||||||
var (
|
|
||||||
err error
|
|
||||||
admin *biz.Admin
|
|
||||||
)
|
|
||||||
switch v := req.Identity.(type) {
|
|
||||||
case *v1.LoginRequest_Username:
|
|
||||||
admin, err = s.uc.LoginByUsername(ctx, v.Username, encodePassword(req.Password))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
case *v1.LoginRequest_Email:
|
|
||||||
admin, err = s.uc.LoginByEmail(ctx, v.Email, encodePassword(req.Password))
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return nil, errors.BadRequest("AUTH", "unsupported identity type")
|
|
||||||
}
|
|
||||||
if err := auth.SetCookie(ctx, admin.ID, admin.Access, time.Now().Add(7*24*time.Hour)); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return convertAdmin(admin), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// Logout implements auth logout.
|
|
||||||
func (s *AdminService) Logout(ctx context.Context, req *emptypb.Empty) (*emptypb.Empty, error) {
|
|
||||||
a, ok := auth.FromContext(ctx)
|
|
||||||
if !ok {
|
|
||||||
return nil, auth.ErrUnauthorized
|
|
||||||
}
|
|
||||||
if err := s.uc.Logout(ctx, a.UserID); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if err := auth.DeleteCookie(ctx); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &emptypb.Empty{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// CreateAdmin implements admin creation.
|
|
||||||
func (s *AdminService) CreateAdmin(ctx context.Context, req *v1.CreateAdminRequest) (*v1.Admin, error) {
|
|
||||||
a, ok := auth.FromContext(ctx)
|
|
||||||
if !ok {
|
|
||||||
return nil, auth.ErrUnauthorized
|
|
||||||
}
|
|
||||||
if !a.HasAdminAccess() {
|
|
||||||
return nil, auth.ErrForbidden
|
|
||||||
}
|
|
||||||
admin, err := s.uc.CreateAdmin(ctx, &biz.Admin{
|
|
||||||
Name: req.Admin.Name,
|
|
||||||
Email: req.Admin.Email,
|
|
||||||
Password: req.Admin.Password,
|
|
||||||
Avatar: req.Admin.Avatar,
|
|
||||||
Access: req.Admin.Access,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return convertAdmin(admin), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// UpdateAdmin implements admin update.
|
|
||||||
func (s *AdminService) UpdateAdmin(ctx context.Context, req *v1.UpdateAdminRequest) (*v1.Admin, error) {
|
|
||||||
a, ok := auth.FromContext(ctx)
|
|
||||||
if !ok {
|
|
||||||
return nil, auth.ErrUnauthorized
|
|
||||||
}
|
|
||||||
if !a.HasAdminAccess() {
|
|
||||||
return nil, auth.ErrForbidden
|
|
||||||
}
|
|
||||||
// Encode password if it's not empty
|
|
||||||
if req.Admin.Password != "" {
|
|
||||||
req.Admin.Password = encodePassword(req.Admin.Password)
|
|
||||||
}
|
|
||||||
admin, err := s.GetAdmin(ctx, &v1.GetAdminRequest{Id: req.Admin.Id})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
fieldmask.Update(req.UpdateMask, admin, req.Admin)
|
|
||||||
updated, err := s.uc.UpdateAdmin(ctx, &biz.Admin{
|
|
||||||
ID: admin.Id,
|
|
||||||
Name: admin.Name,
|
|
||||||
Email: admin.Email,
|
|
||||||
Password: admin.Password,
|
|
||||||
Avatar: admin.Avatar,
|
|
||||||
Access: admin.Access,
|
|
||||||
})
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return convertAdmin(updated), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// DeleteAdmin implements admin deletion.
|
|
||||||
func (s *AdminService) DeleteAdmin(ctx context.Context, req *v1.DeleteAdminRequest) (*emptypb.Empty, error) {
|
|
||||||
a, ok := auth.FromContext(ctx)
|
|
||||||
if !ok {
|
|
||||||
return nil, auth.ErrUnauthorized
|
|
||||||
}
|
|
||||||
if !a.HasAdminAccess() {
|
|
||||||
return nil, auth.ErrForbidden
|
|
||||||
}
|
|
||||||
if err := s.uc.DeleteAdmin(ctx, req.Id); err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return &emptypb.Empty{}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetAdmin implements admin retrieval.
|
|
||||||
func (s *AdminService) GetAdmin(ctx context.Context, req *v1.GetAdminRequest) (*v1.Admin, error) {
|
|
||||||
a, ok := auth.FromContext(ctx)
|
|
||||||
if !ok {
|
|
||||||
return nil, auth.ErrUnauthorized
|
|
||||||
}
|
|
||||||
if !a.HasAdminAccess() {
|
|
||||||
return nil, auth.ErrForbidden
|
|
||||||
}
|
|
||||||
admin, err := s.uc.GetAdmin(ctx, req.Id)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
return convertAdmin(admin), nil
|
|
||||||
}
|
|
||||||
|
|
||||||
// ListAdmins implements admin listing with filtering, ordering, and pagination.
|
|
||||||
func (s *AdminService) ListAdmins(ctx context.Context, req *v1.ListAdminsRequest) (*v1.AdminSet, error) {
|
|
||||||
a, ok := auth.FromContext(ctx)
|
|
||||||
if !ok {
|
|
||||||
return nil, auth.ErrUnauthorized
|
|
||||||
}
|
|
||||||
if !a.HasAdminAccess() {
|
|
||||||
return nil, auth.ErrForbidden
|
|
||||||
}
|
|
||||||
declarations, err := filtering.NewDeclarations(
|
|
||||||
filtering.DeclareStandardFunctions(),
|
|
||||||
filtering.DeclareIdent("name", filtering.TypeString),
|
|
||||||
filtering.DeclareIdent("email", filtering.TypeString),
|
|
||||||
filtering.DeclareIdent("phone", filtering.TypeString),
|
|
||||||
filtering.DeclareIdent("create_time", filtering.TypeTimestamp),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
filter, err := filtering.ParseFilter(req, declarations)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
pageToken, err := pagination.ParsePageToken(req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
orderBy, err := ordering.ParseOrderBy(req)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
if req.PageSize <= 0 {
|
|
||||||
req.PageSize = 20
|
|
||||||
}
|
|
||||||
admins, err := s.uc.ListAdmins(ctx,
|
|
||||||
biz.ListFilter(filter),
|
|
||||||
biz.ListOrderBy(orderBy),
|
|
||||||
biz.ListLimit(int(req.PageSize)),
|
|
||||||
biz.ListOffset(int(pageToken.Offset)),
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
adminSet := &v1.AdminSet{
|
|
||||||
Admins: make([]*v1.Admin, 0, len(admins)),
|
|
||||||
}
|
|
||||||
if len(admins) >= int(req.PageSize) {
|
|
||||||
adminSet.NextPageToken = pageToken.Next(req).String()
|
|
||||||
}
|
|
||||||
for _, admin := range admins {
|
|
||||||
adminSet.Admins = append(adminSet.Admins, convertAdmin(admin))
|
|
||||||
}
|
|
||||||
return adminSet, nil
|
|
||||||
}
|
|
||||||
Loading…
Reference in New Issue