mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-01-06 04:09:40 -06:00
Make accounts backend configurable in ocs
This commit is contained in:
@@ -47,13 +47,15 @@ type TokenManager struct {
|
||||
|
||||
// Config combines all available configuration parts.
|
||||
type Config struct {
|
||||
File string
|
||||
Log Log
|
||||
Debug Debug
|
||||
HTTP HTTP
|
||||
Tracing Tracing
|
||||
TokenManager TokenManager
|
||||
Service Service
|
||||
File string
|
||||
Log Log
|
||||
Debug Debug
|
||||
HTTP HTTP
|
||||
Tracing Tracing
|
||||
TokenManager TokenManager
|
||||
Service Service
|
||||
AccountBackend string
|
||||
RevaAddress string
|
||||
|
||||
Context context.Context
|
||||
Supervised bool
|
||||
|
||||
@@ -150,6 +150,21 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag {
|
||||
EnvVars: []string{"OCS_JWT_SECRET", "OCIS_JWT_SECRET"},
|
||||
Destination: &cfg.TokenManager.JWTSecret,
|
||||
},
|
||||
|
||||
&cli.StringFlag{
|
||||
Name: "account-backend-type",
|
||||
Value: flags.OverrideDefaultString(cfg.AccountBackend, "accounts"),
|
||||
Usage: "account-backend-type",
|
||||
EnvVars: []string{"OCS_ACCOUNT_BACKEND_TYPE"},
|
||||
Destination: &cfg.AccountBackend,
|
||||
},
|
||||
&cli.StringFlag{
|
||||
Name: "reva-gateway-addr",
|
||||
Value: flags.OverrideDefaultString(cfg.RevaAddress, "127.0.0.1:9142"),
|
||||
Usage: "REVA Gateway Endpoint",
|
||||
EnvVars: []string{"OCS_REVA_GATEWAY_ADDR"},
|
||||
Destination: &cfg.RevaAddress,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,6 +10,7 @@ import (
|
||||
"github.com/go-chi/chi/middleware"
|
||||
"github.com/go-chi/render"
|
||||
|
||||
cs3 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
accounts "github.com/owncloud/ocis/accounts/pkg/proto/v0"
|
||||
"github.com/owncloud/ocis/ocis-pkg/account"
|
||||
"github.com/owncloud/ocis/ocis-pkg/log"
|
||||
@@ -19,6 +20,7 @@ import (
|
||||
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/proxy/pkg/user/backend"
|
||||
settings "github.com/owncloud/ocis/settings/pkg/proto/v0"
|
||||
)
|
||||
|
||||
@@ -154,6 +156,11 @@ func (o Ocs) getAccountService() accounts.AccountsService {
|
||||
return accounts.NewAccountsService("com.owncloud.api.accounts", grpc.DefaultClient)
|
||||
}
|
||||
|
||||
func (o Ocs) getCS3Backend() backend.UserBackend {
|
||||
revaClient, err := cs3.GetGatewayServiceClient(o.config.RevaAddress)
|
||||
return backend.NewCS3UserBackend(revaClient, nil, revaClient, o.logger)
|
||||
}
|
||||
|
||||
func (o Ocs) getGroupsService() accounts.GroupsService {
|
||||
return accounts.NewGroupsService("com.owncloud.api.accounts", grpc.DefaultClient)
|
||||
}
|
||||
|
||||
@@ -34,27 +34,19 @@ func (o Ocs) GetSelf(w http.ResponseWriter, r *http.Request) {
|
||||
return
|
||||
}
|
||||
|
||||
account, err = o.getAccountService().GetAccount(r.Context(), &accounts.GetAccountRequest{
|
||||
Id: u.Id.OpaqueId,
|
||||
})
|
||||
switch o.config.AccountBackend {
|
||||
case "accounts":
|
||||
account, err = o.getAccountService().GetAccount(r.Context(), &accounts.GetAccountRequest{
|
||||
Id: u.Id.OpaqueId,
|
||||
})
|
||||
case "cs3":
|
||||
account, err = o.fetchAccountFromCS3BackendByID(r.Context(), u.Id)
|
||||
default:
|
||||
o.logger.Fatal().Msgf("Invalid accounts backend type '%s'", o.config.AccountBackend)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
merr := merrors.FromError(err)
|
||||
// TODO(someone) this fix is in place because if the user backend (PROXY_ACCOUNT_BACKEND_TYPE) is set to, for instance,
|
||||
// cs3, we cannot count with the accounts service.
|
||||
if u != nil {
|
||||
uid, gid := o.extractUIDAndGID(u)
|
||||
d := &data.User{
|
||||
UserID: u.Username,
|
||||
DisplayName: u.DisplayName,
|
||||
LegacyDisplayName: u.DisplayName,
|
||||
Email: u.Mail,
|
||||
UIDNumber: uid,
|
||||
GIDNumber: gid,
|
||||
}
|
||||
mustNotFail(render.Render(w, r, response.DataRender(d)))
|
||||
return
|
||||
}
|
||||
o.logger.Error().Err(merr).Interface("user", u).Msg("could not get account for user")
|
||||
return
|
||||
}
|
||||
@@ -83,39 +75,23 @@ func (o Ocs) GetUser(w http.ResponseWriter, r *http.Request) {
|
||||
var account *accounts.Account
|
||||
var err error
|
||||
|
||||
if userid == "" {
|
||||
switch {
|
||||
case userid == "":
|
||||
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "missing user in context")))
|
||||
} else {
|
||||
case o.config.AccountBackend == "accounts":
|
||||
account, err = o.fetchAccountByUsername(r.Context(), userid)
|
||||
case o.config.AccountBackend == "cs3":
|
||||
account, err = o.fetchAccountFromCS3BackendByUsername(r.Context(), userid)
|
||||
default:
|
||||
o.logger.Fatal().Msgf("Invalid accounts backend type '%s'", o.config.AccountBackend)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
merr := merrors.FromError(err)
|
||||
u, ok := user.ContextGetUser(r.Context())
|
||||
if !ok || u.Id == nil || u.Id.OpaqueId == "" {
|
||||
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaBadRequest.StatusCode, "user is missing an id")))
|
||||
return
|
||||
}
|
||||
if u != nil {
|
||||
uid, gid := o.extractUIDAndGID(u)
|
||||
d := &data.User{
|
||||
UserID: u.Username,
|
||||
DisplayName: u.DisplayName,
|
||||
LegacyDisplayName: u.DisplayName,
|
||||
Email: u.Mail,
|
||||
UIDNumber: uid,
|
||||
GIDNumber: gid,
|
||||
Enabled: "true", // Assume true for CS3 backend?
|
||||
// TODO query storage registry for free space? of home storage, maybe...
|
||||
Quota: &data.Quota{
|
||||
Free: 2840756224000,
|
||||
Used: 5059416668,
|
||||
Total: 2845815640668,
|
||||
Relative: 0.18,
|
||||
Definition: "default",
|
||||
},
|
||||
}
|
||||
mustNotFail(render.Render(w, r, response.DataRender(d)))
|
||||
return
|
||||
if merr.Code == http.StatusNotFound {
|
||||
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaNotFound.StatusCode, "The requested user could not be found")))
|
||||
} else {
|
||||
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, err.Error())))
|
||||
}
|
||||
o.logger.Error().Err(merr).Str("userid", userid).Msg("could not get account for user")
|
||||
return
|
||||
@@ -212,9 +188,20 @@ func (o Ocs) AddUser(w http.ResponseWriter, r *http.Request) {
|
||||
newAccount.GidNumber = gidNumber
|
||||
}
|
||||
|
||||
account, err := o.getAccountService().CreateAccount(r.Context(), &accounts.CreateAccountRequest{
|
||||
Account: newAccount,
|
||||
})
|
||||
var account *accounts.Account
|
||||
var err error
|
||||
|
||||
switch o.config.AccountBackend {
|
||||
case "accounts":
|
||||
account, err = o.getAccountService().CreateAccount(r.Context(), &accounts.CreateAccountRequest{
|
||||
Account: newAccount,
|
||||
})
|
||||
case "cs3":
|
||||
o.logger.Fatal().Msg("cs3 backend doesn't support adding users")
|
||||
default:
|
||||
o.logger.Fatal().Msgf("Invalid accounts backend type '%s'", o.config.AccountBackend)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
merr := merrors.FromError(err)
|
||||
switch merr.Code {
|
||||
@@ -263,7 +250,18 @@ 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) {
|
||||
userid := chi.URLParam(r, "userid")
|
||||
account, err := o.fetchAccountByUsername(r.Context(), userid)
|
||||
|
||||
var account *accounts.Account
|
||||
var err error
|
||||
switch o.config.AccountBackend {
|
||||
case "accounts":
|
||||
account, err := o.fetchAccountByUsername(r.Context(), userid)
|
||||
case "cs3":
|
||||
o.logger.Fatal().Msg("cs3 backend doesn't support editing users")
|
||||
default:
|
||||
o.logger.Fatal().Msgf("Invalid accounts backend type '%s'", o.config.AccountBackend)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
merr := merrors.FromError(err)
|
||||
if merr.Code == http.StatusNotFound {
|
||||
@@ -330,7 +328,18 @@ func (o Ocs) EditUser(w http.ResponseWriter, r *http.Request) {
|
||||
// DeleteUser deletes a user
|
||||
func (o Ocs) DeleteUser(w http.ResponseWriter, r *http.Request) {
|
||||
userid := chi.URLParam(r, "userid")
|
||||
account, err := o.fetchAccountByUsername(r.Context(), userid)
|
||||
|
||||
var account *accounts.Account
|
||||
var err error
|
||||
switch o.config.AccountBackend {
|
||||
case "accounts":
|
||||
account, err := o.fetchAccountByUsername(r.Context(), userid)
|
||||
case "cs3":
|
||||
o.logger.Fatal().Msg("cs3 backend doesn't support deleting users")
|
||||
default:
|
||||
o.logger.Fatal().Msgf("Invalid accounts backend type '%s'", o.config.AccountBackend)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
merr := merrors.FromError(err)
|
||||
if merr.Code == http.StatusNotFound {
|
||||
@@ -365,7 +374,18 @@ func (o Ocs) DeleteUser(w http.ResponseWriter, r *http.Request) {
|
||||
// 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)
|
||||
|
||||
var account *accounts.Account
|
||||
var err error
|
||||
switch o.config.AccountBackend {
|
||||
case "accounts":
|
||||
account, err := o.fetchAccountByUsername(r.Context(), userid)
|
||||
case "cs3":
|
||||
o.logger.Fatal().Msg("cs3 backend doesn't support enabling users")
|
||||
default:
|
||||
o.logger.Fatal().Msgf("Invalid accounts backend type '%s'", o.config.AccountBackend)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
merr := merrors.FromError(err)
|
||||
if merr.Code == http.StatusNotFound {
|
||||
@@ -405,7 +425,18 @@ func (o Ocs) EnableUser(w http.ResponseWriter, r *http.Request) {
|
||||
// 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)
|
||||
|
||||
var account *accounts.Account
|
||||
var err error
|
||||
switch o.config.AccountBackend {
|
||||
case "accounts":
|
||||
account, err := o.fetchAccountByUsername(r.Context(), userid)
|
||||
case "cs3":
|
||||
o.logger.Fatal().Msg("cs3 backend doesn't support disabling users")
|
||||
default:
|
||||
o.logger.Fatal().Msgf("Invalid accounts backend type '%s'", o.config.AccountBackend)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
merr := merrors.FromError(err)
|
||||
if merr.Code == http.StatusNotFound {
|
||||
@@ -522,9 +553,20 @@ func (o Ocs) ListUsers(w http.ResponseWriter, r *http.Request) {
|
||||
query = fmt.Sprintf("on_premises_sam_account_name eq '%s'", escapeValue(search))
|
||||
}
|
||||
|
||||
res, err := o.getAccountService().ListAccounts(r.Context(), &accounts.ListAccountsRequest{
|
||||
Query: query,
|
||||
})
|
||||
var res *accounts.ListAccountsResponse
|
||||
var err error
|
||||
switch o.config.AccountBackend {
|
||||
case "accounts":
|
||||
res, err = o.getAccountService().ListAccounts(r.Context(), &accounts.ListAccountsRequest{
|
||||
Query: query,
|
||||
})
|
||||
case "cs3":
|
||||
// TODO
|
||||
o.logger.Fatal().Msg("cs3 backend doesn't support listing users")
|
||||
default:
|
||||
o.logger.Fatal().Msgf("Invalid accounts backend type '%s'", o.config.AccountBackend)
|
||||
}
|
||||
|
||||
if err != nil {
|
||||
o.logger.Err(err).Msg("could not list users")
|
||||
mustNotFail(render.Render(w, r, response.ErrRender(data.MetaServerError.StatusCode, "could not list users")))
|
||||
@@ -558,6 +600,38 @@ func (o Ocs) fetchAccountByUsername(ctx context.Context, name string) (*accounts
|
||||
return nil, merrors.NotFound("", "The requested user could not be found")
|
||||
}
|
||||
|
||||
func (o Ocs) fetchAccountFromCS3BackendByUsername(ctx context.Context, name string) (*accounts.Account, error) {
|
||||
backend := o.getCS3Backend()
|
||||
u, err := backend.GetUserByClaims(ctx, "username", name, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uid, gid := o.extractUIDAndGID(u)
|
||||
return &accounts.Account{
|
||||
OnPremisesSamAccountName: u.Username,
|
||||
DisplayName: u.DisplayName,
|
||||
Mail: u.Mail,
|
||||
UIDNumber: uid,
|
||||
GIDNumber: gid,
|
||||
}
|
||||
}
|
||||
|
||||
func (o Ocs) fetchAccountFromCS3BackendByID(ctx context.Context, id *cs3.UserId) (*accounts.Account, error) {
|
||||
backend := o.getCS3Backend()
|
||||
u, err := backend.GetUser(ctx, id, false)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
uid, gid := o.extractUIDAndGID(u)
|
||||
return &accounts.Account{
|
||||
OnPremisesSamAccountName: u.Username,
|
||||
DisplayName: u.DisplayName,
|
||||
Mail: u.Mail,
|
||||
UIDNumber: uid,
|
||||
GIDNumber: gid,
|
||||
}
|
||||
}
|
||||
|
||||
func (o Ocs) extractUIDAndGID(u *cs3.User) (int64, int64) {
|
||||
var uid, gid int64
|
||||
var err error
|
||||
|
||||
Reference in New Issue
Block a user