add reset password

fix logger panic, update endpoint, add password reset
pull/10616/head
Kelvin Wang 2018-10-18 13:20:26 -04:00
parent a9b9a0b538
commit 360f8035dd
4 changed files with 114 additions and 5 deletions

View File

@ -63,6 +63,7 @@ func NewAPIHandler(b *APIBackend) *APIHandler {
h.SessionHandler = NewSessionHandler()
h.SessionHandler.BasicAuthService = b.BasicAuthService
h.SessionHandler.SessionService = b.SessionService
h.SessionHandler.Logger = b.Logger.With(zap.String("handler", "basicAuth"))
h.BucketHandler = NewBucketHandler(b.UserResourceMappingService)
h.BucketHandler.BucketService = b.BucketService
@ -73,6 +74,7 @@ func NewAPIHandler(b *APIBackend) *APIHandler {
h.UserHandler = NewUserHandler()
h.UserHandler.UserService = b.UserService
h.UserHandler.BasicAuthService = b.BasicAuthService
h.DashboardHandler = NewDashboardHandler(b.UserResourceMappingService)
h.DashboardHandler.DashboardService = b.DashboardService

View File

@ -36,7 +36,7 @@ func (h *SessionHandler) handleSignin(w http.ResponseWriter, r *http.Request) {
req, err := decodeSigninRequest(ctx, r)
if err != nil {
h.Logger.Info("failed to decode request", zap.String("handler", "basicAuth"), zap.Error(err))
h.Logger.Info("failed to decode request", zap.Error(err))
EncodeError(ctx, err, w)
return
}
@ -80,7 +80,7 @@ func (h *SessionHandler) handleSignout(w http.ResponseWriter, r *http.Request) {
req, err := decodeSignoutRequest(ctx, r)
if err != nil {
h.Logger.Info("failed to decode request", zap.String("handler", "basicAuth"), zap.Error(err))
h.Logger.Info("failed to decode request", zap.Error(err))
EncodeError(ctx, err, w)
return
}

View File

@ -2713,6 +2713,29 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/Error"
/me/password:
put:
tags:
- Users
summary: Update password
security:
- basicAuth: []
requestBody:
description: new password
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/PasswordResetBody"
responses:
'204':
description: password succesfully updated
default:
description: unsuccessful authentication
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
'/tasks/{taskID}/members':
get:
tags:
@ -3003,6 +3026,29 @@ paths:
application/json:
schema:
$ref: "#/components/schemas/Error"
'/users/{userID}/password':
put:
tags:
- Users
summary: Update password
security:
- basicAuth: []
requestBody:
description: new password
required: true
content:
application/json:
schema:
$ref: "#/components/schemas/PasswordResetBody"
responses:
'204':
description: password succesfully updated
default:
description: unsuccessful authentication
content:
application/json:
schema:
$ref: "#/components/schemas/Error"
'/views/{viewID}/members':
get:
tags:
@ -4684,6 +4730,12 @@ components:
$ref: "#/components/schemas/Bucket"
auth:
$ref: "#/components/schemas/Authorization"
PasswordResetBody:
properties:
password:
type: string
required:
- password
Health:
type: object
properties:
@ -4699,4 +4751,4 @@ components:
type: string
enum:
- unhealthy
- healthy
- healthy

View File

@ -17,7 +17,8 @@ import (
// UserHandler represents an HTTP API handler for users.
type UserHandler struct {
*httprouter.Router
UserService platform.UserService
UserService platform.UserService
BasicAuthService platform.BasicAuthService
}
// NewUserHandler returns a new instance of UserHandler.
@ -27,14 +28,68 @@ func NewUserHandler() *UserHandler {
}
h.HandlerFunc("POST", "/api/v2/users", h.handlePostUser)
h.HandlerFunc("GET", "/api/v2/me", h.handleGetMe)
h.HandlerFunc("GET", "/api/v2/users", h.handleGetUsers)
h.HandlerFunc("GET", "/api/v2/users/:id", h.handleGetUser)
h.HandlerFunc("PATCH", "/api/v2/users/:id", h.handlePatchUser)
h.HandlerFunc("DELETE", "/api/v2/users/:id", h.handleDeleteUser)
h.HandlerFunc("PUT", "/api/v2/users/:id/password", h.handlePutPassword)
h.HandlerFunc("GET", "/api/v2/me", h.handleGetMe)
h.HandlerFunc("PUT", "/api/v2/me/password", h.handlePutPassword)
return h
}
// handlePutPassword is the HTTP handler for the PUT /api/v2/users/:id/password
func (h *UserHandler) handlePutPassword(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()
req, err := decodePasswordResetRequest(ctx, r)
if err != nil {
EncodeError(ctx, err, w)
return
}
err = h.BasicAuthService.CompareAndSetPassword(ctx, req.Username, req.PasswordOld, req.PasswordNew)
if err != nil {
EncodeError(ctx, err, w)
return
}
w.WriteHeader(http.StatusNoContent)
}
type passwordResetRequest struct {
Username string
PasswordOld string
PasswordNew string
}
type passwordResetRequestBody struct {
Password string `json:"password"`
}
func decodePasswordResetRequest(ctx context.Context, r *http.Request) (*passwordResetRequest, error) {
u, o, ok := r.BasicAuth()
if !ok {
return nil, fmt.Errorf("invalid basic auth")
}
pr := new(passwordResetRequestBody)
err := json.NewDecoder(r.Body).Decode(pr)
if err != nil {
return nil, &platform.Error{
Code: platform.EInvalid,
Err: err,
}
}
return &passwordResetRequest{
Username: u,
PasswordOld: o,
PasswordNew: pr.Password,
}, nil
}
// handlePostUser is the HTTP handler for the POST /api/v2/users route.
func (h *UserHandler) handlePostUser(w http.ResponseWriter, r *http.Request) {
ctx := r.Context()