hackathon/api/user.go

157 lines
4.4 KiB
Go

package api
import (
"context"
"log"
"time"
codequestpb "github.com/hhhapz/codequest/api/v1"
"github.com/hhhapz/codequest/models"
"google.golang.org/grpc/codes"
"google.golang.org/grpc/status"
)
type UserService struct {
codequestpb.UnsafeUserServiceServer
userStore UserStore
}
func (us *UserService) Info(ctx context.Context, req *codequestpb.InfoRequest) (*codequestpb.Info, error) {
u := User(ctx)
points, err := us.userStore.UserPoints(ctx, u)
if err != nil {
log.Printf("Could not retrieve user points(%q): %v", u.ID, err)
// no return
}
return &codequestpb.Info{
CurrentUser: convertUser(u),
Active: active(),
Points: int32(points),
StartTime: Start.UTC().Format(time.RFC3339),
EndTime: End.UTC().Format(time.RFC3339),
}, nil
}
func (us *UserService) UserByEmail(ctx context.Context, req *codequestpb.UserByEmailRequest) (*codequestpb.User, error) {
var err error
if ctx, err = AdminOnly(ctx); err != nil {
return nil, err
}
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)
}
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
}
users, err := us.userStore.Users(ctx)
if err != nil {
log.Printf("Could not fetch all users: %v", err)
return nil, status.Errorf(codes.Internal, "unable to fetch users")
}
var userList []*codequestpb.User
for _, u := range users {
userList = append(userList, convertUser(u))
}
return &codequestpb.AllUsersResponse{Users: userList}, nil
}
func (us *UserService) UpdateUser(ctx context.Context, req *codequestpb.UpdateUserRequest) (*codequestpb.User, error) {
u := User(ctx)
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")
}
// 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")
// }
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")
}
return convertUser(u), nil
}
func (us *UserService) AdminUpdateUser(ctx context.Context, req *codequestpb.AdminUpdateUserRequest) (*codequestpb.User, error) {
var err error
if ctx, err = AdminOnly(ctx); err != nil {
return nil, err
}
user, err := us.userStore.User(ctx, req.Body.Email)
if err != nil {
log.Printf("Could not fetch user(%q): %v", req.Body.Email, err)
return nil, status.Errorf(codes.NotFound, "email not found: %q", req.Body.Email)
}
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")
}
// 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")
// }
user.Admin = req.Body.Admin
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")
}
return convertUser(user), nil
}
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
}
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)
}
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")
}
return convertUser(user), nil
}
func convertUser(u *models.User) *codequestpb.User {
return &codequestpb.User{
ID: u.ID,
Name: u.Name,
Email: u.Email,
Picture: u.Picture,
Admin: u.Admin,
CreatedAt: u.CreatedAt.Time().UTC().Format(time.RFC3339),
}
}