fix(account): add account creante and fix incorrect field for getting all

This commit is contained in:
2021-11-08 00:26:01 +01:00
parent 3efbec281d
commit 78071a6a91
6 changed files with 160 additions and 11 deletions

View File

@@ -8,6 +8,7 @@ import (
sharedaccount "nos-comptes/internal/shared-account"
"nos-comptes/internal/storage/dao/postgresql"
"nos-comptes/internal/user"
"nos-comptes/middleware"
"time"
"github.com/gin-gonic/gin"
@@ -48,12 +49,13 @@ func NewRouter(config *handler.Config) *gin.Engine {
userRoute.Handle(http.MethodPost, "", uh.CreateUser)
securedUserRoute := userRoute.Group("")
securedUserRoute.Use(middleware.ValidateOAuthToken)
//TODO add secure auth
securedUserRoute.Handle(http.MethodGet, "/:userId", uh.GetUser)
//account route
securedUserRoute.Handle(http.MethodGet, "/:userId/accounts", ah.GetAllAccountOfUser)
securedUserRoute.Handle(http.MethodPost, "/:userId/accounts/:accountId", ah.CreateAccountOfUser)
securedUserRoute.Handle(http.MethodPost, "/:userId/accounts", ah.CreateAccountOfUser)
securedUserRoute.Handle(http.MethodDelete, "/:userId/accounts/:accountId", ah.DeleteAccountOfUser)
securedUserRoute.Handle(http.MethodGet, "/:userId/accounts/:accountId", ah.GetSpecificAccountOfUser)

View File

@@ -2,6 +2,8 @@ package account
import (
"nos-comptes/internal/storage/dao/postgresql"
"github.com/lib/pq"
)
type Database struct {
@@ -12,7 +14,7 @@ func (db *Database) GetAllAccountOfUser(id string) ([]*Account, error) {
q := `
SELECT a.id, a.user_id, a.name, a.provider, a.created_at, a.updated_at
FROM public.account a
WHERE a.id = $1
WHERE a.user_id = $1
`
rows, err := db.Session.Query(q, id)
if err != nil {
@@ -23,7 +25,7 @@ func (db *Database) GetAllAccountOfUser(id string) ([]*Account, error) {
as := make([]*Account, 0)
for rows.Next() {
a := Account{}
err := rows.Scan(&a.ID, &a.userId, &a.name, &a.provider, &a.CreatedAt, &a.UpdatedAt)
err := rows.Scan(&a.ID, &a.UserId, &a.Name, &a.Provider, &a.CreatedAt, &a.UpdatedAt)
if err != nil {
return nil, err
}
@@ -32,6 +34,42 @@ func (db *Database) GetAllAccountOfUser(id string) ([]*Account, error) {
return as, nil
}
func (db *Database) GetAccountWithNameForUser(name string, id string) (*Account, error) {
q := `
SELECT a.id, a.user_id, a.name, a.provider, a.created_at, a.updated_at
FROM public.account a
WHERE a.user_id = $1
AND a.name = $2
`
row := db.Session.QueryRow(q, id, name)
a := Account{}
err := row.Scan(&a.ID, &a.UserId, &a.Name, &a.Provider, &a.CreatedAt, &a.UpdatedAt)
if errPq, ok := err.(*pq.Error); ok {
return nil, postgresql.HandlePgError(errPq)
}
return &a, nil
}
func (db *Database) CreateAccount(account *Account) error {
q := `
INSERT INTO public.account
(Name, Provider, user_id)
VALUES
($1, $2, $3)
RETURNING id, created_at
`
err := db.Session.
QueryRow(q, account.Name, account.Provider, account.UserId).
Scan(&account.ID, &account.CreatedAt)
if errPq, ok := err.(*pq.Error); ok {
return postgresql.HandlePgError(errPq)
}
return err
}
func NewDatabase(db *postgresql.DatabasePostgreSQL) *Database {
return &Database{db}
}

View File

@@ -1,6 +1,7 @@
package account
import (
"fmt"
"net/http"
"nos-comptes/handler"
"nos-comptes/internal/storage/dao/postgresql"
@@ -56,8 +57,60 @@ func (c *Context) GetAllAccountOfUser(gc *gin.Context) {
}
func (c *Context) CreateAccountOfUser(context *gin.Context) {
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.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
}
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}
utils.GetLogger().Warn(account)
utils.GetLogger().Warn(accountEditable.Name)
utils.GetLogger().Warn(accountEditable.Provider)
accountFound, err := c.service.GetAccountWithNameForUser(account.Name, userId)
utils.GetLogger().Warn(err)
utils.GetLogger().Warn(accountFound)
if e, ok := err.(*model.APIError); ok {
if e.Type != model.ErrNotFound.Type {
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
}
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")
}
account.UserId = userId
accountSaved, err := c.service.CreateAccount(account)
if err != nil {
fmt.Println(err)
utils.JSONError(gc.Writer, model.ErrInternalServer)
return
}
utils.JSON(gc.Writer, http.StatusCreated, accountSaved)
return
}
func (c *Context) DeleteAccountOfUser(context *gin.Context) {

View File

@@ -4,13 +4,13 @@ import "time"
type Account struct {
AccountEditable
userId string `json:"userId"`
UserId string `json:"userId,omitempty"`
}
type AccountEditable struct {
ID string `json:"id"`
name string `json:"name"`
provider string `json:"provider"`
CreatedAt time.Time `json:"createdAt"`
UpdatedAt *time.Time `json:"updatedAt"`
ID string `json:"id,omitempty"`
Name string `json:"name"`
Provider string `json:"provider"`
CreatedAt time.Time `json:"createdAt,omitempty"`
UpdatedAt *time.Time `json:"updatedAt,omitempty"`
}

View File

@@ -12,7 +12,6 @@ type Service struct {
func (s *Service) GetAllAccountOfUser(userId string) ([]*Account, error) {
accounts, err := s.db.GetAllAccountOfUser(userId)
utils.GetLogger().Warn(err)
if e, ok := err.(*dao.Error); ok {
switch {
case e.Type == dao.ErrTypeNotFound:
@@ -30,6 +29,27 @@ func (s *Service) GetAllAccountOfUser(userId string) ([]*Account, error) {
return accounts, nil
}
func (s *Service) GetAccountWithNameForUser(name string, id string) (*Account, error) {
account, err := s.db.GetAccountWithNameForUser(name, id)
utils.GetLogger().Warn(err)
if e, ok := err.(*dao.Error); ok {
switch {
case e.Type == dao.ErrTypeNotFound:
return nil, &model.ErrNotFound
default:
return nil, &model.ErrInternalServer
}
} else if err != nil {
return nil, &model.ErrInternalServer
}
return account, nil
}
func (s *Service) CreateAccount(account Account) (*Account, error) {
err := s.db.CreateAccount(&account)
return &account, err
}
func NewService(database *Database) *Service {
return &Service{db: database}
}

36
middleware/oauth_token.go Normal file
View File

@@ -0,0 +1,36 @@
package middleware
import (
"fmt"
"net/http"
"nos-comptes/internal/storage/model"
"nos-comptes/internal/utils"
"strings"
"github.com/gin-gonic/gin"
"google.golang.org/api/oauth2/v1"
)
func ValidateOAuthToken(c *gin.Context) {
authorizationHeader := c.GetHeader("Authorization")
authorizationHeaderSplitted := strings.Split(authorizationHeader, " ")
if len(authorizationHeaderSplitted) != 2 {
utils.JSONError(c.Writer, model.ErrBadRequestFormat)
return
}
oauth2Service, err := oauth2.New(&http.Client{})
if oauth2Service == nil {
fmt.Println(err)
utils.JSONError(c.Writer, model.ErrInternalServer)
return
}
tokenInfoCall := oauth2Service.Tokeninfo()
tokenInfoCall.IdToken(authorizationHeaderSplitted[1])
_, err = tokenInfoCall.Do()
if err != nil {
utils.GetLogger().WithError(err).Error(err)
utils.JSONError(c.Writer, model.ErrBadRequestFormat)
return
}
}