Skip to content

Commit

Permalink
update user profile
Browse files Browse the repository at this point in the history
  • Loading branch information
Kervin Christianata committed Apr 24, 2022
1 parent 5bed3e1 commit 80e3e9b
Show file tree
Hide file tree
Showing 9 changed files with 384 additions and 12 deletions.
23 changes: 23 additions & 0 deletions cmd/api/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -161,6 +161,29 @@ func (app *application) requireAuthenticatedUser(next http.HandlerFunc) http.Han
return
}

if user.Role != "user" {
app.notPermittedResponse(w, r)
return
}

next.ServeHTTP(w, r)
})
}

func (app *application) requireAuthenticatedAdmin(next http.HandlerFunc) http.HandlerFunc {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
user := app.contextGetUser(r)

if user.IsAnonymous() {
app.authenticationRequiredResponse(w, r)
return
}

if user.Role != "admin" {
app.notPermittedResponse(w, r)
return
}

next.ServeHTTP(w, r)
})
}
Expand Down
12 changes: 9 additions & 3 deletions cmd/api/routes.go
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,12 @@ func (app *application) routes() http.Handler {
router.HandlerFunc(http.MethodPost, "/api/users", app.registerUserHandler)
router.HandlerFunc(http.MethodGet, "/api/users/activated", app.activateUserHandler)
router.HandlerFunc(http.MethodPut, "/api/users/password", app.updateUserPasswordHandler)
router.HandlerFunc(http.MethodGet, "/api/users", app.requireAuthenticatedUser(app.getUserHandler))

router.HandlerFunc(http.MethodPut, "/api/users/update/name", app.requireAuthenticatedUser(app.updateUserNameHandler))
router.HandlerFunc(http.MethodPut, "/api/users/update/gender", app.requireAuthenticatedUser(app.updateUserGenderHandler))
router.HandlerFunc(http.MethodPut, "/api/users/update/date-of-birth", app.requireAuthenticatedUser(app.updateUserDateOfBirthHandler))
router.HandlerFunc(http.MethodPut, "/api/users/update/phone-number", app.requireAuthenticatedUser(app.updateUserPhoneNumberHandler))

// Tokens
router.HandlerFunc(http.MethodPost, "/api/tokens/authentication", app.createAuthenticationTokenHandler)
Expand Down Expand Up @@ -90,10 +96,10 @@ func (app *application) routes() http.Handler {
router.HandlerFunc(http.MethodDelete, "/cms/brands/:id", app.deleteBrandHandler)

// Movies
router.HandlerFunc(http.MethodGet, "/cms/movies", app.requireActivatedUser(app.listMoviesHandler))
router.HandlerFunc(http.MethodGet, "/cms/movies", app.requireAuthenticatedAdmin(app.listMoviesHandler))
router.HandlerFunc(http.MethodPost, "/cms/movies", app.requirePermission("movies:write", app.createMovieHandler))
router.HandlerFunc(http.MethodGet, "/cms/movies/:id", app.requireActivatedUser(app.showMovieHandler))
router.HandlerFunc(http.MethodPut, "/cms/movies/:id", app.requireActivatedUser(app.fullUpdateMovieHandler))
router.HandlerFunc(http.MethodGet, "/cms/movies/:id", app.requireAuthenticatedAdmin(app.showMovieHandler))
router.HandlerFunc(http.MethodPut, "/cms/movies/:id", app.requireAuthenticatedAdmin(app.fullUpdateMovieHandler))
router.HandlerFunc(http.MethodPatch, "/cms/movies/:id", app.requirePermission("movies:write", app.updateMovieHandler))
router.HandlerFunc(http.MethodDelete, "/cms/movies/:id", app.requirePermission("movies:write", app.deleteMovieHandler))

Expand Down
188 changes: 188 additions & 0 deletions cmd/api/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -263,5 +263,193 @@ func (app *application) updateUserPasswordHandler(w http.ResponseWriter, r *http
if err != nil {
app.serverErrorResponse(w, r, err)
}
}

func (app *application) getUserHandler(w http.ResponseWriter, r *http.Request) {
user := app.contextGetUser(r)

err := app.writeJSON(w, http.StatusOK, http.StatusText(http.StatusOK), user, nil)
if err != nil {
app.serverErrorResponse(w, r, err)
}
}

func (app *application) updateUserNameHandler(w http.ResponseWriter, r *http.Request) {
var input struct {
Name string `json:"name"`
}

user := app.contextGetUser(r)

err := app.readJSON(w, r, &input)
if err != nil {
app.badRequestResponse(w, r, err)
return
}

v := validator.New()

data.ValidateName(v, input.Name)

if !v.Valid() {
app.failedValidationResponse(w, r, v.Errors)
return
}

// Set the new name for the user.
user.Name = input.Name

// Save the updated user record in our database, checking for any edit conflicts as normal.
err = app.models.Users.UpdateName(user)
if err != nil {
switch {
case errors.Is(err, data.ErrEditConflict):
app.editConflictResponse(w, r)
default:
app.serverErrorResponse(w, r, err)
}
return
}

// Send the user a confirmation message.
env := envelope{"message": "user name has been successfully updated"}
err = app.writeJSON(w, http.StatusOK, http.StatusText(http.StatusOK), env, nil)
if err != nil {
app.serverErrorResponse(w, r, err)
}
}

func (app *application) updateUserGenderHandler(w http.ResponseWriter, r *http.Request) {
var input struct {
Gender string `json:"gender"`
}

user := app.contextGetUser(r)

err := app.readJSON(w, r, &input)
if err != nil {
app.badRequestResponse(w, r, err)
return
}

v := validator.New()

data.ValidateGender(v, input.Gender)

if !v.Valid() {
app.failedValidationResponse(w, r, v.Errors)
return
}

// Set the new name for the user.
user.Gender = input.Gender

// Save the updated user record in our database, checking for any edit conflicts as normal.
err = app.models.Users.UpdateGender(user)
if err != nil {
switch {
case errors.Is(err, data.ErrEditConflict):
app.editConflictResponse(w, r)
default:
app.serverErrorResponse(w, r, err)
}
return
}

// Send the user a confirmation message.
env := envelope{"message": "user gender has been successfully updated"}
err = app.writeJSON(w, http.StatusOK, http.StatusText(http.StatusOK), env, nil)
if err != nil {
app.serverErrorResponse(w, r, err)
}
}

func (app *application) updateUserDateOfBirthHandler(w http.ResponseWriter, r *http.Request) {
var input struct {
DateOfBirth time.Time `json:"date_of_birth"`
}

user := app.contextGetUser(r)

err := app.readJSON(w, r, &input)
if err != nil {
app.badRequestResponse(w, r, err)
return
}

v := validator.New()

data.ValidateDateOfBirth(v, input.DateOfBirth)

if !v.Valid() {
app.failedValidationResponse(w, r, v.Errors)
return
}

// Set the new name for the user.
user.DateOfBirth = input.DateOfBirth

// Save the updated user record in our database, checking for any edit conflicts as normal.
err = app.models.Users.UpdateDateOfBirth(user)
if err != nil {
switch {
case errors.Is(err, data.ErrEditConflict):
app.editConflictResponse(w, r)
default:
app.serverErrorResponse(w, r, err)
}
return
}

// Send the user a confirmation message.
env := envelope{"message": "user dob has been successfully updated"}
err = app.writeJSON(w, http.StatusOK, http.StatusText(http.StatusOK), env, nil)
if err != nil {
app.serverErrorResponse(w, r, err)
}
}

func (app *application) updateUserPhoneNumberHandler(w http.ResponseWriter, r *http.Request) {
var input struct {
PhoneNumber string `json:"phone_number"`
}

user := app.contextGetUser(r)

err := app.readJSON(w, r, &input)
if err != nil {
app.badRequestResponse(w, r, err)
return
}

v := validator.New()

data.ValidatePhoneNumber(v, input.PhoneNumber)

if !v.Valid() {
app.failedValidationResponse(w, r, v.Errors)
return
}

// Set the new name for the user.
user.PhoneNumber = input.PhoneNumber

// Save the updated user record in our database, checking for any edit conflicts as normal.
err = app.models.Users.UpdatePhoneNumber(user)
if err != nil {
switch {
case errors.Is(err, data.ErrEditConflict):
app.editConflictResponse(w, r)
default:
app.serverErrorResponse(w, r, err)
}
return
}

// Send the user a confirmation message.
env := envelope{"message": "user phone number has been successfully updated"}
err = app.writeJSON(w, http.StatusOK, http.StatusText(http.StatusOK), env, nil)
if err != nil {
app.serverErrorResponse(w, r, err)
}
}
1 change: 1 addition & 0 deletions internal/data/models.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ var (
ErrRecordNotFound = errors.New("record not found")
ErrEditConflict = errors.New("edit conflict")
ErrDuplicateSlug = errors.New("duplicate slug")
ErrInvalidEnum = errors.New("invalid enum value")
)

type Models struct {
Expand Down
Loading

0 comments on commit 80e3e9b

Please sign in to comment.