Merge pull request #627 from butonic/add-basic-auth-option
add enable basic auth option and check permissions
This commit is contained in:
@@ -1,40 +0,0 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/cs3org/reva/pkg/token/manager/jwt"
|
||||
"github.com/cs3org/reva/pkg/user"
|
||||
)
|
||||
|
||||
// AccessToken middleware is used to set the user from an x-access-token to the context
|
||||
func AccessToken(opts ...Option) func(next http.Handler) http.Handler {
|
||||
opt := newOptions(opts...)
|
||||
|
||||
return func(next http.Handler) http.Handler {
|
||||
// TODO: handle error
|
||||
tokenManager, err := jwt.New(map[string]interface{}{
|
||||
"secret": opt.TokenManagerConfig.JWTSecret,
|
||||
"expires": int64(60),
|
||||
})
|
||||
if err != nil {
|
||||
opt.Logger.Fatal().Err(err).Msgf("Could not initialize token-manager")
|
||||
}
|
||||
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
token := r.Header.Get("x-access-token")
|
||||
if token != "" {
|
||||
u, err := tokenManager.DismantleToken(r.Context(), token)
|
||||
if err != nil {
|
||||
opt.Logger.Error().Err(err).Msg("could not dismantle token")
|
||||
w.WriteHeader(http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
// store user in context for request
|
||||
r = r.WithContext(user.ContextSetUser(r.Context(), u))
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, r)
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -1,8 +1,8 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"github.com/owncloud/ocis/ocs/pkg/config"
|
||||
"github.com/owncloud/ocis/ocis-pkg/log"
|
||||
"github.com/owncloud/ocis/ocis-pkg/roles"
|
||||
)
|
||||
|
||||
// Option defines a single option function.
|
||||
@@ -12,8 +12,8 @@ type Option func(o *Options)
|
||||
type Options struct {
|
||||
// Logger to use for logging, must be set
|
||||
Logger log.Logger
|
||||
// TokenManagerConfig for communicating with the reva token manager
|
||||
TokenManagerConfig config.TokenManager
|
||||
// RoleManager for looking up permissions
|
||||
RoleManager *roles.Manager
|
||||
}
|
||||
|
||||
// newOptions initializes the available default options.
|
||||
@@ -34,9 +34,9 @@ func Logger(l log.Logger) Option {
|
||||
}
|
||||
}
|
||||
|
||||
// TokenManagerConfig provides a function to set the token manger config option.
|
||||
func TokenManagerConfig(cfg config.TokenManager) Option {
|
||||
// RoleManager provides a function to set the RoleManager option.
|
||||
func RoleManager(val *roles.Manager) Option {
|
||||
return func(o *Options) {
|
||||
o.TokenManagerConfig = cfg
|
||||
o.RoleManager = val
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,37 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/go-chi/render"
|
||||
accounts "github.com/owncloud/ocis/accounts/pkg/service/v0"
|
||||
"github.com/owncloud/ocis/ocis-pkg/roles"
|
||||
"github.com/owncloud/ocis/ocs/pkg/service/v0/data"
|
||||
"github.com/owncloud/ocis/ocs/pkg/service/v0/response"
|
||||
)
|
||||
|
||||
// RequireAdmin middleware is used to require the user in context to be an admin / have account management permissions
|
||||
func RequireAdmin(opts ...Option) func(next http.Handler) http.Handler {
|
||||
opt := newOptions(opts...)
|
||||
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// get roles from context
|
||||
roleIDs, ok := roles.ReadRoleIDsFromContext(r.Context())
|
||||
if !ok {
|
||||
render.Render(w, r, response.ErrRender(data.MetaUnauthorized.StatusCode, "Unauthorized"))
|
||||
return
|
||||
}
|
||||
|
||||
// check if permission is present in roles of the authenticated account
|
||||
if opt.RoleManager.FindPermissionByID(r.Context(), roleIDs, accounts.AccountManagementPermissionID) != nil {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
render.Render(w, r, response.ErrRender(data.MetaUnauthorized.StatusCode, "Unauthorized"))
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/cs3org/reva/pkg/user"
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/go-chi/render"
|
||||
accounts "github.com/owncloud/ocis/accounts/pkg/service/v0"
|
||||
"github.com/owncloud/ocis/ocis-pkg/roles"
|
||||
"github.com/owncloud/ocis/ocs/pkg/service/v0/data"
|
||||
"github.com/owncloud/ocis/ocs/pkg/service/v0/response"
|
||||
)
|
||||
|
||||
// RequireSelfOrAdmin middleware is used to require the requesting user to be an admin or the requested user himself
|
||||
func RequireSelfOrAdmin(opts ...Option) func(next http.Handler) http.Handler {
|
||||
opt := newOptions(opts...)
|
||||
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
u, ok := user.ContextGetUser(r.Context())
|
||||
if !ok {
|
||||
render.Render(w, r, response.ErrRender(data.MetaUnauthorized.StatusCode, "Unauthorized"))
|
||||
return
|
||||
}
|
||||
if u.Id == nil || u.Id.OpaqueId == "" {
|
||||
render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "user is missing an id"))
|
||||
return
|
||||
}
|
||||
// get roles from context
|
||||
roleIDs, ok := roles.ReadRoleIDsFromContext(r.Context())
|
||||
if !ok {
|
||||
render.Render(w, r, response.ErrRender(data.MetaUnauthorized.StatusCode, "Unauthorized"))
|
||||
return
|
||||
}
|
||||
|
||||
// check if account management permission is present in roles of the authenticated account
|
||||
if opt.RoleManager.FindPermissionByID(r.Context(), roleIDs, accounts.AccountManagementPermissionID) != nil {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
|
||||
// check if self management permission is present in roles of the authenticated account
|
||||
if opt.RoleManager.FindPermissionByID(r.Context(), roleIDs, accounts.SelfManagementPermissionID) != nil {
|
||||
userid := chi.URLParam(r, "userid")
|
||||
if userid == "" || userid == u.Id.OpaqueId || userid == u.Username {
|
||||
next.ServeHTTP(w, r)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
render.Render(w, r, response.ErrRender(data.MetaUnauthorized.StatusCode, "Unauthorized"))
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
package middleware
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/cs3org/reva/pkg/user"
|
||||
"github.com/go-chi/render"
|
||||
"github.com/owncloud/ocis/ocs/pkg/service/v0/data"
|
||||
"github.com/owncloud/ocis/ocs/pkg/service/v0/response"
|
||||
)
|
||||
|
||||
// RequireUser middleware is used to require a user in context
|
||||
func RequireUser() func(next http.Handler) http.Handler {
|
||||
|
||||
return func(next http.Handler) http.Handler {
|
||||
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
u, ok := user.ContextGetUser(r.Context())
|
||||
if !ok {
|
||||
render.Render(w, r, response.ErrRender(data.MetaUnauthorized.StatusCode, "Unauthorized"))
|
||||
return
|
||||
}
|
||||
if u.Id == nil || u.Id.OpaqueId == "" {
|
||||
render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "user is missing an id"))
|
||||
return
|
||||
}
|
||||
|
||||
next.ServeHTTP(w, r)
|
||||
|
||||
})
|
||||
}
|
||||
}
|
||||
+409
-342
File diff suppressed because it is too large
Load Diff
@@ -18,6 +18,9 @@ var MetaFailure = Meta{Status: "", StatusCode: 101, Message: "Failure"}
|
||||
// MetaInvalidInput is an error response with code 102
|
||||
var MetaInvalidInput = Meta{Status: "", StatusCode: 102, Message: "Invalid Input"}
|
||||
|
||||
// MetaForbidden is an error response with code 104
|
||||
var MetaForbidden = Meta{Status: "", StatusCode: 104, Message: "Forbidden"}
|
||||
|
||||
// MetaBadRequest is used for unknown errors
|
||||
var MetaBadRequest = Meta{Status: "error", StatusCode: 400, Message: "Bad Request"}
|
||||
|
||||
|
||||
+179
-19
@@ -1,9 +1,13 @@
|
||||
package svc
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"regexp"
|
||||
"strconv"
|
||||
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/go-chi/render"
|
||||
@@ -41,10 +45,28 @@ func (o Ocs) ListUserGroups(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
groups := []string{}
|
||||
for i := range account.MemberOf {
|
||||
groups = append(groups, account.MemberOf[i].Id)
|
||||
if account.MemberOf[i].OnPremisesSamAccountName == "" {
|
||||
o.logger.Warn().Str("groupid", account.MemberOf[i].Id).Msg("group on_premises_sam_account_name is empty, trying to lookup by id")
|
||||
// we can try to look up the name
|
||||
group, err := o.getGroupsService().GetGroup(r.Context(), &accounts.GetGroupRequest{
|
||||
Id: account.MemberOf[i].Id,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
o.logger.Error().Err(err).Str("groupid", account.MemberOf[i].Id).Msg("could not get group")
|
||||
continue
|
||||
}
|
||||
if group.OnPremisesSamAccountName == "" {
|
||||
o.logger.Error().Err(err).Str("groupid", account.MemberOf[i].Id).Msg("group on_premises_sam_account_name is empty")
|
||||
continue
|
||||
}
|
||||
groups = append(groups, group.OnPremisesSamAccountName)
|
||||
} else {
|
||||
groups = append(groups, account.MemberOf[i].OnPremisesSamAccountName)
|
||||
}
|
||||
}
|
||||
|
||||
o.logger.Error().Err(err).Int("count", len(groups)).Str("userid", userid).Msg("listing groups for user")
|
||||
o.logger.Error().Err(err).Int("count", len(groups)).Str("userid", account.Id).Msg("listing groups for user")
|
||||
render.Render(w, r, response.DataRender(&data.Groups{Groups: groups}))
|
||||
}
|
||||
|
||||
@@ -69,9 +91,21 @@ func (o Ocs) AddToGroup(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
// ocs only knows about names so we have to look up the internal id
|
||||
group, err := o.fetchGroupByName(r.Context(), 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()))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
_, err = o.getGroupsService().AddMember(r.Context(), &accounts.AddMemberRequest{
|
||||
AccountId: account.Id,
|
||||
GroupId: groupid,
|
||||
GroupId: group.Id,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
@@ -81,21 +115,46 @@ func (o Ocs) AddToGroup(w http.ResponseWriter, r *http.Request) {
|
||||
} 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")
|
||||
o.logger.Error().Err(err).Str("userid", account.Id).Str("groupid", group.Id).Msg("could not add user to group")
|
||||
return
|
||||
}
|
||||
|
||||
o.logger.Debug().Str("userid", userid).Str("groupid", groupid).Msg("added user to group")
|
||||
o.logger.Debug().Str("userid", account.Id).Str("groupid", group.Id).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) {
|
||||
userid := chi.URLParam(r, "userid")
|
||||
groupid := r.URL.Query().Get("groupid")
|
||||
|
||||
var err error
|
||||
|
||||
// Really? a DELETE with form encoded body?!?
|
||||
// but it is not encoded as mime, so we cannot just call r.ParseForm()
|
||||
// read it manually
|
||||
body, err := ioutil.ReadAll(r.Body)
|
||||
if err != nil {
|
||||
render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, err.Error()))
|
||||
return
|
||||
}
|
||||
if err = r.Body.Close(); err != nil {
|
||||
render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
values, err := url.ParseQuery(string(body))
|
||||
if err != nil {
|
||||
render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
groupid := values.Get("groupid")
|
||||
if groupid == "" {
|
||||
render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, err.Error()))
|
||||
return
|
||||
}
|
||||
|
||||
var account *accounts.Account
|
||||
var err error
|
||||
|
||||
if isValidUUID(userid) {
|
||||
account, _ = o.getAccountService().GetAccount(r.Context(), &accounts.GetAccountRequest{
|
||||
@@ -116,9 +175,21 @@ func (o Ocs) RemoveFromGroup(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
}
|
||||
|
||||
// ocs only knows about names so we have to look up the internal id
|
||||
group, err := o.fetchGroupByName(r.Context(), 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()))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
_, err = o.getGroupsService().RemoveMember(r.Context(), &accounts.RemoveMemberRequest{
|
||||
AccountId: account.Id,
|
||||
GroupId: groupid,
|
||||
GroupId: group.Id,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
@@ -128,11 +199,11 @@ func (o Ocs) RemoveFromGroup(w http.ResponseWriter, r *http.Request) {
|
||||
} 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")
|
||||
o.logger.Error().Err(err).Str("userid", account.Id).Str("groupid", group.Id).Msg("could not remove user from group")
|
||||
return
|
||||
}
|
||||
|
||||
o.logger.Debug().Str("userid", userid).Str("groupid", groupid).Msg("removed user from group")
|
||||
o.logger.Debug().Str("userid", account.Id).Str("groupid", group.Id).Msg("removed user from group")
|
||||
render.Render(w, r, response.DataRender(struct{}{}))
|
||||
}
|
||||
|
||||
@@ -156,7 +227,7 @@ func (o Ocs) ListGroups(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
groups := []string{}
|
||||
for i := range res.Groups {
|
||||
groups = append(groups, res.Groups[i].Id)
|
||||
groups = append(groups, res.Groups[i].OnPremisesSamAccountName)
|
||||
}
|
||||
|
||||
render.Render(w, r, response.DataRender(&data.Groups{Groups: groups}))
|
||||
@@ -164,15 +235,78 @@ func (o Ocs) ListGroups(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// AddGroup adds a group
|
||||
func (o Ocs) AddGroup(w http.ResponseWriter, r *http.Request) {
|
||||
render.Render(w, r, response.ErrRender(data.MetaUnknownError.StatusCode, "not implemented"))
|
||||
groupid := r.PostFormValue("groupid")
|
||||
displayname := r.PostFormValue("displayname")
|
||||
gid := r.PostFormValue("gidnumber")
|
||||
|
||||
var gidNumber int64
|
||||
var err error
|
||||
|
||||
if gid != "" {
|
||||
gidNumber, err = strconv.ParseInt(gid, 10, 64)
|
||||
if err != nil {
|
||||
render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "Cannot use the gidnumber provided"))
|
||||
o.logger.Error().Err(err).Str("gid", gid).Str("groupid", groupid).Msg("Cannot use the gidnumber provided")
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
if displayname == "" {
|
||||
displayname = groupid
|
||||
}
|
||||
|
||||
newGroup := &accounts.Group{
|
||||
Id: groupid,
|
||||
DisplayName: displayname,
|
||||
OnPremisesSamAccountName: groupid,
|
||||
GidNumber: gidNumber,
|
||||
}
|
||||
group, err := o.getGroupsService().CreateGroup(r.Context(), &accounts.CreateGroupRequest{
|
||||
Group: newGroup,
|
||||
})
|
||||
if err != nil {
|
||||
merr := merrors.FromError(err)
|
||||
switch merr.Code {
|
||||
case http.StatusBadRequest:
|
||||
render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, merr.Detail))
|
||||
case http.StatusConflict:
|
||||
if response.APIVersion(r.Context()) == "2" {
|
||||
// it seems the application framework sets the ocs status code to the httpstatus code, which affects the provisioning api
|
||||
// see https://github.com/owncloud/core/blob/b9ff4c93e051c94adfb301545098ae627e52ef76/lib/public/AppFramework/OCSController.php#L142-L150
|
||||
render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, merr.Detail))
|
||||
} else {
|
||||
render.Render(w, r, response.ErrRender(data.MetaInvalidInput.StatusCode, merr.Detail))
|
||||
}
|
||||
default:
|
||||
render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
|
||||
}
|
||||
o.logger.Error().Err(err).Str("groupid", groupid).Msg("could not add group")
|
||||
// TODO check error if group already existed
|
||||
return
|
||||
}
|
||||
o.logger.Debug().Interface("group", group).Msg("added group")
|
||||
|
||||
render.Render(w, r, response.DataRender(struct{}{}))
|
||||
}
|
||||
|
||||
// DeleteGroup deletes a group
|
||||
func (o Ocs) DeleteGroup(w http.ResponseWriter, r *http.Request) {
|
||||
groupid := chi.URLParam(r, "groupid")
|
||||
|
||||
_, err := o.getGroupsService().DeleteGroup(r.Context(), &accounts.DeleteGroupRequest{
|
||||
Id: groupid,
|
||||
// ocs only knows about names so we have to look up the internal id
|
||||
group, err := o.fetchGroupByName(r.Context(), 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()))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
_, err = o.getGroupsService().DeleteGroup(r.Context(), &accounts.DeleteGroupRequest{
|
||||
Id: group.Id,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
@@ -182,11 +316,11 @@ func (o Ocs) DeleteGroup(w http.ResponseWriter, r *http.Request) {
|
||||
} 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")
|
||||
o.logger.Error().Err(err).Str("groupid", group.Id).Msg("could not remove group")
|
||||
return
|
||||
}
|
||||
|
||||
o.logger.Debug().Str("groupid", groupid).Msg("removed group")
|
||||
o.logger.Debug().Str("groupid", group.Id).Msg("removed group")
|
||||
render.Render(w, r, response.DataRender(struct{}{}))
|
||||
}
|
||||
|
||||
@@ -195,7 +329,19 @@ func (o Ocs) GetGroupMembers(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
groupid := chi.URLParam(r, "groupid")
|
||||
|
||||
res, err := o.getGroupsService().ListMembers(r.Context(), &accounts.ListMembersRequest{Id: groupid})
|
||||
// ocs only knows about names so we have to look up the internal id
|
||||
group, err := o.fetchGroupByName(r.Context(), 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()))
|
||||
}
|
||||
return
|
||||
}
|
||||
|
||||
res, err := o.getGroupsService().ListMembers(r.Context(), &accounts.ListMembersRequest{Id: group.Id})
|
||||
|
||||
if err != nil {
|
||||
merr := merrors.FromError(err)
|
||||
@@ -204,13 +350,13 @@ func (o Ocs) GetGroupMembers(w http.ResponseWriter, r *http.Request) {
|
||||
} 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")
|
||||
o.logger.Error().Err(err).Str("groupid", group.Id).Msg("could not get list of members")
|
||||
return
|
||||
}
|
||||
|
||||
members := []string{}
|
||||
for i := range res.Members {
|
||||
members = append(members, res.Members[i].Id)
|
||||
members = append(members, res.Members[i].OnPremisesSamAccountName)
|
||||
}
|
||||
|
||||
o.logger.Error().Err(err).Int("count", len(members)).Str("groupid", groupid).Msg("listing group members")
|
||||
@@ -221,3 +367,17 @@ func isValidUUID(uuid string) bool {
|
||||
r := regexp.MustCompile("^[a-fA-F0-9]{8}-[a-fA-F0-9]{4}-4[a-fA-F0-9]{3}-[8|9|aA|bB][a-fA-F0-9]{3}-[a-fA-F0-9]{12}$")
|
||||
return r.MatchString(uuid)
|
||||
}
|
||||
|
||||
func (o Ocs) fetchGroupByName(ctx context.Context, name string) (*accounts.Group, error) {
|
||||
var res *accounts.ListGroupsResponse
|
||||
res, err := o.getGroupsService().ListGroups(ctx, &accounts.ListGroupsRequest{
|
||||
Query: fmt.Sprintf("on_premises_sam_account_name eq '%v'", escapeValue(name)),
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if res != nil && len(res.Groups) == 1 {
|
||||
return res.Groups[0], nil
|
||||
}
|
||||
return nil, merrors.NotFound("", "The requested group could not be found")
|
||||
}
|
||||
|
||||
@@ -3,8 +3,10 @@ package svc
|
||||
import (
|
||||
"net/http"
|
||||
|
||||
"github.com/owncloud/ocis/ocs/pkg/config"
|
||||
"github.com/owncloud/ocis/ocis-pkg/log"
|
||||
"github.com/owncloud/ocis/ocis-pkg/roles"
|
||||
"github.com/owncloud/ocis/ocs/pkg/config"
|
||||
settings "github.com/owncloud/ocis/settings/pkg/proto/v0"
|
||||
)
|
||||
|
||||
// Option defines a single option function.
|
||||
@@ -12,9 +14,11 @@ type Option func(o *Options)
|
||||
|
||||
// Options defines the available options for this package.
|
||||
type Options struct {
|
||||
Logger log.Logger
|
||||
Config *config.Config
|
||||
Middleware []func(http.Handler) http.Handler
|
||||
Logger log.Logger
|
||||
Config *config.Config
|
||||
Middleware []func(http.Handler) http.Handler
|
||||
RoleService settings.RoleService
|
||||
RoleManager *roles.Manager
|
||||
}
|
||||
|
||||
// newOptions initializes the available default options.
|
||||
@@ -48,3 +52,17 @@ func Middleware(val ...func(http.Handler) http.Handler) Option {
|
||||
o.Middleware = val
|
||||
}
|
||||
}
|
||||
|
||||
// RoleService provides a function to set the RoleService option.
|
||||
func RoleService(val settings.RoleService) Option {
|
||||
return func(o *Options) {
|
||||
o.RoleService = val
|
||||
}
|
||||
}
|
||||
|
||||
// RoleManager provides a function to set the RoleManager option.
|
||||
func RoleManager(val *roles.Manager) Option {
|
||||
return func(o *Options) {
|
||||
o.RoleManager = val
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,10 +32,17 @@ func APIVersion(ctx context.Context) string {
|
||||
|
||||
// OcsV1StatusCodes returns the http status codes for the OCS API v1.
|
||||
func OcsV1StatusCodes(meta data.Meta) int {
|
||||
if meta.StatusCode == data.MetaUnauthorized.StatusCode {
|
||||
return http.StatusUnauthorized
|
||||
}
|
||||
return http.StatusOK
|
||||
}
|
||||
|
||||
// OcsV2StatusCodes maps the OCS codes to http status codes for the ocs API v2.
|
||||
// see https://github.com/owncloud/core/blob/c08baf580927ecb8ec179028dda255fdd85b4568/lib/private/legacy/api.php#L528
|
||||
// also HTTP status codes for apps are the same as OCS codes
|
||||
// see https://github.com/owncloud/core/blob/b9ff4c93e051c94adfb301545098ae627e52ef76/lib/public/AppFramework/OCSController.php#L142-L150
|
||||
// I think this is a bug in the ocs v2 api, but since we are going to mimic bugs in ocis ... here goes
|
||||
func OcsV2StatusCodes(meta data.Meta) int {
|
||||
sc := meta.StatusCode
|
||||
switch sc {
|
||||
@@ -47,7 +54,8 @@ func OcsV2StatusCodes(meta data.Meta) int {
|
||||
return http.StatusInternalServerError
|
||||
case data.MetaUnauthorized.StatusCode:
|
||||
return http.StatusUnauthorized
|
||||
case 100:
|
||||
case data.MetaOK.StatusCode:
|
||||
// TODO mustn't data.Meta be a pointer so this assignment has an effect
|
||||
meta.StatusCode = http.StatusOK
|
||||
return http.StatusOK
|
||||
}
|
||||
@@ -61,7 +69,7 @@ func OcsV2StatusCodes(meta data.Meta) int {
|
||||
return http.StatusBadRequest
|
||||
}
|
||||
|
||||
// TODO change this status code?
|
||||
// TODO change this status code? yes, align with oc10 core mapStatusCodes
|
||||
return http.StatusOK
|
||||
}
|
||||
|
||||
|
||||
@@ -2,18 +2,24 @@ package svc
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"time"
|
||||
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/go-chi/chi/middleware"
|
||||
"github.com/go-chi/render"
|
||||
"github.com/micro/go-micro/v2/client/grpc"
|
||||
|
||||
mclient "github.com/micro/go-micro/v2/client"
|
||||
accounts "github.com/owncloud/ocis/accounts/pkg/proto/v0"
|
||||
"github.com/owncloud/ocis/ocis-pkg/account"
|
||||
"github.com/owncloud/ocis/ocis-pkg/log"
|
||||
opkgm "github.com/owncloud/ocis/ocis-pkg/middleware"
|
||||
"github.com/owncloud/ocis/ocis-pkg/roles"
|
||||
"github.com/owncloud/ocis/ocs/pkg/config"
|
||||
ocsm "github.com/owncloud/ocis/ocs/pkg/middleware"
|
||||
"github.com/owncloud/ocis/ocs/pkg/service/v0/data"
|
||||
"github.com/owncloud/ocis/ocs/pkg/service/v0/response"
|
||||
"github.com/owncloud/ocis/ocis-pkg/log"
|
||||
settings "github.com/owncloud/ocis/settings/pkg/proto/v0"
|
||||
)
|
||||
|
||||
var defaultClient = grpc.NewClient()
|
||||
@@ -31,19 +37,47 @@ func NewService(opts ...Option) Service {
|
||||
m := chi.NewMux()
|
||||
m.Use(options.Middleware...)
|
||||
|
||||
svc := Ocs{
|
||||
config: options.Config,
|
||||
mux: m,
|
||||
logger: options.Logger,
|
||||
roleService := options.RoleService
|
||||
if roleService == nil {
|
||||
// https://github.com/owncloud/ocis-proxy/issues/38
|
||||
// TODO this won't work with a registry other than mdns. Look into Micro's client initialization.
|
||||
roleService = settings.NewRoleService("com.owncloud.api.settings", mclient.DefaultClient)
|
||||
}
|
||||
roleManager := options.RoleManager
|
||||
if roleManager == nil {
|
||||
m := roles.NewManager(
|
||||
roles.CacheSize(1024),
|
||||
roles.CacheTTL(time.Hour*24*7),
|
||||
roles.Logger(options.Logger),
|
||||
roles.RoleService(roleService),
|
||||
)
|
||||
roleManager = &m
|
||||
}
|
||||
|
||||
svc := Ocs{
|
||||
config: options.Config,
|
||||
mux: m,
|
||||
RoleManager: roleManager,
|
||||
logger: options.Logger,
|
||||
}
|
||||
|
||||
requireUser := ocsm.RequireUser()
|
||||
|
||||
requireAdmin := ocsm.RequireAdmin(
|
||||
ocsm.RoleManager(roleManager),
|
||||
)
|
||||
|
||||
requireSelfOrAdmin := ocsm.RequireSelfOrAdmin(
|
||||
ocsm.RoleManager(roleManager),
|
||||
ocsm.Logger(options.Logger),
|
||||
)
|
||||
m.Route(options.Config.HTTP.Root, func(r chi.Router) {
|
||||
r.NotFound(svc.NotFound)
|
||||
r.Use(middleware.StripSlashes)
|
||||
r.Use(ocsm.AccessToken(
|
||||
ocsm.Logger(options.Logger),
|
||||
ocsm.TokenManagerConfig(options.Config.TokenManager),
|
||||
))
|
||||
r.Use(opkgm.ExtractAccountUUID(
|
||||
account.Logger(options.Logger),
|
||||
account.JWTSecret(options.Config.TokenManager.JWTSecret)),
|
||||
)
|
||||
r.Use(ocsm.OCSFormatCtx) // updates request Accept header according to format=(json|xml) query parameter
|
||||
r.Route("/v{version:(1|2)}.php", func(r chi.Router) {
|
||||
r.Use(response.VersionCtx) // stores version in context
|
||||
@@ -51,32 +85,48 @@ func NewService(opts ...Option) Service {
|
||||
r.Route("/apps/notifications/api/v1", func(r chi.Router) {})
|
||||
r.Route("/cloud", func(r chi.Router) {
|
||||
r.Route("/capabilities", func(r chi.Router) {})
|
||||
// TODO /apps
|
||||
r.Route("/user", func(r chi.Router) {
|
||||
r.Get("/", svc.GetUser)
|
||||
r.With(requireSelfOrAdmin).Get("/", svc.GetSelf)
|
||||
r.Get("/signing-key", svc.GetSigningKey)
|
||||
})
|
||||
|
||||
// for /users endpoints see https://github.com/owncloud/core/blob/master/apps/provisioning_api/appinfo/routes.php#L44-L56
|
||||
r.Route("/users", func(r chi.Router) {
|
||||
r.Get("/", svc.ListUsers)
|
||||
r.Post("/", svc.AddUser)
|
||||
r.Get("/{userid}", svc.GetUser)
|
||||
r.Put("/{userid}", svc.EditUser)
|
||||
r.Delete("/{userid}", svc.DeleteUser)
|
||||
r.With(requireAdmin).Get("/", svc.ListUsers)
|
||||
r.With(requireAdmin).Post("/", svc.AddUser)
|
||||
r.Route("/{userid}", func(r chi.Router) {
|
||||
r.With(requireUser).Get("/", svc.GetUser)
|
||||
r.With(requireSelfOrAdmin).Put("/", svc.EditUser)
|
||||
r.With(requireAdmin).Delete("/", svc.DeleteUser)
|
||||
r.With(requireAdmin).Put("/enable", svc.EnableUser)
|
||||
r.With(requireAdmin).Put("/disable", svc.DisableUser)
|
||||
})
|
||||
|
||||
r.Route("/{userid}/groups", func(r chi.Router) {
|
||||
r.Get("/", svc.ListUserGroups)
|
||||
r.Post("/", svc.AddToGroup)
|
||||
r.Delete("/", svc.RemoveFromGroup)
|
||||
r.With(requireSelfOrAdmin).Get("/", svc.ListUserGroups)
|
||||
r.With(requireAdmin).Post("/", svc.AddToGroup)
|
||||
r.With(requireAdmin).Delete("/", svc.RemoveFromGroup)
|
||||
})
|
||||
|
||||
r.Route("/{userid}/subadmins", func(r chi.Router) {
|
||||
r.With(requireAdmin).Post("/", svc.NotImplementedStub)
|
||||
r.With(requireSelfOrAdmin).Get("/", svc.NotImplementedStub)
|
||||
r.With(requireAdmin).Delete("/", svc.NotImplementedStub)
|
||||
})
|
||||
})
|
||||
|
||||
// for /groups endpoints see https://github.com/owncloud/core/blob/master/apps/provisioning_api/appinfo/routes.php#L65-L69
|
||||
r.Route("/groups", func(r chi.Router) {
|
||||
r.Get("/", svc.ListGroups)
|
||||
r.Post("/", svc.AddGroup)
|
||||
r.Delete("/{groupid}", svc.DeleteGroup)
|
||||
r.Get("/{groupid}", svc.GetGroupMembers)
|
||||
r.With(requireAdmin).Get("/", svc.ListGroups)
|
||||
r.With(requireAdmin).Post("/", svc.AddGroup)
|
||||
r.With(requireSelfOrAdmin).Get("/{groupid}", svc.GetGroupMembers)
|
||||
r.With(requireAdmin).Delete("/{groupid}", svc.DeleteGroup)
|
||||
r.With(requireAdmin).Get("/{groupid}/subadmins", svc.NotImplementedStub)
|
||||
})
|
||||
})
|
||||
r.Route("/config", func(r chi.Router) {
|
||||
r.Get("/", svc.GetConfig)
|
||||
r.With(requireUser).Get("/", svc.GetConfig)
|
||||
})
|
||||
})
|
||||
})
|
||||
@@ -86,9 +136,11 @@ func NewService(opts ...Option) Service {
|
||||
|
||||
// Ocs defines implements the business logic for Service.
|
||||
type Ocs struct {
|
||||
config *config.Config
|
||||
logger log.Logger
|
||||
mux *chi.Mux
|
||||
config *config.Config
|
||||
logger log.Logger
|
||||
RoleService settings.RoleService
|
||||
RoleManager *roles.Manager
|
||||
mux *chi.Mux
|
||||
}
|
||||
|
||||
// ServeHTTP implements the Service interface.
|
||||
@@ -108,3 +160,8 @@ func (o Ocs) getAccountService() accounts.AccountsService {
|
||||
func (o Ocs) getGroupsService() accounts.GroupsService {
|
||||
return accounts.NewGroupsService("com.owncloud.api.accounts", defaultClient)
|
||||
}
|
||||
|
||||
// NotImplementedStub returns a not implemented error
|
||||
func (o Ocs) NotImplementedStub(w http.ResponseWriter, r *http.Request) {
|
||||
render.Render(w, r, response.ErrRender(data.MetaUnknownError.StatusCode, "Not implemented"))
|
||||
}
|
||||
|
||||
+143
-20
@@ -12,6 +12,7 @@ import (
|
||||
"github.com/cs3org/reva/pkg/user"
|
||||
"github.com/go-chi/chi"
|
||||
"github.com/go-chi/render"
|
||||
"google.golang.org/genproto/protobuf/field_mask"
|
||||
"google.golang.org/protobuf/types/known/fieldmaskpb"
|
||||
|
||||
"github.com/micro/go-micro/v2/client/grpc"
|
||||
@@ -22,22 +23,58 @@ import (
|
||||
storepb "github.com/owncloud/ocis/store/pkg/proto/v0"
|
||||
)
|
||||
|
||||
// GetUser returns the currently logged in user
|
||||
// GetSelf returns the currently logged in user
|
||||
func (o Ocs) GetSelf(w http.ResponseWriter, r *http.Request) {
|
||||
var account *accounts.Account
|
||||
var err error
|
||||
u, ok := user.ContextGetUser(r.Context())
|
||||
if !ok || u.Id == nil || u.Id.OpaqueId == "" {
|
||||
render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "user is missing an id"))
|
||||
return
|
||||
}
|
||||
|
||||
account, err = o.getAccountService().GetAccount(r.Context(), &accounts.GetAccountRequest{
|
||||
Id: u.Id.OpaqueId,
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
merr := merrors.FromError(err)
|
||||
if merr.Code == http.StatusNotFound {
|
||||
// if the user was authenticated why was he not found?!? log error?
|
||||
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(merr).Interface("user", u).Msg("could not get account for user")
|
||||
return
|
||||
}
|
||||
|
||||
// remove password from log if it is set
|
||||
if account.PasswordProfile != nil {
|
||||
account.PasswordProfile.Password = ""
|
||||
}
|
||||
o.logger.Debug().Interface("account", account).Msg("got user")
|
||||
|
||||
d := &data.User{
|
||||
UserID: account.Id,
|
||||
DisplayName: account.DisplayName,
|
||||
LegacyDisplayName: account.DisplayName,
|
||||
Email: account.Mail,
|
||||
UIDNumber: account.UidNumber,
|
||||
GIDNumber: account.GidNumber,
|
||||
// TODO hide enabled flag or it might get rendered as false
|
||||
}
|
||||
render.Render(w, r, response.DataRender(d))
|
||||
}
|
||||
|
||||
// GetUser returns the user with the given userid
|
||||
func (o Ocs) GetUser(w http.ResponseWriter, r *http.Request) {
|
||||
// TODO this endpoint needs authentication using the roles and permissions
|
||||
userid := chi.URLParam(r, "userid")
|
||||
var account *accounts.Account
|
||||
var err error
|
||||
|
||||
if userid == "" {
|
||||
u, ok := user.ContextGetUser(r.Context())
|
||||
if !ok || u.Id == nil || u.Id.OpaqueId == "" {
|
||||
render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "missing user in context"))
|
||||
return
|
||||
}
|
||||
account, err = o.getAccountService().GetAccount(r.Context(), &accounts.GetAccountRequest{
|
||||
Id: u.Id.OpaqueId,
|
||||
})
|
||||
render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "missing user in context"))
|
||||
} else {
|
||||
account, err = o.fetchAccountByUsername(r.Context(), userid)
|
||||
}
|
||||
@@ -48,7 +85,7 @@ func (o Ocs) GetUser(w http.ResponseWriter, r *http.Request) {
|
||||
} else {
|
||||
render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
|
||||
}
|
||||
o.logger.Error().Err(err).Str("userid", userid).Msg("could not get user")
|
||||
o.logger.Error().Err(merr).Str("userid", userid).Msg("could not get account for user")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -67,14 +104,13 @@ func (o Ocs) GetUser(w http.ResponseWriter, r *http.Request) {
|
||||
}
|
||||
|
||||
d := &data.User{
|
||||
UserID: account.PreferredName,
|
||||
UserID: account.Id,
|
||||
DisplayName: account.DisplayName,
|
||||
LegacyDisplayName: account.DisplayName,
|
||||
Email: account.Mail,
|
||||
UIDNumber: account.UidNumber,
|
||||
GIDNumber: account.GidNumber,
|
||||
Enabled: enabled,
|
||||
// FIXME onlyfor users/{userid} endpoint (not /user)
|
||||
Enabled: enabled, // TODO include in response only when admin?
|
||||
// TODO query storage registry for free space? of home storage, maybe...
|
||||
Quota: &data.Quota{
|
||||
Free: 2840756224000,
|
||||
@@ -89,7 +125,6 @@ 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 using the roles and permissions
|
||||
userid := r.PostFormValue("userid")
|
||||
password := r.PostFormValue("password")
|
||||
displayname := r.PostFormValue("displayname")
|
||||
@@ -150,9 +185,18 @@ func (o Ocs) AddUser(w http.ResponseWriter, r *http.Request) {
|
||||
})
|
||||
if err != nil {
|
||||
merr := merrors.FromError(err)
|
||||
if merr.Code == http.StatusBadRequest {
|
||||
switch merr.Code {
|
||||
case http.StatusBadRequest:
|
||||
render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, merr.Detail))
|
||||
} else {
|
||||
case http.StatusConflict:
|
||||
if response.APIVersion(r.Context()) == "2" {
|
||||
// it seems the application framework sets the ocs status code to the httpstatus code, which affects the provisioning api
|
||||
// see https://github.com/owncloud/core/blob/b9ff4c93e051c94adfb301545098ae627e52ef76/lib/public/AppFramework/OCSController.php#L142-L150
|
||||
render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, merr.Detail))
|
||||
} else {
|
||||
render.Render(w, r, response.ErrRender(data.MetaInvalidInput.StatusCode, merr.Detail))
|
||||
}
|
||||
default:
|
||||
render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
|
||||
}
|
||||
o.logger.Error().Err(err).Str("userid", userid).Msg("could not add user")
|
||||
@@ -186,7 +230,6 @@ func (o Ocs) AddUser(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
// EditUser creates a new user account
|
||||
func (o Ocs) EditUser(w http.ResponseWriter, r *http.Request) {
|
||||
// TODO this endpoint needs authentication
|
||||
userid := chi.URLParam(r, "userid")
|
||||
account, err := o.fetchAccountByUsername(r.Context(), userid)
|
||||
if err != nil {
|
||||
@@ -239,7 +282,7 @@ func (o Ocs) EditUser(w http.ResponseWriter, r *http.Request) {
|
||||
default:
|
||||
render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
|
||||
}
|
||||
o.logger.Error().Err(err).Str("userid", req.Account.Id).Msg("could not edit user")
|
||||
o.logger.Error().Err(err).Str("account_id", req.Account.Id).Str("user_id", userid).Msg("could not edit user")
|
||||
return
|
||||
}
|
||||
|
||||
@@ -287,6 +330,86 @@ func (o Ocs) DeleteUser(w http.ResponseWriter, r *http.Request) {
|
||||
render.Render(w, r, response.DataRender(struct{}{}))
|
||||
}
|
||||
|
||||
// EnableUser enables a user
|
||||
func (o Ocs) EnableUser(w http.ResponseWriter, r *http.Request) {
|
||||
userid := chi.URLParam(r, "userid")
|
||||
account, err := o.fetchAccountByUsername(r.Context(), 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 enable user")
|
||||
return
|
||||
}
|
||||
|
||||
account.AccountEnabled = true
|
||||
|
||||
req := accounts.UpdateAccountRequest{
|
||||
Account: account,
|
||||
UpdateMask: &field_mask.FieldMask{
|
||||
Paths: []string{"AccountEnabled"},
|
||||
},
|
||||
}
|
||||
|
||||
_, err = o.getAccountService().UpdateAccount(r.Context(), &req)
|
||||
if err != nil {
|
||||
merr := merrors.FromError(err)
|
||||
if merr.Code == http.StatusNotFound {
|
||||
render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested account could not be found"))
|
||||
} else {
|
||||
render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
|
||||
}
|
||||
o.logger.Error().Err(err).Str("account_id", account.Id).Msg("could not enable account")
|
||||
return
|
||||
}
|
||||
|
||||
o.logger.Debug().Str("account_id", account.Id).Msg("enabled user")
|
||||
render.Render(w, r, response.DataRender(struct{}{}))
|
||||
}
|
||||
|
||||
// DisableUser disables a user
|
||||
func (o Ocs) DisableUser(w http.ResponseWriter, r *http.Request) {
|
||||
userid := chi.URLParam(r, "userid")
|
||||
account, err := o.fetchAccountByUsername(r.Context(), 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 disable user")
|
||||
return
|
||||
}
|
||||
|
||||
account.AccountEnabled = false
|
||||
|
||||
req := accounts.UpdateAccountRequest{
|
||||
Account: account,
|
||||
UpdateMask: &field_mask.FieldMask{
|
||||
Paths: []string{"AccountEnabled"},
|
||||
},
|
||||
}
|
||||
|
||||
_, err = o.getAccountService().UpdateAccount(r.Context(), &req)
|
||||
if err != nil {
|
||||
merr := merrors.FromError(err)
|
||||
if merr.Code == http.StatusNotFound {
|
||||
render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested account could not be found"))
|
||||
} else {
|
||||
render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error()))
|
||||
}
|
||||
o.logger.Error().Err(err).Str("account_id", account.Id).Msg("could not disable account")
|
||||
return
|
||||
}
|
||||
|
||||
o.logger.Debug().Str("account_id", account.Id).Msg("disabled user")
|
||||
render.Render(w, r, response.DataRender(struct{}{}))
|
||||
}
|
||||
|
||||
// GetSigningKey returns the signing key for the current user. It will create it on the fly if it does not exist
|
||||
// The signing key is part of the user settings and is used by the proxy to authenticate requests
|
||||
// Currently, the username is used as the OC-Credential
|
||||
@@ -378,7 +501,7 @@ func (o Ocs) ListUsers(w http.ResponseWriter, r *http.Request) {
|
||||
|
||||
users := []string{}
|
||||
for i := range res.Accounts {
|
||||
users = append(users, res.Accounts[i].Id)
|
||||
users = append(users, res.Accounts[i].OnPremisesSamAccountName)
|
||||
}
|
||||
|
||||
render.Render(w, r, response.DataRender(&data.Users{Users: users}))
|
||||
|
||||
Reference in New Issue
Block a user