package svc import ( "encoding/json" "errors" "net/http" "net/url" revactx "github.com/cs3org/reva/pkg/ctx" "github.com/go-chi/chi/v5" "github.com/go-chi/render" libregraph "github.com/owncloud/libre-graph-api-go" "github.com/owncloud/ocis/graph/pkg/identity" "github.com/owncloud/ocis/graph/pkg/service/v0/errorcode" ) // GetMe implements the Service interface. func (g Graph) GetMe(w http.ResponseWriter, r *http.Request) { u, ok := revactx.ContextGetUser(r.Context()) if !ok { g.logger.Error().Msg("user not in context") errorcode.ServiceNotAvailable.Render(w, r, http.StatusInternalServerError, "user not in context") return } g.logger.Info().Interface("user", u).Msg("User in /me") me := identity.CreateUserModelFromCS3(u) render.Status(r, http.StatusOK) render.JSON(w, r, me) } // GetUsers implements the Service interface. func (g Graph) GetUsers(w http.ResponseWriter, r *http.Request) { users, err := g.identityBackend.GetUsers(r.Context(), r.URL.Query()) if err != nil { var errcode errorcode.Error if errors.As(err, &errcode) { errcode.Render(w, r) } else { errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error()) } } render.Status(r, http.StatusOK) render.JSON(w, r, &listResponse{Value: users}) } func (g Graph) PostUser(w http.ResponseWriter, r *http.Request) { u := libregraph.NewUser() err := json.NewDecoder(r.Body).Decode(u) if err != nil { errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error()) return } if isNilOrEmpty(u.DisplayName) || isNilOrEmpty(u.OnPremisesSamAccountName) || isNilOrEmpty(u.Mail) { errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "Missing Required Attribute") return } // Disallow user-supplied IDs. It's supposed to be readonly. We're either // generating them in the backend ourselves or rely on the Backend's // storage (e.g. LDAP) to provide a unique ID. if !isNilOrEmpty(u.Id) { errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "user id is a read-only attribute") return } if u, err = g.identityBackend.CreateUser(r.Context(), *u); err != nil { errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error()) return } render.Status(r, http.StatusOK) render.JSON(w, r, u) } // GetUser implements the Service interface. func (g Graph) GetUser(w http.ResponseWriter, r *http.Request) { userID := chi.URLParam(r, "userID") userID, err := url.PathUnescape(userID) if err != nil { errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "unescaping user id failed") } if userID == "" { errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing user id") return } user, err := g.identityBackend.GetUser(r.Context(), userID) if err != nil { var errcode errorcode.Error if errors.As(err, &errcode) { errcode.Render(w, r) } else { errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error()) } } render.Status(r, http.StatusOK) render.JSON(w, r, user) } func (g Graph) DeleteUser(w http.ResponseWriter, r *http.Request) { userID := chi.URLParam(r, "userID") userID, err := url.PathUnescape(userID) if err != nil { errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "unescaping user id failed") } if userID == "" { errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing user id") return } err = g.identityBackend.DeleteUser(r.Context(), userID) if err != nil { var errcode errorcode.Error if errors.As(err, &errcode) { errcode.Render(w, r) } else { errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error()) } } render.Status(r, http.StatusNoContent) render.NoContent(w, r) } // PatchUser implements the Service Interface. Updates the specified attributes of an // ExistingUser func (g Graph) PatchUser(w http.ResponseWriter, r *http.Request) { nameOrID := chi.URLParam(r, "userID") nameOrID, err := url.PathUnescape(nameOrID) if err != nil { errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "unescaping user id failed") } if nameOrID == "" { errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, "missing user id") return } changes := libregraph.NewUser() err = json.NewDecoder(r.Body).Decode(changes) if err != nil { errorcode.InvalidRequest.Render(w, r, http.StatusBadRequest, err.Error()) return } u, err := g.identityBackend.UpdateUser(r.Context(), nameOrID, *changes) if err != nil { var errcode errorcode.Error if errors.As(err, &errcode) { errcode.Render(w, r) } else { errorcode.GeneralException.Render(w, r, http.StatusInternalServerError, err.Error()) } } render.Status(r, http.StatusOK) render.JSON(w, r, u) } func isNilOrEmpty(s *string) bool { return s == nil || *s == "" }