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

minor fix: add path paramter(organization) for user resource #19

Merged
merged 4 commits into from
Apr 7, 2023
Merged
Show file tree
Hide file tree
Changes from all 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
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