package account import ( "net/http" "nos-comptes/handler" "nos-comptes/internal/storage/dao/postgresql" "nos-comptes/internal/storage/model" "nos-comptes/internal/storage/validators" "nos-comptes/internal/user" "nos-comptes/internal/utils" utils2 "nos-comptes/internal/utils" "github.com/gin-gonic/gin" ) type Context struct { service *Service db *Database userService *user.Service *handler.Context } func (c *Context) GetAllAccountOfUser(gc *gin.Context) { userId := gc.Param("userId") err := c.Validator.VarCtx(gc, userId, "uuid4") if err != nil { utils2.JSONError(gc.Writer, validators.NewDataValidationAPIError(err)) return } _, err = c.userService.GetUserById(userId) if e, ok := err.(*model.APIError); ok { utils.GetLoggerFromCtx(gc).WithError(err).WithField("type", e.Type).Error("error GetUser: get user error") utils.JSONErrorWithMessage(gc.Writer, *e, e.Description) } else if err != nil { utils.GetLoggerFromCtx(gc).WithError(err).Error("error while get user") utils.JSONError(gc.Writer, model.ErrInternalServer) return } accounts, err := c.service.GetAllAccountOfUser(userId) if e, ok := err.(*model.APIError); ok { utils.GetLoggerFromCtx(gc).WithError(err).WithField("type", e.Type).Error("error GetAllAccounts: get accounts") utils.JSONErrorWithMessage(gc.Writer, *e, e.Description) } else if err != nil { utils.GetLoggerFromCtx(gc).WithError(err).Error("error while get accounts") utils.JSONError(gc.Writer, model.ErrInternalServer) return } if len(accounts) == 0 { utils.JSON(gc.Writer, http.StatusNoContent, nil) } else { utils.JSON(gc.Writer, http.StatusOK, accounts) } } func (c *Context) CreateAccountOfUser(gc *gin.Context) { userId := gc.Param("userId") err := c.Validator.VarCtx(gc, userId, "uuid4") if err != nil { utils2.JSONError(gc.Writer, validators.NewDataValidationAPIError(err)) return } _, err = c.userService.GetUserById(userId) if e, ok := err.(*model.APIError); ok { utils.GetLogger().Info(err) utils.GetLoggerFromCtx(gc).WithError(err).WithField("type", e.Type).Error("error GetUser: get user error") utils.JSONErrorWithMessage(gc.Writer, *e, e.Description) return } else if err != nil { utils.GetLoggerFromCtx(gc).WithError(err).Error("error while get user") utils.JSONError(gc.Writer, model.ErrInternalServer) return } var account Account var accountEditable AccountEditable if err := gc.BindJSON(&accountEditable); err != nil { utils2.JSONError(gc.Writer, validators.NewDataValidationAPIError(err)) return } account = Account{AccountEditable: accountEditable, UserId: userId} accountFound, err := c.service.GetAccountWithNameForUser(account.Name, userId) if e, ok := err.(*model.APIError); ok { if e.Type != model.ErrNotFound.Type { utils.GetLoggerFromCtx(gc).WithError(err).WithField("type", e.Type).Error("error GetAccount: get account error") utils.JSONErrorWithMessage(gc.Writer, *e, e.Description) return } } else if err != nil { utils.GetLoggerFromCtx(gc).WithError(err).Error("error while get account") utils.JSONError(gc.Writer, model.ErrInternalServer) return } if accountFound != nil { utils.GetLoggerFromCtx(gc).WithError(&model.ErrAlreadyExists).WithField("type", model.ErrAlreadyExists.Type).Error("error CreateAccount: account already exists") utils.JSONErrorWithMessage(gc.Writer, model.ErrAlreadyExists, "account already exists with the same Name") return } account.UserId = userId accountSaved, err := c.service.CreateAccount(account) if err != nil { utils.GetLogger().Info(err) utils.JSONErrorWithMessage(gc.Writer, model.ErrInternalServer, err.Error()) return } utils.JSON(gc.Writer, http.StatusCreated, accountSaved) return } func (c *Context) DeleteAccountOfUser(gc *gin.Context) { userId := gc.Param("userId") err := c.Validator.VarCtx(gc, userId, "uuid4") if err != nil { utils2.JSONError(gc.Writer, validators.NewDataValidationAPIError(err)) return } accountId := gc.Param("accountId") err = c.Validator.VarCtx(gc, userId, "uuid4") if err != nil { utils2.JSONError(gc.Writer, validators.NewDataValidationAPIError(err)) return } usrParam, err := c.userService.GetUserById(userId) if e, ok := err.(*model.APIError); ok { utils.GetLogger().Info(err) utils.GetLoggerFromCtx(gc).WithError(err).WithField("type", e.Type).Error("error GetUser: get user error") utils.JSONErrorWithMessage(gc.Writer, *e, e.Description) return } else if err != nil { utils.GetLoggerFromCtx(gc).WithError(err).Error("error while get user") utils.JSONError(gc.Writer, model.ErrInternalServer) return } googleUserId, exists := gc.Get("googleUserId") if exists == false { utils.GetLoggerFromCtx(gc).Error("error while getting google user id") utils.JSONError(gc.Writer, model.ErrInternalServer) return } usr, err := c.userService.GetUserFromGoogleID(googleUserId.(string)) if e, ok := err.(*model.APIError); ok { utils.GetLogger().Info(err) utils.GetLoggerFromCtx(gc).WithError(err).WithField("type", e.Type).Error("error GetUserFromGoogleID: get user from google user id") utils.JSONErrorWithMessage(gc.Writer, *e, e.Description) return } else if err != nil { utils.GetLoggerFromCtx(gc).WithError(err).Error("error while get user from google user id") utils.JSONError(gc.Writer, model.ErrInternalServer) return } if usr == nil || usr.ID != usrParam.ID { utils.GetLoggerFromCtx(gc).WithError(err).Error("User in path doesn't match authenticated user") utils.JSONError(gc.Writer, model.ErrBadRequestFormat) return } c.service.DeleteAccountOfUser(userId, accountId) } func (c *Context) GetSpecificAccountOfUser(gc *gin.Context) { userId := gc.Param("userId") err := c.Validator.VarCtx(gc, userId, "uuid4") if err != nil { utils2.JSONError(gc.Writer, validators.NewDataValidationAPIError(err)) return } accountId := gc.Param("accountId") err = c.Validator.VarCtx(gc, userId, "uuid4") if err != nil { utils2.JSONError(gc.Writer, validators.NewDataValidationAPIError(err)) return } usrParam, err := c.userService.GetUserById(userId) if e, ok := err.(*model.APIError); ok { utils.GetLogger().Info(err) utils.GetLoggerFromCtx(gc).WithError(err).WithField("type", e.Type).Error("error GetUser: get user error") utils.JSONErrorWithMessage(gc.Writer, *e, e.Description) return } else if err != nil { utils.GetLoggerFromCtx(gc).WithError(err).Error("error while get user") utils.JSONError(gc.Writer, model.ErrInternalServer) return } googleUserId, exists := gc.Get("googleUserId") if exists == false { utils.GetLoggerFromCtx(gc).Error("error while getting google user id") utils.JSONError(gc.Writer, model.ErrInternalServer) return } usr, err := c.userService.GetUserFromGoogleID(googleUserId.(string)) if e, ok := err.(*model.APIError); ok { utils.GetLogger().Info(err) utils.GetLoggerFromCtx(gc).WithError(err).WithField("type", e.Type).Error("error GetUserFromGoogleID: get user from google user id") utils.JSONErrorWithMessage(gc.Writer, *e, e.Description) return } else if err != nil { utils.GetLoggerFromCtx(gc).WithError(err).Error("error while get user from google user id") utils.JSONError(gc.Writer, model.ErrInternalServer) return } if usr == nil || usr.ID != usrParam.ID { utils.GetLoggerFromCtx(gc).WithError(err).Error("User in path doesn't match authenticated user") utils.JSONError(gc.Writer, model.ErrBadRequestFormat) return } account, err := c.service.GetASpecificAccountForUser(usr.ID, accountId) if e, ok := err.(*model.APIError); ok { utils.GetLogger().Info(err) utils.GetLoggerFromCtx(gc).WithError(err).WithField("type", e.Type).Error("error GetUserFromGoogleID: get user from google user id") utils.JSONErrorWithMessage(gc.Writer, *e, e.Description) return } else if err != nil { utils.GetLoggerFromCtx(gc).WithError(err).Error("error while get user from google user id") utils.JSONError(gc.Writer, model.ErrInternalServer) return } utils.JSON(gc.Writer, http.StatusCreated, account) } func NewHandler(ctx *handler.Context, db *postgresql.DatabasePostgreSQL) *Context { database := NewDatabase(db) service := NewService(database) userService := user.NewService(user.NewDatabase(db)) return &Context{service: service, db: database, userService: userService, Context: ctx} }