2021-09-30 10:32:18 +07:00
|
|
|
package api
|
|
|
|
|
|
|
|
import (
|
2021-12-19 15:30:21 +07:00
|
|
|
"context"
|
2021-09-30 10:32:18 +07:00
|
|
|
"log"
|
|
|
|
|
2021-12-19 15:30:21 +07:00
|
|
|
codequestpb "github.com/hhhapz/codequest/api/v1"
|
|
|
|
"github.com/hhhapz/codequest/models"
|
|
|
|
"google.golang.org/grpc/codes"
|
|
|
|
"google.golang.org/grpc/status"
|
|
|
|
"google.golang.org/protobuf/types/known/timestamppb"
|
2021-09-30 10:32:18 +07:00
|
|
|
)
|
|
|
|
|
|
|
|
type UserService struct {
|
2021-12-19 15:30:21 +07:00
|
|
|
codequestpb.UnimplementedUserServiceServer
|
|
|
|
|
2021-09-30 10:32:18 +07:00
|
|
|
userStore UserStore
|
|
|
|
}
|
|
|
|
|
2021-12-19 15:30:21 +07:00
|
|
|
func (us *UserService) User(ctx context.Context, req *codequestpb.UserRequest) (*codequestpb.User, error) {
|
|
|
|
u := UserCtx(ctx)
|
|
|
|
return convertUser(u), nil
|
2021-09-30 10:32:18 +07:00
|
|
|
}
|
|
|
|
|
2021-12-19 15:30:21 +07:00
|
|
|
func (us *UserService) UserByEmail(ctx context.Context, req *codequestpb.UserByEmailRequest) (*codequestpb.User, error) {
|
|
|
|
u := UserCtx(ctx)
|
|
|
|
if u.Email == req.Email {
|
|
|
|
return convertUser(u), nil
|
2021-09-30 10:32:18 +07:00
|
|
|
}
|
|
|
|
|
2021-12-19 15:30:21 +07:00
|
|
|
var err error
|
|
|
|
if ctx, err = AdminOnly(ctx); err != nil {
|
|
|
|
return nil, err
|
2021-09-30 10:32:18 +07:00
|
|
|
}
|
|
|
|
|
2021-12-19 15:30:21 +07:00
|
|
|
user, err := us.userStore.User(ctx, req.Email)
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("Could not fetch user(%q): %v", req.Email, err)
|
|
|
|
return nil, status.Errorf(codes.NotFound, "email not found: %q", req.Email)
|
2021-09-30 10:32:18 +07:00
|
|
|
}
|
2021-12-19 15:30:21 +07:00
|
|
|
|
|
|
|
return convertUser(user), nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (us *UserService) AllUsers(ctx context.Context, req *codequestpb.AllUsersRequest) (*codequestpb.AllUsersResponse, error) {
|
|
|
|
var err error
|
|
|
|
if ctx, err = AdminOnly(ctx); err != nil {
|
|
|
|
return nil, err
|
2021-09-30 10:32:18 +07:00
|
|
|
}
|
|
|
|
|
2021-12-19 15:30:21 +07:00
|
|
|
users, err := us.userStore.Users(ctx)
|
2021-09-30 10:32:18 +07:00
|
|
|
if err != nil {
|
2021-12-19 15:30:21 +07:00
|
|
|
log.Printf("Could not fetch all users: %v", err)
|
|
|
|
return nil, status.Errorf(codes.Internal, "unable to fetch users")
|
2021-09-30 10:32:18 +07:00
|
|
|
}
|
|
|
|
|
2021-12-19 15:30:21 +07:00
|
|
|
var userList []*codequestpb.User
|
|
|
|
for _, u := range users {
|
|
|
|
userList = append(userList, convertUser(u))
|
|
|
|
}
|
|
|
|
return &codequestpb.AllUsersResponse{Users: userList}, nil
|
2021-09-30 10:32:18 +07:00
|
|
|
}
|
|
|
|
|
2021-12-19 15:30:21 +07:00
|
|
|
func (us *UserService) UpdateUser(ctx context.Context, req *codequestpb.UpdateUserRequest) (*codequestpb.User, error) {
|
|
|
|
u := UserCtx(ctx)
|
2021-09-30 10:32:18 +07:00
|
|
|
|
2021-12-19 15:30:21 +07:00
|
|
|
u.Name = req.Body.Name
|
|
|
|
if len(u.Name) < 3 || len(u.Name) > 20 {
|
|
|
|
return nil, status.Errorf(codes.InvalidArgument, "name must be between 3 and 20 characters")
|
2021-09-30 10:32:18 +07:00
|
|
|
}
|
|
|
|
|
2021-12-22 14:38:22 +07:00
|
|
|
// TODO FIX THIS
|
|
|
|
// gl := req.Body.GradeLevel
|
|
|
|
// u.GradeLevel = sql.NullInt64{Int64: int64(gl), Valid: true}
|
|
|
|
// if gl < 9 || gl > 12 {
|
|
|
|
// return nil, status.Errorf(codes.InvalidArgument, "grade level must be between 9 and 12")
|
|
|
|
// }
|
2021-09-30 10:32:18 +07:00
|
|
|
|
2021-12-19 15:30:21 +07:00
|
|
|
if err := us.userStore.UpdateUser(ctx, u); err != nil {
|
|
|
|
log.Printf("could not update user: %v", err)
|
|
|
|
return nil, status.Errorf(codes.Internal, "unable to update user")
|
2021-09-30 10:32:18 +07:00
|
|
|
}
|
|
|
|
|
2021-12-19 15:30:21 +07:00
|
|
|
return convertUser(u), nil
|
2021-09-30 10:32:18 +07:00
|
|
|
}
|
|
|
|
|
2021-12-19 15:30:21 +07:00
|
|
|
func (us *UserService) AdminUpdateUser(ctx context.Context, req *codequestpb.UpdateUserRequest) (*codequestpb.User, error) {
|
|
|
|
var err error
|
|
|
|
if ctx, err = AdminOnly(ctx); err != nil {
|
|
|
|
return nil, err
|
2021-09-30 10:32:18 +07:00
|
|
|
}
|
|
|
|
|
2021-12-19 15:30:21 +07:00
|
|
|
user, err := us.userStore.User(ctx, req.Email)
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("Could not fetch user(%q): %v", req.Email, err)
|
|
|
|
return nil, status.Errorf(codes.NotFound, "email not found: %q", req.Email)
|
2021-09-30 10:32:18 +07:00
|
|
|
}
|
|
|
|
|
2021-12-19 15:30:21 +07:00
|
|
|
user.Name = req.Body.Name
|
|
|
|
if len(user.Name) < 3 || len(user.Name) > 20 {
|
|
|
|
return nil, status.Errorf(codes.InvalidArgument, "name must be between 3 and 20 characters")
|
2021-09-30 10:32:18 +07:00
|
|
|
}
|
|
|
|
|
2021-12-22 14:38:22 +07:00
|
|
|
// gl := req.Body.GradeLevel
|
|
|
|
// user.GradeLevel = sql.NullInt64{Int64: int64(gl), Valid: true}
|
|
|
|
// if gl < 9 || gl > 12 {
|
|
|
|
// return nil, status.Errorf(codes.InvalidArgument, "grade level must be between 9 and 12")
|
|
|
|
// }
|
2021-09-30 10:32:18 +07:00
|
|
|
|
2021-12-19 15:30:21 +07:00
|
|
|
user.Admin = req.Body.Admin
|
2021-09-30 10:32:18 +07:00
|
|
|
|
2021-12-19 15:30:21 +07:00
|
|
|
if err := us.userStore.UpdateUser(ctx, user); err != nil {
|
|
|
|
log.Printf("could not update user: %v", err)
|
|
|
|
return nil, status.Errorf(codes.Internal, "unable to update user")
|
2021-09-30 10:32:18 +07:00
|
|
|
}
|
|
|
|
|
2021-12-19 15:30:21 +07:00
|
|
|
return convertUser(user), nil
|
2021-09-30 10:32:18 +07:00
|
|
|
}
|
|
|
|
|
2021-12-19 15:30:21 +07:00
|
|
|
func (us *UserService) DeleteUser(ctx context.Context, req *codequestpb.DeleteUserRequest) (*codequestpb.User, error) {
|
|
|
|
var err error
|
|
|
|
if ctx, err = AdminOnly(ctx); err != nil {
|
|
|
|
return nil, err
|
2021-09-30 10:32:18 +07:00
|
|
|
}
|
|
|
|
|
2021-12-19 15:30:21 +07:00
|
|
|
user, err := us.userStore.User(ctx, req.Email)
|
|
|
|
if err != nil {
|
|
|
|
log.Printf("Could not fetch user(%q): %v", req.Email, err)
|
|
|
|
return nil, status.Errorf(codes.NotFound, "email not found: %q", req.Email)
|
2021-09-30 10:32:18 +07:00
|
|
|
}
|
|
|
|
|
2021-12-19 15:30:21 +07:00
|
|
|
if err := us.userStore.DeleteUser(ctx, user); err != nil {
|
|
|
|
log.Printf("could not delete user: %v", err)
|
|
|
|
return nil, status.Errorf(codes.Internal, "unable to delete user")
|
2021-09-30 10:32:18 +07:00
|
|
|
}
|
|
|
|
|
2021-12-19 15:30:21 +07:00
|
|
|
return convertUser(user), nil
|
2021-09-30 10:32:18 +07:00
|
|
|
}
|
|
|
|
|
2021-12-19 15:30:21 +07:00
|
|
|
func convertUser(u *models.User) *codequestpb.User {
|
|
|
|
return &codequestpb.User{
|
2021-12-22 14:38:22 +07:00
|
|
|
ID: u.ID,
|
|
|
|
Name: u.Name,
|
|
|
|
Email: u.Email,
|
|
|
|
Picture: u.Picture,
|
|
|
|
Admin: u.Admin,
|
|
|
|
CreatedAt: timestamppb.New(u.CreatedAt.Time()),
|
2021-12-19 15:30:21 +07:00
|
|
|
}
|
2021-09-30 10:32:18 +07:00
|
|
|
}
|