package grpcserver import ( "context" "encoding/base64" "encoding/json" "strings" "time" grpcproto "git.coopgo.io/coopgo-apps/silvermobi/servers/grpcapi/proto" "github.com/rs/zerolog/log" "google.golang.org/grpc/codes" "google.golang.org/grpc/metadata" "google.golang.org/grpc/status" ) func (s SilvermobiGRPCService) SetPhoneNumber(ctx context.Context, req *grpcproto.SetPhoneNumberRequest) (res *grpcproto.SetPhoneNumberResponse, err error) { var ( md metadata.MD authHeader []string ok bool ) if md, ok = metadata.FromIncomingContext(ctx); !ok { return nil, status.Errorf(codes.Unauthenticated, "Missing metadata") } authHeader, ok = md["authorization"] if !ok || len(authHeader) == 0 { return nil, status.Errorf(codes.Unauthenticated, "Missing authorization header") } tokenString := strings.TrimPrefix(authHeader[0], "Bearer ") id := ExtractIdFromToken(tokenString) log.Info(). Str("User ID", id). Msg("SetPhoneNumber") if err = s.Handler.UpdatePhoneNumber( context.Background(), id, req.PhoneNumber, ); err != nil { return nil, err } return &grpcproto.SetPhoneNumberResponse{Ok: true}, nil } func (s SilvermobiGRPCService) VerifyPhoneNumber(ctx context.Context, req *grpcproto.VerifyPhoneNumberRequest) (res *grpcproto.VerifyPhoneNumberResponse, err error) { var ( md metadata.MD authHeader []string ok bool ) if md, ok = metadata.FromIncomingContext(ctx); !ok { return nil, status.Errorf(codes.Unauthenticated, "Missing metadata") } authHeader, ok = md["authorization"] if !ok || len(authHeader) == 0 { return nil, status.Errorf(codes.Unauthenticated, "Missing authorization header") } tokenString := strings.TrimPrefix(authHeader[0], "Bearer ") id := ExtractIdFromToken(tokenString) log.Info(). Str("User ID", id). Msg("VerifyPhoneNumber") if err = s.Handler.VerifyPhoneNumber( context.Background(), id, req.PhoneNumber, req.VerificationCode, ); err != nil { return nil, err } return &grpcproto.VerifyPhoneNumberResponse{Ok: true}, nil } func (s SilvermobiGRPCService) SetBirthDate(ctx context.Context, req *grpcproto.BirthDateRequest) (res *grpcproto.BirthDateResponse, err error) { var ( md metadata.MD authHeader []string ok bool ) if md, ok = metadata.FromIncomingContext(ctx); !ok { return nil, status.Errorf(codes.Unauthenticated, "Missing metadata") } authHeader, ok = md["authorization"] if !ok || len(authHeader) == 0 { return nil, status.Errorf(codes.Unauthenticated, "Missing authorization header") } tokenString := strings.TrimPrefix(authHeader[0], "Bearer ") id := ExtractIdFromToken(tokenString) log.Info(). Str("User ID", id). Msg("SetBirthDate") birthdate := time.Unix(req.Birthdate.Seconds, int64(req.Birthdate.Nanos)).UTC() birthdateString := birthdate.Format("2006-01-02T15:04:05Z") if err = s.Handler.UpdateBirthDate(ctx, id, birthdateString); err != nil { return nil, err } return &grpcproto.BirthDateResponse{ Ok: true, }, nil } func (s SilvermobiGRPCService) SetAccountType(ctx context.Context, req *grpcproto.AccountTypeRequest) (res *grpcproto.AccountTypeResponse, err error) { var ( md metadata.MD authHeader []string ok bool ) if md, ok = metadata.FromIncomingContext(ctx); !ok { return nil, status.Errorf(codes.Unauthenticated, "Missing metadata") } authHeader, ok = md["authorization"] if !ok || len(authHeader) == 0 { return nil, status.Errorf(codes.Unauthenticated, "Missing authorization header") } tokenString := strings.TrimPrefix(authHeader[0], "Bearer ") id := ExtractIdFromToken(tokenString) log.Info(). Str("User ID", id). Msg("SetAccountType") if req.GetType() != grpcproto.AccountTypeRequest_PASSENGER && req.GetType() != grpcproto.AccountTypeRequest_DRIVER { return nil, status.Errorf(codes.InvalidArgument, "Type should be PASSENGER or DRIVER") } if err = s.Handler.SetAccountType(ctx, id, req.GetType().String()); err != nil { return nil, err } return &grpcproto.AccountTypeResponse{ Ok: true, }, nil } func (s SilvermobiGRPCService) GetAccountType(ctx context.Context, req *grpcproto.AccountTypeRequest) (res *grpcproto.AccountTypeResponse, err error) { var ( md metadata.MD authHeader []string ok bool accountType string responseType grpcproto.AccountTypeResponse_AccountType ) if md, ok = metadata.FromIncomingContext(ctx); !ok { return nil, status.Errorf(codes.Unauthenticated, "Missing metadata") } authHeader, ok = md["authorization"] if !ok || len(authHeader) == 0 { return nil, status.Errorf(codes.Unauthenticated, "Missing authorization header") } tokenString := strings.TrimPrefix(authHeader[0], "Bearer ") id := ExtractIdFromToken(tokenString) log.Info(). Str("User ID", id). Msg("GetAccountType") if req.Request == false || !req.Request { return nil, status.Errorf(codes.InvalidArgument, "request arg should be true") } if accountType, err = s.Handler.GetAccountType(ctx, id); err != nil { return nil, err } switch accountType { case "PASSENGER": responseType = grpcproto.AccountTypeResponse_PASSENGER case "DRIVER": responseType = grpcproto.AccountTypeResponse_DRIVER default: return nil, status.Errorf(codes.InvalidArgument, "Invalid account type") } response := &grpcproto.AccountTypeResponse{ Type: responseType, } return response, nil } func (s SilvermobiGRPCService) GetValidation(ctx context.Context, req *grpcproto.ValidationRequest) (res *grpcproto.ValidationResponse, err error) { var ( md metadata.MD authHeader []string ok, phoneValidation, birthValidation, typeValidation bool ) if md, ok = metadata.FromIncomingContext(ctx); ok { return nil, status.Errorf(codes.Unauthenticated, "Missing metadata") } authHeader, ok = md["authorization"] if !ok || len(authHeader) == 0 { return nil, status.Errorf(codes.Unauthenticated, "Missing authorization header") } tokenString := strings.TrimPrefix(authHeader[0], "Bearer ") id := ExtractIdFromToken(tokenString) if phoneValidation, birthValidation, typeValidation, err = s.Handler.CheckValidation(ctx, id); err != nil { return nil, err } return &grpcproto.ValidationResponse{ Phone: phoneValidation, Birthdate: birthValidation, Type: typeValidation, }, nil } func ExtractIdFromToken(tokenString string) string { var ( err error payloadBytes []byte payloadMap map[string]interface{} id string ok bool ) parts := strings.Split(tokenString, ".") if len(parts) != 3 { return "" } if payloadBytes, err = base64.RawStdEncoding.DecodeString(parts[1]); err != nil { return "" } if err = json.Unmarshal(payloadBytes, &payloadMap); err != nil { return "" } if id, ok = payloadMap["sub"].(string); !ok { return "" } return id }