mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-03-12 20:27:12 -04:00
implement more group management endpoints
Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
This commit is contained in:
5
changelog/unreleased/groups-provisioning.md
Normal file
5
changelog/unreleased/groups-provisioning.md
Normal file
@@ -0,0 +1,5 @@
|
||||
Enhancement: Add Group management for OCS Povisioning API
|
||||
|
||||
We added support for the group management related set of API calls of the provisioning API. [Reference](https://doc.owncloud.com/server/admin_manual/configuration/user/user_provisioning_api.html)
|
||||
|
||||
https://github.com/owncloud/ocis-ocs/pull/25
|
||||
@@ -4,7 +4,9 @@ import (
|
||||
"fmt"
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/go-chi/render"
|
||||
merrors "github.com/micro/go-micro/v2/errors"
|
||||
|
||||
accounts "github.com/owncloud/ocis-accounts/pkg/proto/v0"
|
||||
"github.com/owncloud/ocis-ocs/pkg/service/v0/data"
|
||||
@@ -13,17 +15,78 @@ import (
|
||||
|
||||
// ListUserGroups lists a users groups
|
||||
func (o Ocs) ListUserGroups(w http.ResponseWriter, r *http.Request) {
|
||||
render.Render(w, r, response.DataRender(&data.Groups{Groups: []string{}}))
|
||||
userid := chi.URLParam(r, "userid")
|
||||
|
||||
account, err := o.getAccountService().GetAccount(r.Context(), &accounts.GetAccountRequest{Id: userid})
|
||||
|
||||
if err != nil {
|
||||
merr := merrors.FromError(err)
|
||||
if merr.Code == http.StatusNotFound {
|
||||
render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested user could not be found"))
|
||||
} else {
|
||||
render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
|
||||
}
|
||||
o.logger.Error().Err(err).Str("userid", userid).Msg("could not get list of user groups")
|
||||
return
|
||||
}
|
||||
|
||||
groups := []string{}
|
||||
for i := range account.MemberOf {
|
||||
groups = append(groups, account.MemberOf[i].Id)
|
||||
}
|
||||
|
||||
o.logger.Error().Err(err).Int("count", len(groups)).Str("userid", userid).Msg("listing groups for user")
|
||||
render.Render(w, r, response.DataRender(&data.Groups{Groups: groups}))
|
||||
}
|
||||
|
||||
// AddToGroup adds a user to a group
|
||||
func (o Ocs) AddToGroup(w http.ResponseWriter, r *http.Request) {
|
||||
render.Render(w, r, response.ErrRender(data.MetaUnknownError.StatusCode, "not implemented"))
|
||||
userid := chi.URLParam(r, "userid")
|
||||
groupid := r.URL.Query().Get("groupid")
|
||||
|
||||
_, err := o.getGroupsService().AddMember(r.Context(), &accounts.AddMemberRequest{
|
||||
AccountId: userid,
|
||||
GroupId: groupid,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
merr := merrors.FromError(err)
|
||||
if merr.Code == http.StatusNotFound {
|
||||
render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested user could not be found"))
|
||||
} else {
|
||||
render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
|
||||
}
|
||||
o.logger.Error().Err(err).Str("userid", userid).Str("groupid", groupid).Msg("could not add user to group")
|
||||
return
|
||||
}
|
||||
|
||||
o.logger.Debug().Str("userid", userid).Str("groupid", groupid).Msg("added user to group")
|
||||
render.Render(w, r, response.DataRender(struct{}{}))
|
||||
}
|
||||
|
||||
// RemoveFromGroup removes a user from a group
|
||||
func (o Ocs) RemoveFromGroup(w http.ResponseWriter, r *http.Request) {
|
||||
render.Render(w, r, response.ErrRender(data.MetaUnknownError.StatusCode, "not implemented"))
|
||||
userid := chi.URLParam(r, "userid")
|
||||
groupid := r.URL.Query().Get("groupid")
|
||||
|
||||
_, err := o.getGroupsService().RemoveMember(r.Context(), &accounts.RemoveMemberRequest{
|
||||
AccountId: userid,
|
||||
GroupId: groupid,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
merr := merrors.FromError(err)
|
||||
if merr.Code == http.StatusNotFound {
|
||||
render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested user could not be found"))
|
||||
} else {
|
||||
render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
|
||||
}
|
||||
o.logger.Error().Err(err).Str("userid", userid).Str("groupid", groupid).Msg("could not remove user from group")
|
||||
return
|
||||
}
|
||||
|
||||
o.logger.Debug().Str("userid", userid).Str("groupid", groupid).Msg("removed user from group")
|
||||
render.Render(w, r, response.DataRender(struct{}{}))
|
||||
}
|
||||
|
||||
// ListGroups lists all groups
|
||||
@@ -33,15 +96,17 @@ func (o Ocs) ListGroups(w http.ResponseWriter, r *http.Request) {
|
||||
if search != "" {
|
||||
query = fmt.Sprintf("id eq '%s' or on_premises_sam_account_name eq '%s'", escapeValue(search), escapeValue(search))
|
||||
}
|
||||
accSvc := o.getGroupsService()
|
||||
res, err := accSvc.ListGroups(r.Context(), &accounts.ListGroupsRequest{
|
||||
|
||||
res, err := o.getGroupsService().ListGroups(r.Context(), &accounts.ListGroupsRequest{
|
||||
Query: query,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
o.logger.Err(err).Msg("could not list users")
|
||||
render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, "could not list users"))
|
||||
return
|
||||
}
|
||||
|
||||
groups := []string{}
|
||||
for i := range res.Groups {
|
||||
groups = append(groups, res.Groups[i].Id)
|
||||
@@ -57,10 +122,50 @@ func (o Ocs) AddGroup(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// DeleteGroup deletes a group
|
||||
func (o Ocs) DeleteGroup(w http.ResponseWriter, r *http.Request) {
|
||||
render.Render(w, r, response.ErrRender(data.MetaUnknownError.StatusCode, "not implemented"))
|
||||
groupid := chi.URLParam(r, "groupid")
|
||||
|
||||
_, err := o.getGroupsService().DeleteGroup(r.Context(), &accounts.DeleteGroupRequest{
|
||||
Id: groupid,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
merr := merrors.FromError(err)
|
||||
if merr.Code == http.StatusNotFound {
|
||||
render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested group could not be found"))
|
||||
} else {
|
||||
render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
|
||||
}
|
||||
o.logger.Error().Err(err).Str("groupid", groupid).Msg("could not remove group")
|
||||
return
|
||||
}
|
||||
|
||||
o.logger.Debug().Str("groupid", groupid).Msg("removed group")
|
||||
render.Render(w, r, response.DataRender(struct{}{}))
|
||||
}
|
||||
|
||||
// GetGroupMembers lists all members of a group
|
||||
func (o Ocs) GetGroupMembers(w http.ResponseWriter, r *http.Request) {
|
||||
render.Render(w, r, response.ErrRender(data.MetaUnknownError.StatusCode, "not implemented"))
|
||||
|
||||
groupid := chi.URLParam(r, "groupid")
|
||||
|
||||
res, err := o.getGroupsService().ListMembers(r.Context(), &accounts.ListMembersRequest{Id: groupid})
|
||||
|
||||
if err != nil {
|
||||
merr := merrors.FromError(err)
|
||||
if merr.Code == http.StatusNotFound {
|
||||
render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested group could not be found"))
|
||||
} else {
|
||||
render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
|
||||
}
|
||||
o.logger.Error().Err(err).Str("groupid", groupid).Msg("could not get list of members")
|
||||
return
|
||||
}
|
||||
|
||||
members := []string{}
|
||||
for i := range res.Members {
|
||||
members = append(members, res.Members[i].Id)
|
||||
}
|
||||
|
||||
o.logger.Error().Err(err).Int("count", len(members)).Str("groupid", groupid).Msg("listing group members")
|
||||
render.Render(w, r, response.DataRender(&data.Users{Users: members}))
|
||||
}
|
||||
|
||||
@@ -22,7 +22,7 @@ import (
|
||||
|
||||
// GetUser returns the currently logged in user
|
||||
func (o Ocs) GetUser(w http.ResponseWriter, r *http.Request) {
|
||||
// TODO this endpoint needs authentication
|
||||
// TODO this endpoint needs authentication using the roles and permissions
|
||||
userid := chi.URLParam(r, "userid")
|
||||
|
||||
if userid == "" {
|
||||
@@ -35,8 +35,7 @@ func (o Ocs) GetUser(w http.ResponseWriter, r *http.Request) {
|
||||
userid = u.Id.OpaqueId
|
||||
}
|
||||
|
||||
accSvc := o.getAccountService()
|
||||
account, err := accSvc.GetAccount(r.Context(), &accounts.GetAccountRequest{
|
||||
account, err := o.getAccountService().GetAccount(r.Context(), &accounts.GetAccountRequest{
|
||||
Id: userid,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -67,15 +66,26 @@ func (o Ocs) GetUser(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// AddUser creates a new user account
|
||||
func (o Ocs) AddUser(w http.ResponseWriter, r *http.Request) {
|
||||
// TODO this endpoint needs authentication
|
||||
// TODO this endpoint needs authentication using the roles and permissions
|
||||
userid := r.PostFormValue("userid")
|
||||
password := r.PostFormValue("password")
|
||||
username := r.PostFormValue("username")
|
||||
displayname := r.PostFormValue("displayname")
|
||||
email := r.PostFormValue("email")
|
||||
|
||||
accSvc := o.getAccountService()
|
||||
account, err := accSvc.CreateAccount(r.Context(), &accounts.CreateAccountRequest{
|
||||
// fallbacks
|
||||
/* TODO decide if we want to make these fallbacks. Keep in mind:
|
||||
- ocis requires a username and email
|
||||
- the username should really be different from the userid
|
||||
if username == "" {
|
||||
username = userid
|
||||
}
|
||||
if displayname == "" {
|
||||
displayname = username
|
||||
}
|
||||
*/
|
||||
|
||||
account, err := o.getAccountService().CreateAccount(r.Context(), &accounts.CreateAccountRequest{
|
||||
Account: &accounts.Account{
|
||||
DisplayName: displayname,
|
||||
PreferredName: username,
|
||||
@@ -148,8 +158,7 @@ func (o Ocs) EditUser(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
accSvc := o.getAccountService()
|
||||
account, err := accSvc.UpdateAccount(r.Context(), &req)
|
||||
account, err := o.getAccountService().UpdateAccount(r.Context(), &req)
|
||||
if err != nil {
|
||||
merr := merrors.FromError(err)
|
||||
switch merr.Code {
|
||||
@@ -168,6 +177,7 @@ func (o Ocs) EditUser(w http.ResponseWriter, r *http.Request) {
|
||||
if account.PasswordProfile != nil {
|
||||
account.PasswordProfile.Password = ""
|
||||
}
|
||||
|
||||
o.logger.Debug().Interface("account", account).Msg("updated user")
|
||||
render.Render(w, r, response.DataRender(struct{}{}))
|
||||
}
|
||||
@@ -177,8 +187,8 @@ func (o Ocs) DeleteUser(w http.ResponseWriter, r *http.Request) {
|
||||
req := accounts.DeleteAccountRequest{
|
||||
Id: chi.URLParam(r, "userid"),
|
||||
}
|
||||
accSvc := o.getAccountService()
|
||||
_, err := accSvc.DeleteAccount(r.Context(), &req)
|
||||
|
||||
_, err := o.getAccountService().DeleteAccount(r.Context(), &req)
|
||||
if err != nil {
|
||||
merr := merrors.FromError(err)
|
||||
if merr.Code == http.StatusNotFound {
|
||||
@@ -189,6 +199,7 @@ func (o Ocs) DeleteUser(w http.ResponseWriter, r *http.Request) {
|
||||
o.logger.Error().Err(err).Str("userid", req.Id).Msg("could not delete user")
|
||||
return
|
||||
}
|
||||
|
||||
o.logger.Debug().Str("userid", req.Id).Msg("deleted user")
|
||||
render.Render(w, r, response.DataRender(struct{}{}))
|
||||
}
|
||||
@@ -203,6 +214,7 @@ func (o Ocs) GetSigningKey(w http.ResponseWriter, r *http.Request) {
|
||||
render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "missing user in context"))
|
||||
return
|
||||
}
|
||||
|
||||
c := storepb.NewStoreService("com.owncloud.api.store", grpc.NewClient())
|
||||
res, err := c.Read(r.Context(), &storepb.ReadRequest{
|
||||
Options: &storepb.ReadOptions{
|
||||
@@ -251,6 +263,7 @@ func (o Ocs) GetSigningKey(w http.ResponseWriter, r *http.Request) {
|
||||
// TODO Expiry?
|
||||
},
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
//o.logger.Error().Err(err).Msg("error writing key")
|
||||
render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, "could not persist signing key"))
|
||||
@@ -270,8 +283,8 @@ func (o Ocs) ListUsers(w http.ResponseWriter, r *http.Request) {
|
||||
if search != "" {
|
||||
query = fmt.Sprintf("id eq '%s' or on_premises_sam_account_name eq '%s'", escapeValue(search), escapeValue(search))
|
||||
}
|
||||
accSvc := o.getAccountService()
|
||||
res, err := accSvc.ListAccounts(r.Context(), &accounts.ListAccountsRequest{
|
||||
|
||||
res, err := o.getAccountService().ListAccounts(r.Context(), &accounts.ListAccountsRequest{
|
||||
Query: query,
|
||||
})
|
||||
if err != nil {
|
||||
@@ -279,6 +292,7 @@ func (o Ocs) ListUsers(w http.ResponseWriter, r *http.Request) {
|
||||
render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, "could not list users"))
|
||||
return
|
||||
}
|
||||
|
||||
users := []string{}
|
||||
for i := range res.Accounts {
|
||||
users = append(users, res.Accounts[i].Id)
|
||||
|
||||
Reference in New Issue
Block a user