mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-07 04:40:05 -06:00
113 lines
3.4 KiB
Go
113 lines
3.4 KiB
Go
package svc
|
|
|
|
import (
|
|
"net/http"
|
|
"strings"
|
|
|
|
"github.com/CiscoM31/godata"
|
|
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
|
|
cs3rpc "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
|
|
"github.com/go-chi/render"
|
|
libregraph "github.com/opencloud-eu/libre-graph-api-go"
|
|
|
|
"github.com/opencloud-eu/opencloud/services/graph/pkg/errorcode"
|
|
revactx "github.com/opencloud-eu/reva/v2/pkg/ctx"
|
|
"github.com/opencloud-eu/reva/v2/pkg/events"
|
|
)
|
|
|
|
// ChangeOwnPassword implements the Service interface. It allows the user to change
|
|
// its own password
|
|
func (g Graph) ChangeOwnPassword(w http.ResponseWriter, r *http.Request) {
|
|
ctx := r.Context()
|
|
u, ok := revactx.ContextGetUser(ctx)
|
|
if !ok {
|
|
g.logger.Error().Msg("user not in context")
|
|
errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError, "user not in context")
|
|
return
|
|
}
|
|
|
|
sanitizedPath := strings.TrimPrefix(r.URL.Path, "/graph/v1.0/")
|
|
_, err := godata.ParseRequest(r.Context(), sanitizedPath, r.URL.Query())
|
|
if err != nil {
|
|
g.logger.Err(err).Interface("query", r.URL.Query()).Msg("query error")
|
|
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
cpw := libregraph.NewPasswordChangeWithDefaults()
|
|
err = StrictJSONUnmarshal(r.Body, cpw)
|
|
if err != nil {
|
|
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error())
|
|
return
|
|
}
|
|
|
|
currentPw := cpw.GetCurrentPassword()
|
|
if currentPw == "" {
|
|
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "current password cannot be empty")
|
|
return
|
|
}
|
|
|
|
newPw := cpw.GetNewPassword()
|
|
if newPw == "" {
|
|
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "new password cannot be empty")
|
|
return
|
|
}
|
|
|
|
if newPw == currentPw {
|
|
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "new password must be different from current password")
|
|
return
|
|
}
|
|
|
|
authReq := &gateway.AuthenticateRequest{
|
|
Type: "basic",
|
|
ClientId: u.Username,
|
|
ClientSecret: currentPw,
|
|
}
|
|
client, err := g.gatewaySelector.Next()
|
|
if err != nil {
|
|
errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError, "could not select next gateway client, aborting")
|
|
return
|
|
}
|
|
authRes, err := client.Authenticate(r.Context(), authReq)
|
|
if err != nil {
|
|
errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError, err.Error())
|
|
return
|
|
}
|
|
|
|
switch authRes.Status.Code {
|
|
case cs3rpc.Code_CODE_OK:
|
|
break
|
|
case cs3rpc.Code_CODE_UNAUTHENTICATED, cs3rpc.Code_CODE_PERMISSION_DENIED:
|
|
errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "wrong current password")
|
|
return
|
|
default:
|
|
errorcode.InvalidRequest.Render(w, r, http.StatusInternalServerError, "password change failed")
|
|
return
|
|
}
|
|
|
|
newPwProfile := libregraph.NewPasswordProfile()
|
|
newPwProfile.SetPassword(newPw)
|
|
changes := libregraph.NewUserUpdate()
|
|
changes.SetPasswordProfile(*newPwProfile)
|
|
_, err = g.identityBackend.UpdateUser(ctx, u.Id.OpaqueId, *changes)
|
|
if err != nil {
|
|
errorcode.InvalidRequest.Render(w, r, http.StatusInternalServerError, "password change failed")
|
|
g.logger.Debug().Err(err).Str("userid", u.Id.OpaqueId).Msg("failed to update user password")
|
|
return
|
|
}
|
|
|
|
currentUser := revactx.ContextMustGetUser(r.Context())
|
|
g.publishEvent(
|
|
ctx,
|
|
events.UserFeatureChanged{
|
|
Executant: currentUser.Id,
|
|
UserID: u.Id.OpaqueId,
|
|
Features: []events.UserFeature{
|
|
{Name: "password", Value: "***"},
|
|
},
|
|
},
|
|
)
|
|
|
|
render.Status(r, http.StatusNoContent)
|
|
render.NoContent(w, r)
|
|
}
|