diff --git a/src/v2/handler/onboard/onboard_forgot_password.go b/src/v2/handler/onboard/onboard_forgot_password.go new file mode 100644 index 0000000..9d980d1 --- /dev/null +++ b/src/v2/handler/onboard/onboard_forgot_password.go @@ -0,0 +1,55 @@ +package onboard + +import ( + "encoding/json" + "io/ioutil" + "log" + "net/http" + + "github.com/asaskevich/govalidator" + "github.com/bb-consent/api/src/common" + "github.com/bb-consent/api/src/config" + "github.com/bb-consent/api/src/user" + "github.com/bb-consent/api/src/v2/iam" +) + +type forgotPassword struct { + Username string `json:"username" valid:"required,email"` +} + +// OnboardForgotPassword User forgot the password, need to reset the password +func OnboardForgotPassword(w http.ResponseWriter, r *http.Request) { + var fp forgotPassword + + b, _ := ioutil.ReadAll(r.Body) + json.Unmarshal(b, &fp) + + // validating request params + valid, err := govalidator.ValidateStruct(fp) + if !valid { + log.Printf("Invalid request params for forgot password") + common.HandleErrorV2(w, http.StatusBadRequest, err.Error(), err) + return + } + + log.Printf("User: %v forgot password", fp.Username) + + sanitizedUserName := common.Sanitize(fp.Username) + + //Get user details from DB + u, err := user.GetByEmail(sanitizedUserName) + if err != nil { + log.Printf("User with %v doesnt exist", fp.Username) + common.HandleErrorV2(w, http.StatusBadRequest, err.Error(), err) + return + } + err = iam.ForgotPassword(u.IamID) + if err != nil { + m := "Failed to send email" + common.HandleErrorV2(w, http.StatusBadRequest, m, err) + return + } + + w.Header().Set(config.ContentTypeHeader, config.ContentTypeJSON) + w.WriteHeader(http.StatusOK) +} diff --git a/src/v2/http_path/onboard_paths.go b/src/v2/http_path/onboard_paths.go index ac89cf6..233420c 100644 --- a/src/v2/http_path/onboard_paths.go +++ b/src/v2/http_path/onboard_paths.go @@ -23,3 +23,5 @@ const GetOrganizationLogoImage = "/v2/onboard/organisation/logoimage" const OnboardReadOrganisationAdmin = "/v2/onboard/admin" const OnboardUpdateOrganisationAdmin = "/v2/onboard/admin" + +const OnboardForgotPassword = "/v2/onboard/password/forgot" diff --git a/src/v2/http_path/routes.go b/src/v2/http_path/routes.go index 555ffb7..3d431b7 100644 --- a/src/v2/http_path/routes.go +++ b/src/v2/http_path/routes.go @@ -120,6 +120,7 @@ func SetRoutes(r *mux.Router, e *casbin.Enforcer) { r.Handle(OnboardRefreshToken, m.Chain(onboardHandler.OnboardRefreshToken, m.AddContentType())).Methods("POST") r.Handle(ExchangeAuthorizationCode, m.Chain(onboardHandler.ExchangeAuthorizationCode, m.LoggerNoAuth())).Methods("POST") + r.Handle(OnboardForgotPassword, m.Chain(onboardHandler.OnboardForgotPassword, m.LoggerNoAuth())).Methods("PUT") r.Handle(GetOrganizationByID, m.Chain(onboardHandler.OnboardReadOrganisation, m.Logger(), m.Authorize(e), m.SetApplicationMode(), m.Authenticate(), m.AddContentType())).Methods("GET") r.Handle(UpdateOrganization, m.Chain(onboardHandler.UpdateOrganization, m.Logger(), m.Authorize(e), m.SetApplicationMode(), m.Authenticate(), m.AddContentType())).Methods("PUT") diff --git a/src/v2/iam/iam.go b/src/v2/iam/iam.go index 84861c5..f4e0b7c 100644 --- a/src/v2/iam/iam.go +++ b/src/v2/iam/iam.go @@ -49,6 +49,23 @@ func RefreshToken(clientId string, refreshToken string, realm string, client *go return token, err } +func ForgotPassword(iamId string) error { + client := GetClient() + token, err := GetAdminToken(IamConfig.AdminUser, IamConfig.AdminPassword, "master", client) + if err != nil { + return err + } + params := gocloak.ExecuteActionsEmail{ + UserID: &iamId, + Actions: &[]string{ + "UPDATE_PASSWORD", + }, + } + + err = client.ExecuteActionsEmail(context.Background(), token.AccessToken, IamConfig.Realm, params) + return err +} + func GetClient() *gocloak.GoCloak { client := gocloak.NewClient(IamConfig.URL) return client