Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix error handling in frontend and backend #265

Merged
merged 16 commits into from
Mar 17, 2024
Merged
Show file tree
Hide file tree
Changes from 5 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 38 additions & 27 deletions backend/pkg/helper/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,111 +26,122 @@ var (
)

func NewMicroNotAuthorizedErr(id ClientID) error {
return microErrors.Unauthorized(string(id), "user not authorized")
return microErrors.Unauthorized(string(id), "User not authorized")
}

func NewMicroNoEntryWithIDErr(id ClientID) error {
return microErrors.BadRequest(string(id), "no entry with id")
return microErrors.BadRequest(string(id), "No entry with id")
}

func NewMicroNoExistingUserWithEmailErr(id ClientID) error {
return microErrors.BadRequest(string(id), "no existing user with email")
return microErrors.BadRequest(string(id), "User does not exist")
}

func NewMicroUserAlreadyExistsErr(id ClientID) error {
return microErrors.BadRequest(string(id), "this user already exists")
return microErrors.BadRequest(string(id), "This user already exists")
}

func NewMicroInvalidUserNameFormatErr(id ClientID) error {
return microErrors.BadRequest(string(id), "invalid user name format")
func NewMicroInvalidNameFormatErr(id ClientID) error {
return microErrors.BadRequest(string(id), "Invalid name format")
}

func NewMicroInvalidParameterDataErr(id ClientID) error {
return microErrors.BadRequest(string(id), "invalid parameter data")
return microErrors.BadRequest(string(id), "Invalid parameter data")
}

func NewMicroMissingParameterDataErr(id ClientID) error {
return microErrors.BadRequest(string(id), "Missing request parameters")
}

func NewMicroUserAlreadyInGroupErr(id ClientID) error {
return microErrors.BadRequest(string(id), "user already in group")
return microErrors.BadRequest(string(id), "User already in group")
}

func NewMicroCantLeaveDefaultGroupErr(id ClientID) error {
return microErrors.BadRequest(string(id), "You can't leave your default group")
}

func NewMicroCantLeaveAsLastAdminErr(id ClientID) error {
return microErrors.BadRequest(string(id), "You can't leave when you are the last admin")
return microErrors.BadRequest(string(id), "You can't leave as last admin")
}

func NewMicroCantInviteToHomegroupErr(id ClientID) error {
return microErrors.BadRequest(string(id), "You can't invite users to your homegroup")
}

func NewMicroUserAdmissionInProgressErr(id ClientID) error {
return microErrors.BadRequest(string(id), "user already invited")
return microErrors.BadRequest(string(id), "User already invited")
}

func NewMicroCardSideNotInGivenCardErr(id ClientID) error {
return microErrors.BadRequest(string(id), "card side not in given card")
return microErrors.BadRequest(string(id), "Card side not in given card")
}

func NewMicroDeckTypeNotValidErr(id ClientID) error {
return microErrors.BadRequest(string(id), "invalid deck type")
return microErrors.BadRequest(string(id), "Invalid deck type")
}

func NewMicroAlreadyRequestedErr(id ClientID) error {
return microErrors.BadRequest(string(id), "user access already requested")
return microErrors.BadRequest(string(id), "User access already requested")
}

func NewMicroAlreadyInvitedErr(id ClientID) error {
return microErrors.BadRequest(string(id), "user already invited")
return microErrors.BadRequest(string(id), "User already invited")
}

func NewMicroHashingFailedErr(id ClientID) error {
return microErrors.InternalServerError(string(id), "error while hashing password")
func NewMicroCantModifyGroupAdminErr(id ClientID) error {
return microErrors.Unauthorized(string(id), "You can not modify group admins")
4KevR marked this conversation as resolved.
Show resolved Hide resolved
}

func NewMicroInvalidEmailOrPasswordErr(id ClientID) error {
return microErrors.BadRequest(string(id), "invalid email or password")
func NewMicroCantKickGroupAdminErr(id ClientID) error {
return microErrors.Unauthorized(string(id), "You can not kick group admins")
4KevR marked this conversation as resolved.
Show resolved Hide resolved
}

func NewMicroInvalidPasswordErr(id ClientID) error {
return microErrors.BadRequest(string(id), "invalid password")
func NewMicroHashingFailedErr(id ClientID) error {
return microErrors.InternalServerError(string(id), "Error while hashing password")
}

func NewMicroInvalidEmailOrPasswordErr(id ClientID) error {
return microErrors.BadRequest(string(id), "Invalid email or password")
}

func NewMicroNotSuccessfulResponseErr(id ClientID) error {
return microErrors.BadRequest(string(id), "operation not successful")
return microErrors.BadRequest(string(id), "Operation not successful")
}

func NewMicroWrongRatingErr(id ClientID) error {
return microErrors.BadRequest(string(id), "invalid rating")
return microErrors.BadRequest(string(id), "Invalid rating")
}

func NewMicroWrongDeckIDErr(id ClientID) error {
return microErrors.BadRequest(string(id), "wrong deck id")
return microErrors.BadRequest(string(id), "Wrong deck id")
}

func NewMicroDeckAlreadyFavoriteErr(id ClientID) error {
return microErrors.BadRequest(string(id), "This Deck is already your favorite")
}

func NewFiberReauthenticateError() error {
return fiber.NewError(fiber.StatusUnauthorized, "Please re-authenticate")
}
func NewFiberBadRequestErr(detail string) error {
4KevR marked this conversation as resolved.
Show resolved Hide resolved
return fiber.NewError(fiber.StatusBadRequest, detail)
}

func NewFiberMissingEmailErr() error {
return fiber.NewError(fiber.StatusBadRequest, "no Email provided")
return fiber.NewError(fiber.StatusBadRequest, "No Email provided")
Julian702 marked this conversation as resolved.
Show resolved Hide resolved
}

func NewFiberMissingNameErr() error {
return fiber.NewError(fiber.StatusBadRequest, "no Name provided")
return fiber.NewError(fiber.StatusBadRequest, "No Name provided")
Julian702 marked this conversation as resolved.
Show resolved Hide resolved
}

func NewFiberMissingPasswordErr() error {
return fiber.NewError(fiber.StatusBadRequest, "no Password provided")
return fiber.NewError(fiber.StatusBadRequest, "No Password provided")
Julian702 marked this conversation as resolved.
Show resolved Hide resolved
}

func NewFiberMissingDeckIDErr() error {
return fiber.NewError(fiber.StatusBadRequest, "no deckID provided")
return fiber.NewError(fiber.StatusBadRequest, "No deckID provided")
}

func NewFiberUnauthorizedErr(detail string) error {
Expand Down
6 changes: 3 additions & 3 deletions backend/pkg/helper/errors_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ func TestErrors(t *testing.T) {
microNoEntryWithIDErr := helper.NewMicroNoEntryWithIDErr(id)
microNoExistingUserWithEmailErr := helper.NewMicroNoExistingUserWithEmailErr(id)
microUserAlreadyExistsErr := helper.NewMicroUserAlreadyExistsErr(id)
microInvalidUserNameFormatErr := helper.NewMicroInvalidUserNameFormatErr(id)
microInvalidUserNameFormatErr := helper.NewMicroInvalidNameFormatErr(id)
microInvalidParameterDataErr := helper.NewMicroInvalidParameterDataErr(id)
microUserAlreadyInGroupErr := helper.NewMicroUserAlreadyInGroupErr(id)
microUserAdmissionInProgressErr := helper.NewMicroUserAdmissionInProgressErr(id)
Expand All @@ -28,7 +28,7 @@ func TestErrors(t *testing.T) {
microNotSuccessfulResponseErr := helper.NewMicroNotSuccessfulResponseErr(id)
fiberBadRequestErr := helper.NewFiberBadRequestErr(id)
fiberUnauthorizedErr := helper.NewFiberUnauthorizedErr(id)

assert.IsType(t, microErrors.Unauthorized(string(id), "user not authorized"), microNotAuthorizedErr)
assert.IsType(t, microErrors.BadRequest(string(id), "no entry with id"), microNoEntryWithIDErr)
assert.IsType(t, microErrors.BadRequest(string(id), "no existing user with email"), microNoExistingUserWithEmailErr)
Expand All @@ -43,4 +43,4 @@ func TestErrors(t *testing.T) {
assert.IsType(t, microErrors.BadRequest(string(id), "operation not successful"), microNotSuccessfulResponseErr)
assert.IsType(t, fiber.NewError(fiber.StatusBadRequest, id), fiberBadRequestErr)
assert.IsType(t, fiber.NewError(fiber.StatusUnauthorized, id), fiberUnauthorizedErr)
}
}
2 changes: 1 addition & 1 deletion backend/pkg/helper/jwtHelper.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ func GetJWTPublicKey() (crypto.PublicKey, error) {

func ParseJWTToken(tokenString string) (*jwt.Token, error) {
if tokenString == "" {
return nil, errors.New("please re-authenticate")
return nil, NewFiberReauthenticateError()
}
token, err := jwt.Parse(tokenString, func(token *jwt.Token) (interface{}, error) {
// Validate the alg is what you expect:
Expand Down
11 changes: 10 additions & 1 deletion backend/pkg/helper/security.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,17 @@ func IsAuthorized(groupRole pbCommon.GroupRole, requiredRole pbCommon.GroupRole)
func CheckForValidName(name string, pattern *regexp.Regexp, clientID ClientID) error {
logger.Infof("Check name %s for valid format", name)
if !pattern.MatchString(name) {
return NewMicroInvalidUserNameFormatErr(clientID)
return NewMicroInvalidNameFormatErr(clientID)
}
logger.Infof("Name %s is valid", name)
return nil
}

func CheckForValidPassword(password string, clientID ClientID) error {
logger.Infof("Check password for valid format")
TomRomeo marked this conversation as resolved.
Show resolved Hide resolved
if len(password) < 3 {
return NewMicroInvalidParameterDataErr(clientID)
}
logger.Infof("Password is valid")
return nil
}
7 changes: 2 additions & 5 deletions backend/services/collaboration/handler/collaboration.go
Original file line number Diff line number Diff line change
Expand Up @@ -415,7 +415,7 @@ func (e *Collaboration) ModifyGroupUserRequest(
return helper.NewMicroUserAdmissionInProgressErr(helper.CollaborationServiceID)
}
if modUserCurrRole == model.RoleAdmin {
return helper.NewMicroNotAuthorizedErr(helper.CollaborationServiceID)
return helper.NewMicroCantModifyGroupAdminErr(helper.CollaborationServiceID)
}
newModelRole := converter.MigrateProtoRoleToModelRole(req.Group.Role)
switch newModelRole {
Expand All @@ -433,9 +433,6 @@ func (e *Collaboration) ModifyGroupUserRequest(
func (e *Collaboration) KickGroupUser(ctx context.Context, req *pbCommon.GroupModUserRequest, rsp *pbCommon.Success) error {
logger.Infof("Received Collaboration.KickGroupUserRequest request: %v", req)

if req.UserID == req.ModUserID {
return helper.NewMicroNotAuthorizedErr(helper.CollaborationServiceID)
}
Julian702 marked this conversation as resolved.
Show resolved Hide resolved
role, err := e.store.FindGroupUserRole(ctx, req.UserID, req.Group.GroupID)
if err != nil {
return err
Expand All @@ -451,7 +448,7 @@ func (e *Collaboration) KickGroupUser(ctx context.Context, req *pbCommon.GroupMo
return helper.NewMicroUserAdmissionInProgressErr(helper.CollaborationServiceID)
}
if delUserCurrRole == model.RoleAdmin {
return helper.NewMicroNotAuthorizedErr(helper.CollaborationServiceID)
return helper.NewMicroCantKickGroupAdminErr(helper.CollaborationServiceID)
}
if err := e.store.RemoveUserFromGroup(ctx, req.ModUserID, req.Group.GroupID); err != nil {
return err
Expand Down
19 changes: 2 additions & 17 deletions backend/services/frontend/handler/frontend.go
Original file line number Diff line number Diff line change
Expand Up @@ -48,15 +48,6 @@ func (e *Frontend) RegisterHandler(c *fiber.Ctx) error {
if err := c.BodyParser(&data); err != nil {
return err
}
if data.Email == "" {
return helper.NewFiberMissingEmailErr()
}
if data.Name == "" {
return helper.NewFiberMissingNameErr()
}
if data.Password == "" {
return helper.NewFiberMissingPasswordErr()
}
4KevR marked this conversation as resolved.
Show resolved Hide resolved
_, err := e.userService.Register(c.Context(), &pbCommon.User{
UserEmail: data.Email,
UserName: data.Name,
Expand All @@ -75,12 +66,6 @@ func (e *Frontend) LoginHandler(c *fiber.Ctx) error {
if err := c.BodyParser(&reqUser); err != nil {
return err
}
if reqUser.Email == "" {
return helper.NewFiberMissingEmailErr()
}
if reqUser.Password == "" {
return helper.NewFiberMissingPasswordErr()
}
rspLogin, err := e.userService.Login(c.Context(), &pbCommon.User{
UserEmail: reqUser.Email,
UserPassword: reqUser.Password,
Expand All @@ -104,11 +89,11 @@ func (e *Frontend) ReauthHandler(c *fiber.Ctx) error {
tokenString := c.Cookies("refresh_token")
refreshToken, err := helper.ParseJWTToken(tokenString)
if err != nil {
return helper.NewFiberUnauthorizedErr(err.Error())
return helper.NewFiberReauthenticateError()
4KevR marked this conversation as resolved.
Show resolved Hide resolved
}
claims, ok := refreshToken.Claims.(jwt.MapClaims)
if !ok || !refreshToken.Valid {
return helper.NewFiberUnauthorizedErr("Please re-authenticate")
return helper.NewFiberReauthenticateError()
}

rsp, err := e.userService.VerifyUserExists(c.Context(), &pbCommon.User{
Expand Down
20 changes: 13 additions & 7 deletions backend/services/user/handler/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,10 @@ func New(s store.UserStore, cS pbCollaboration.CollaborationService) *User {
}

func (e *User) Register(ctx context.Context, req *pbCommon.User, rsp *pbCommon.Success) error {
logger.Infof("Received User.Register request: email: %v", req.UserEmail)
logger.Infof("Received User.Register request")
4KevR marked this conversation as resolved.
Show resolved Hide resolved
if helper.SomeEmpty(req.UserEmail, req.UserName, req.UserPassword) {
return helper.NewMicroMissingParameterDataErr(helper.UserServiceID)
}
if _, err := e.store.FindUserByEmail(ctx, req.UserEmail); err == nil {
return helper.NewMicroUserAlreadyExistsErr(helper.UserServiceID)
} else if !errors.Is(err, helper.ErrStoreNoExistingUserWithEmail) {
Expand All @@ -35,17 +38,17 @@ func (e *User) Register(ctx context.Context, req *pbCommon.User, rsp *pbCommon.S
if err := helper.CheckForValidName(req.UserName, helper.UserNameRegex, helper.UserServiceID); err != nil {
return err
}
if err := helper.CheckForValidPassword(req.UserPassword, helper.UserServiceID); err != nil {
return err
}
addr, err := mail.ParseAddress(req.UserEmail)
if err != nil {
return err
return helper.NewMicroInvalidParameterDataErr(helper.UserServiceID)
}
newUser := model.User{
Email: addr.Address,
Name: req.UserName,
}
if req.UserPassword == "" {
return helper.NewMicroInvalidEmailOrPasswordErr(helper.UserServiceID)
}
hash, err := bcrypt.GenerateFromPassword([]byte(req.UserPassword), bcrypt.MinCost)
if err != nil {
return helper.NewMicroHashingFailedErr(helper.UserServiceID)
Expand Down Expand Up @@ -117,11 +120,14 @@ func (e *User) DeleteUser(ctx context.Context, req *pbCommon.User, rsp *pbCommon
}

func (e *User) Login(ctx context.Context, req *pbCommon.User, rsp *pbCommon.User) error {
logger.Infof("Received User.Login request: email: %v", req.UserEmail)
logger.Infof("Received User.Login request")
4KevR marked this conversation as resolved.
Show resolved Hide resolved
if helper.SomeEmpty(req.UserEmail, req.UserPassword) {
return helper.NewMicroMissingParameterDataErr(helper.UserServiceID)
}
user, err := e.store.FindUserByEmail(ctx, req.UserEmail)
if err != nil {
if errors.Is(err, helper.ErrStoreNoExistingUserWithEmail) {
return helper.NewMicroNoExistingUserWithEmailErr(helper.UserServiceID)
return helper.NewMicroInvalidEmailOrPasswordErr(helper.UserServiceID)
}
return err
}
Expand Down
7 changes: 4 additions & 3 deletions backend/store/postgres.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,9 +45,10 @@ func NewPostgresStore(ctx context.Context) (*gorm.DB, error) {
logger := logger.New(
logrus.NewWriter(),
logger.Config{
SlowThreshold: time.Millisecond,
LogLevel: logger.Warn,
Colorful: false,
SlowThreshold: time.Millisecond,
LogLevel: logger.Silent,
IgnoreRecordNotFoundError: true,
Colorful: false,
},
)

Expand Down
8 changes: 8 additions & 0 deletions frontend/components/graphics/LoadingSpinner.stories.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,3 +24,11 @@ export const NoDelay: Story = {
delay: 0,
},
};

export const SimpleTheme: Story = {
args: {
className: "w-16",
Julian702 marked this conversation as resolved.
Show resolved Hide resolved
delay: 0,
theme: "simple",
},
};
Loading
Loading