mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-04-27 22:41:10 -05:00
Merge pull request #1911 from ishank011/gh-ocis-1825
This commit is contained in:
@@ -18,6 +18,7 @@ require (
|
||||
github.com/olekukonko/tablewriter v0.0.5
|
||||
github.com/openzipkin/zipkin-go v0.2.5
|
||||
github.com/owncloud/ocis/accounts v0.5.3-0.20210216094451-dc73176dc62d
|
||||
github.com/owncloud/ocis/proxy v0.0.0-20210216094451-dc73176dc62d
|
||||
github.com/owncloud/ocis/ocis-pkg v0.0.0-20210216094451-dc73176dc62d
|
||||
github.com/owncloud/ocis/settings v0.0.0-20210216094451-dc73176dc62d
|
||||
github.com/owncloud/ocis/store v0.0.0-20210216094451-dc73176dc62d
|
||||
@@ -32,6 +33,7 @@ require (
|
||||
|
||||
replace (
|
||||
github.com/owncloud/ocis/accounts => ../accounts
|
||||
github.com/owncloud/ocis/proxy => ../proxy
|
||||
github.com/owncloud/ocis/ocis-pkg => ../ocis-pkg
|
||||
github.com/owncloud/ocis/settings => ../settings
|
||||
github.com/owncloud/ocis/store => ../store
|
||||
|
||||
@@ -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,
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -19,6 +19,8 @@ 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/cs3"
|
||||
"github.com/owncloud/ocis/proxy/pkg/user/backend"
|
||||
settings "github.com/owncloud/ocis/settings/pkg/proto/v0"
|
||||
)
|
||||
|
||||
@@ -57,6 +59,10 @@ func NewService(opts ...Option) Service {
|
||||
logger: options.Logger,
|
||||
}
|
||||
|
||||
if svc.config.AccountBackend == "" {
|
||||
svc.config.AccountBackend = "accounts"
|
||||
}
|
||||
|
||||
requireUser := ocsm.RequireUser()
|
||||
|
||||
requireAdmin := ocsm.RequireAdmin(
|
||||
@@ -154,6 +160,14 @@ 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)
|
||||
if err != nil {
|
||||
o.logger.Fatal().Msgf("could not get reva client at address %s", 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)
|
||||
}
|
||||
|
||||
+127
-14
@@ -17,6 +17,7 @@ import (
|
||||
"google.golang.org/protobuf/types/known/fieldmaskpb"
|
||||
|
||||
merrors "github.com/asim/go-micro/v3/errors"
|
||||
cs3 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
||||
accounts "github.com/owncloud/ocis/accounts/pkg/proto/v0"
|
||||
"github.com/owncloud/ocis/ocs/pkg/service/v0/data"
|
||||
"github.com/owncloud/ocis/ocs/pkg/service/v0/response"
|
||||
@@ -42,13 +43,14 @@ func (o Ocs) GetSelf(w http.ResponseWriter, r *http.Request) {
|
||||
// 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: u.UidNumber,
|
||||
GIDNumber: u.GidNumber,
|
||||
UIDNumber: uid,
|
||||
GIDNumber: gid,
|
||||
}
|
||||
mustNotFail(render.Render(w, r, response.DataRender(d)))
|
||||
return
|
||||
@@ -81,11 +83,17 @@ 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.fetchAccountFromCS3Backend(r.Context(), userid)
|
||||
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 {
|
||||
@@ -188,9 +196,19 @@ 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
|
||||
|
||||
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 {
|
||||
@@ -239,7 +257,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 {
|
||||
@@ -306,7 +335,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 {
|
||||
@@ -341,7 +381,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 {
|
||||
@@ -381,7 +432,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 {
|
||||
@@ -498,9 +560,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")))
|
||||
@@ -533,3 +606,43 @@ func (o Ocs) fetchAccountByUsername(ctx context.Context, name string) (*accounts
|
||||
}
|
||||
return nil, merrors.NotFound("", "The requested user could not be found")
|
||||
}
|
||||
|
||||
func (o Ocs) fetchAccountFromCS3Backend(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,
|
||||
}, nil
|
||||
}
|
||||
|
||||
func (o Ocs) extractUIDAndGID(u *cs3.User) (int64, int64) {
|
||||
var uid, gid int64
|
||||
var err error
|
||||
if u.Opaque != nil && u.Opaque.Map != nil {
|
||||
if uidObj, ok := u.Opaque.Map["uid"]; ok {
|
||||
if uidObj.Decoder == "plain" {
|
||||
uid, err = strconv.ParseInt(string(uidObj.Value), 10, 64)
|
||||
if err != nil {
|
||||
o.logger.Error().Err(err).Interface("user", u).Msg("could not extract uid for user")
|
||||
}
|
||||
}
|
||||
}
|
||||
if gidObj, ok := u.Opaque.Map["gid"]; ok {
|
||||
if gidObj.Decoder == "plain" {
|
||||
gid, err = strconv.ParseInt(string(gidObj.Value), 10, 64)
|
||||
if err != nil {
|
||||
o.logger.Error().Err(err).Interface("user", u).Msg("could not extract gid for user")
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return uid, gid
|
||||
}
|
||||
|
||||
@@ -70,10 +70,14 @@ func (c *cs3backend) GetUserByClaims(ctx context.Context, claim, value string, w
|
||||
c.logger.Error().Err(err).Msg("Could not encode loaded roles")
|
||||
}
|
||||
|
||||
user.Opaque = &types.Opaque{
|
||||
Map: map[string]*types.OpaqueEntry{
|
||||
"roles": enc,
|
||||
},
|
||||
if user.Opaque == nil {
|
||||
user.Opaque = &types.Opaque{
|
||||
Map: map[string]*types.OpaqueEntry{
|
||||
"roles": enc,
|
||||
},
|
||||
}
|
||||
} else {
|
||||
user.Opaque.Map["roles"] = enc
|
||||
}
|
||||
|
||||
return res.User, nil
|
||||
|
||||
Reference in New Issue
Block a user