Skip to content

Commit

Permalink
Merge pull request #19 from cho4036/minor_fix
Browse files Browse the repository at this point in the history
minor fix: add path paramter(organization) for user resource
  • Loading branch information
ktkfree authored Apr 7, 2023
2 parents 039b35e + 1476d44 commit c2d1d88
Show file tree
Hide file tree
Showing 12 changed files with 1,020 additions and 483 deletions.
429 changes: 296 additions & 133 deletions api/swagger/docs.go

Large diffs are not rendered by default.

426 changes: 295 additions & 131 deletions api/swagger/swagger.json

Large diffs are not rendered by default.

345 changes: 238 additions & 107 deletions api/swagger/swagger.yaml

Large diffs are not rendered by default.

1 change: 0 additions & 1 deletion go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ require (
github.com/Nerzal/gocloak/v13 v13.1.0
github.com/dgrijalva/jwt-go v3.2.0+incompatible
github.com/go-playground/validator v9.31.0+incompatible
github.com/gofrs/uuid v4.0.0+incompatible
github.com/golang-jwt/jwt v3.2.2+incompatible
github.com/golang-jwt/jwt/v4 v4.5.0
github.com/golang/mock v1.6.0
Expand Down
18 changes: 16 additions & 2 deletions internal/delivery/http/organization.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,10 @@ func (h *OrganizationHandler) GetOrganization(w http.ResponseWriter, r *http.Req
organization, err := h.usecase.Get(organizationId)
if err != nil {
log.Errorf("error is :%s(%T)", err.Error(), err)
if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound {
ErrorJSON(w, httpErrors.NewBadRequestError(err))
return
}

ErrorJSON(w, err)
return
Expand Down Expand Up @@ -174,7 +178,10 @@ func (h *OrganizationHandler) DeleteOrganization(w http.ResponseWriter, r *http.
err = h.usecase.Delete(organizationId, token)
if err != nil {
log.Errorf("error is :%s(%T)", err.Error(), err)

if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound {
ErrorJSON(w, httpErrors.NewBadRequestError(err))
return
}
ErrorJSON(w, err)
return
}
Expand Down Expand Up @@ -211,7 +218,10 @@ func (h *OrganizationHandler) UpdateOrganization(w http.ResponseWriter, r *http.
organization, err := h.usecase.Update(organizationId, input)
if err != nil {
log.Errorf("error is :%s(%T)", err.Error(), err)

if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound {
ErrorJSON(w, httpErrors.NewBadRequestError(err))
return
}
ErrorJSON(w, err)
return
}
Expand Down Expand Up @@ -252,6 +262,10 @@ func (h *OrganizationHandler) UpdatePrimaryCluster(w http.ResponseWriter, r *htt

err = h.usecase.UpdatePrimaryClusterId(organizationId, input.PrimaryClusterId)
if err != nil {
if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound {
ErrorJSON(w, httpErrors.NewBadRequestError(err))
return
}
ErrorJSON(w, err)
return
}
Expand Down
163 changes: 107 additions & 56 deletions internal/delivery/http/user.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"github.com/openinfradev/tks-api/pkg/log"

"github.com/gorilla/mux"
"github.com/openinfradev/tks-api/internal/auth/request"
"github.com/openinfradev/tks-api/internal/usecase"
"github.com/openinfradev/tks-api/pkg/domain"
"github.com/openinfradev/tks-api/pkg/httpErrors"
Expand All @@ -33,12 +32,19 @@ type UserHandler struct {
// @Description Create user
// @Accept json
// @Produce json
// @Param organizationId path string true "organizationId"
// @Param body body domain.CreateUserRequest true "create user request"
// @Success 200 {object} domain.CreateUserResponse "create user response"
// @Router /users [post]
// @Router /organizations/{organizationId}/users [post]
// @Security JWT
func (u UserHandler) Create(w http.ResponseWriter, r *http.Request) {
// TODO implement validation
vars := mux.Vars(r)
organizationId, ok := vars["organizationId"]
if !ok {
ErrorJSON(w, httpErrors.NewBadRequestError(fmt.Errorf("organizationId not found in path")))
return
}

input := domain.CreateUserRequest{}
err := UnmarshalRequestInput(r, &input)
if err != nil {
Expand All @@ -48,20 +54,21 @@ func (u UserHandler) Create(w http.ResponseWriter, r *http.Request) {
return
}

userInfo, ok := request.UserFrom(r.Context())
if !ok {
ErrorJSON(w, httpErrors.NewBadRequestError(fmt.Errorf("user info not found in token")))
return
}
//userInfo, ok := request.UserFrom(r.Context())
//if !ok {
// ErrorJSON(w, httpErrors.NewBadRequestError(fmt.Errorf("user info not found in token")))
// return
//}

ctx := r.Context()
var user domain.User
if err = domain.Map(input, &user); err != nil {
log.Error(err)
}
user.Organization = domain.Organization{
ID: userInfo.GetOrganizationId(),
ID: organizationId,
}

resUser, err := u.usecase.Create(ctx, &user)
if err != nil {
log.Errorf("error is :%s(%T)", err.Error(), err)
Expand Down Expand Up @@ -89,22 +96,33 @@ func (u UserHandler) Create(w http.ResponseWriter, r *http.Request) {
// @Description Get user detail
// @Accept json
// @Produce json
// @Param userId path string true "userId"
// @Param organizationId path string true "organizationId"
// @Param accountId path string true "accountId"
// @Success 200 {object} domain.GetUserResponse
// @Router /users/{userId} [get]
// @Router /organizations/{organizationId}/users/{accountId} [get]
// @Security JWT
func (u UserHandler) Get(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
userId, ok := vars["userId"]
userId, ok := vars["accountId"]
if !ok {
ErrorJSON(w, httpErrors.NewBadRequestError(fmt.Errorf("accountId not found in path")))
return
}
organizationId, ok := vars["organizationId"]
if !ok {
ErrorJSON(w, httpErrors.NewBadRequestError(fmt.Errorf("userId not found in path")))
ErrorJSON(w, httpErrors.NewBadRequestError(fmt.Errorf("organizationId not found in path")))
return
}

user, err := u.usecase.GetByAccountId(r.Context(), userId)
user, err := u.usecase.GetByAccountId(r.Context(), userId, organizationId)
if err != nil {
log.Errorf("error is :%s(%T)", err.Error(), err)

if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound {
ErrorJSON(w, httpErrors.NewBadRequestError(err))
return
}

ErrorJSON(w, err)
return
}
Expand All @@ -123,11 +141,19 @@ func (u UserHandler) Get(w http.ResponseWriter, r *http.Request) {
// @Description Get user list
// @Accept json
// @Produce json
// @Param organizationId path string true "organizationId"
// @Success 200 {object} []domain.ListUserBody
// @Router /users [get]
// @Router /organizations/{organizationId}/users [get]
// @Security JWT
func (u UserHandler) List(w http.ResponseWriter, r *http.Request) {
users, err := u.usecase.List(r.Context())
vars := mux.Vars(r)
organizationId, ok := vars["organizationId"]
if !ok {
ErrorJSON(w, httpErrors.NewBadRequestError(fmt.Errorf("organizationId not found in path")))
return
}

users, err := u.usecase.List(r.Context(), organizationId)
if err != nil {
if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound {
ResponseJSON(w, http.StatusNoContent, domain.ListUserResponse{})
Expand Down Expand Up @@ -156,22 +182,28 @@ func (u UserHandler) List(w http.ResponseWriter, r *http.Request) {
// @Description Delete user
// @Accept json
// @Produce json
// @Param userId path string true "userId"
// @Param organizationId path string true "organizationId"
// @Param accountId path string true "accountId"
// @Success 200 {object} domain.User
// @Router /users/{userId} [delete]
// @Router /organizations/{organizationId}/users/{accountId} [delete]
// @Security JWT
func (u UserHandler) Delete(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
userId, ok := vars["userId"]
userId, ok := vars["accountId"]
if !ok {
ErrorJSON(w, httpErrors.NewBadRequestError(fmt.Errorf("accountId not found in path")))
return
}
organizationId, ok := vars["organizationId"]
if !ok {
ErrorJSON(w, httpErrors.NewBadRequestError(fmt.Errorf("userId not found in path")))
ErrorJSON(w, httpErrors.NewBadRequestError(fmt.Errorf("organizationId not found in path")))
return
}

err := u.usecase.DeleteByAccountId(r.Context(), userId)
err := u.usecase.DeleteByAccountId(r.Context(), userId, organizationId)
if err != nil {
if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound {
ErrorJSON(w, httpErrors.NewNotFoundError(err))
ErrorJSON(w, httpErrors.NewBadRequestError(err))
return
}
log.Errorf("error is :%s(%T)", err.Error(), err)
Expand All @@ -189,16 +221,22 @@ func (u UserHandler) Delete(w http.ResponseWriter, r *http.Request) {
// @Description Update user detail
// @Accept json
// @Produce json
// @Param userId path string true "userId"
// @Param organizationId path string true "organizationId"
// @Param accountId path string true "accountId"
// @Param body body domain.UpdateUserRequest true "update user request"
// @Success 200 {object} domain.UpdateUserResponse
// @Router /users/{userId} [put]
// @Router /organizations/{organizationId}/users/{accountId} [put]
// @Security JWT
func (u UserHandler) Update(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
userId, ok := vars["userId"]
accountId, ok := vars["accountId"]
if !ok {
ErrorJSON(w, httpErrors.NewBadRequestError(fmt.Errorf("userId not found in path")))
ErrorJSON(w, httpErrors.NewBadRequestError(fmt.Errorf("accountId not found in path")))
return
}
organizationId, ok := vars["organizationId"]
if !ok {
ErrorJSON(w, httpErrors.NewBadRequestError(fmt.Errorf("organizationId not found in path")))
return
}

Expand All @@ -211,25 +249,21 @@ func (u UserHandler) Update(w http.ResponseWriter, r *http.Request) {
return
}

userInfo, ok := request.UserFrom(r.Context())
if !ok {
ErrorJSON(w, httpErrors.NewBadRequestError(fmt.Errorf("user info not found in token")))
return
}

ctx := r.Context()
var user domain.User
if err = domain.Map(input, &user); err != nil {
log.Error(err)
}
user.Organization = domain.Organization{
ID: userInfo.GetOrganizationId(),
ID: organizationId,
}
user.AccountId = userId
user.AccountId = accountId

resUser, err := u.usecase.UpdateByAccountId(ctx, userId, &user)
resUser, err := u.usecase.UpdateByAccountId(ctx, accountId, &user)
if err != nil {
log.Errorf("error is :%s(%T)", err.Error(), err)
if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound {
ErrorJSON(w, httpErrors.NewBadRequestError(err))
}

ErrorJSON(w, err)
return
Expand All @@ -249,30 +283,38 @@ func (u UserHandler) Update(w http.ResponseWriter, r *http.Request) {
// @Description Update user password detail
// @Accept json
// @Produce json
// @Param userId path string true "userId"
// @Param organizationId path string true "organizationId"
// @Param accountId path string true "accountId"
// @Param body body domain.UpdatePasswordRequest true "update user password request"
// @Success 200 {object} domain.UpdatePasswordResponse
// @Router /users/{userId}/password [put]
// @Router /organizations/{organizationId}/users/{accountId}/password [put]
// @Security JWT
func (u UserHandler) UpdatePassword(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
userId, ok := vars["userId"]
accountId, ok := vars["accountId"]
if !ok {
ErrorJSON(w, httpErrors.NewBadRequestError(fmt.Errorf("accountId not found in path")))
return
}
organizationId, ok := vars["organizationId"]
if !ok {
ErrorJSON(w, httpErrors.NewBadRequestError(fmt.Errorf("userId not found in path")))
ErrorJSON(w, httpErrors.NewBadRequestError(fmt.Errorf("organizationId not found in path")))
return
}

input := domain.UpdatePasswordRequest{}
err := UnmarshalRequestInput(r, &input)
if err != nil {
log.Errorf("error is :%s(%T)", err.Error(), err)

ErrorJSON(w, httpErrors.NewBadRequestError(err))
return
}

err = u.usecase.UpdatePasswordByAccountId(r.Context(), userId, input.Password)
err = u.usecase.UpdatePasswordByAccountId(r.Context(), accountId, input.Password, organizationId)
if err != nil {
if _, status := httpErrors.ErrorResponse(err); status == http.StatusNotFound {
ErrorJSON(w, httpErrors.NewBadRequestError(err))
return
}
log.Errorf("error is :%s(%T)", err.Error(), err)

ErrorJSON(w, err)
Expand All @@ -284,34 +326,43 @@ func (u UserHandler) UpdatePassword(w http.ResponseWriter, r *http.Request) {

// CheckId godoc
// @Tags Users
// @Summary Update user password detail
// @Description Update user password detail
// @Summary Get user id existence
// @Description return true when accountId exists
// @Accept json
// @Produce json
// @Param userId path string true "userId"
// @Success 204
// @Failure 409
// @Router /users/{userId} [post]
// @Param organizationId path string true "organizationId"
// @Param accountId path string true "accountId"
// @Success 200
// @Router /organizations/{organizationId}/users/{accountId}/existence [get]
// @Security JWT
func (u UserHandler) CheckId(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
userId, ok := vars["userId"]
accountId, ok := vars["accountId"]
if !ok {
ErrorJSON(w, httpErrors.NewBadRequestError(fmt.Errorf("accountId not found in path")))
return
}
organizationId, ok := vars["organizationId"]
if !ok {
ErrorJSON(w, httpErrors.NewBadRequestError(fmt.Errorf("userId not found in path")))
ErrorJSON(w, httpErrors.NewBadRequestError(fmt.Errorf("organizationId not found in path")))
return
}

_, err := u.usecase.GetByAccountId(r.Context(), userId)
exist := true
_, err := u.usecase.GetByAccountId(r.Context(), accountId, organizationId)
if err != nil {
if _, code := httpErrors.ErrorResponse(err); code == http.StatusNotFound {
ResponseJSON(w, http.StatusNoContent, nil)
exist = false
} else {
ErrorJSON(w, err)
return
}
ErrorJSON(w, err)
return
}

ResponseJSON(w, http.StatusConflict, nil)
var out domain.CheckExistedIdResponse
out.Existed = exist

ResponseJSON(w, http.StatusOK, out)
}

func NewUserHandler(h usecase.IUserUsecase) IUserHandler {
Expand Down
1 change: 1 addition & 0 deletions internal/repository/organization.go
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,7 @@ func (r *OrganizationRepository) Update(organizationId string, in domain.UpdateO
res := r.db.Model(&Organization{}).
Where("id = ?", organizationId).
Updates(Organization{
Name: in.Name,
Description: in.Description,
Phone: in.Phone,
PrimaryClusterId: in.PrimaryClusterId,
Expand Down
Loading

0 comments on commit c2d1d88

Please sign in to comment.