package device import ( "errors" "fmt" "net/http" "github.com/gin-gonic/gin" "edge-infra.dev/pkg/edge/iam/apperror" "edge-infra.dev/pkg/edge/iam/log" "edge-infra.dev/pkg/edge/iam/util" ) // todo: bring back length bindings // todo: why json not form data type selfServiceForm struct { OldPassword string `json:"old_password" binding:"required"` NewPassword string `json:"new_password" binding:"required"` Action string `json:"action"` } func (dm *AuthMethod) selfService(c *gin.Context) error { logger := log.Get(c.Request.Context()).WithName("device-selfservice") // grab the form var form selfServiceForm if err := c.BindJSON(&form); err != nil { dm.metrics.IncSignUpRequestsTotal(signUpPin, util.Failed) return apperror.NewAbortError( fmt.Errorf("failed to self service on bad request: %w", err), http.StatusBadRequest) } session, _ := dm.sessionStore.Get(c.Request, "oauth2") token, ok := session.Values["device_token"] if !ok { err := errors.New("no token_set found in session. need one to self serve") return apperror.NewAbortError(err, http.StatusForbidden) } if form.Action == "cancel" { delete(session.Values, "device_token") if err := session.Save(c.Request, c.Writer); err != nil { return apperror.NewAbortError( fmt.Errorf("failed to save cookie session: %w", err), http.StatusInternalServerError) } // c.Redirect(http.StatusTemporaryRedirect, "/idp/entry/device") return nil } // try and update the password validationResult, err := dm.service.SelfService(token.(string), form.OldPassword, form.NewPassword) if err != nil { // todo: handle invalid user entry differnet from other reasons if err == ErrSelfServiceDenied { return apperror.NewStatusError(err, http.StatusUnprocessableEntity) } if err == ErrSelfServiceBadRequest { // todo: pass along the validation errors? logger.Info("self service failed", "bad request", validationResult) // apperror.NewJSONError(err, http.StatusUnprocessableEntity, "bad request", validationResult) c.JSON(http.StatusUnprocessableEntity, validationResult) return nil } return apperror.NewAbortError( fmt.Errorf("failed to self service device password: %w", err), http.StatusInternalServerError) } // yeah, we did it - back to start delete(session.Values, "device_token") if err := session.Save(c.Request, c.Writer); err != nil { return apperror.NewAbortError( fmt.Errorf("failed to save cookie session: %w", err), http.StatusInternalServerError) } dm.metrics.IncSignUpRequestsTotal(signUpPin, util.Succeeded) return nil }