From 862329cce0abbf9e3716f9cbca0a66705ff533b5 Mon Sep 17 00:00:00 2001 From: Benedikt Kulmann Date: Thu, 1 Oct 2020 11:35:24 +0200 Subject: [PATCH] Fix service user usage for eos --- accounts/pkg/config/config.go | 2 +- accounts/pkg/flagset/flagset.go | 14 ++++---- accounts/pkg/service/v0/accounts.go | 56 +++++++++++++++++++---------- accounts/pkg/storage/cs3.go | 8 +++-- 4 files changed, 51 insertions(+), 29 deletions(-) diff --git a/accounts/pkg/config/config.go b/accounts/pkg/config/config.go index d2df73c18b..6240b06b1b 100644 --- a/accounts/pkg/config/config.go +++ b/accounts/pkg/config/config.go @@ -81,8 +81,8 @@ type CS3 struct { // ServiceUser defines the user required for EOS type ServiceUser struct { + UUID string Username string - Password string UID int64 GID int64 } diff --git a/accounts/pkg/flagset/flagset.go b/accounts/pkg/flagset/flagset.go index 6b659592a0..e236426368 100644 --- a/accounts/pkg/flagset/flagset.go +++ b/accounts/pkg/flagset/flagset.go @@ -127,6 +127,13 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag { EnvVars: []string{"ACCOUNTS_STORAGE_CS3_DATA_PREFIX"}, Destination: &cfg.Repo.CS3.DataPrefix, }, + &cli.StringFlag{ + Name: "service-user-uuid", + Value: "95cb8724-03b2-11eb-a0a6-c33ef8ef53ad", + Usage: "uuid of the internal service user (required on EOS)", + EnvVars: []string{"ACCOUNTS_SERVICE_USER_UUID"}, + Destination: &cfg.ServiceUser.UUID, + }, &cli.StringFlag{ Name: "service-user-username", Value: "", @@ -134,13 +141,6 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag { EnvVars: []string{"ACCOUNTS_SERVICE_USER_USERNAME"}, Destination: &cfg.ServiceUser.Username, }, - &cli.StringFlag{ - Name: "service-user-password", - Value: "", - Usage: "password of the internal service user (required on EOS)", - EnvVars: []string{"ACCOUNTS_SERVICE_USER_PASSWORD"}, - Destination: &cfg.ServiceUser.Password, - }, &cli.Int64Flag{ Name: "service-user-uid", Value: 0, diff --git a/accounts/pkg/service/v0/accounts.go b/accounts/pkg/service/v0/accounts.go index 5ff29c5193..acdd1c855b 100644 --- a/accounts/pkg/service/v0/accounts.go +++ b/accounts/pkg/service/v0/accounts.go @@ -5,7 +5,6 @@ import ( "fmt" "path/filepath" "regexp" - "strings" "sync" "time" @@ -102,6 +101,36 @@ func (s Service) hasAccountManagementPermissions(ctx context.Context) bool { return s.RoleManager.FindPermissionByID(ctx, roleIDs, AccountManagementPermissionID) != nil } +// serviceUserToIndex temporarily adds a service user to the index, which is supposed to be removed before the lock on the handler function is released +func (s Service) serviceUserToIndex() (teardownServiceUser func()) { + if s.Config.ServiceUser.Username != "" && s.Config.ServiceUser.UUID != "" { + err := s.index.Index(s.Config.ServiceUser.UUID, &proto.BleveAccount{ + BleveType: "account", + Account: s.getInMemoryServiceUser(), + }) + if err != nil { + s.log.Logger.Err(err).Msg("service user was configured but failed to be added to the index") + } else { + return func() { + _ = s.index.Delete(s.Config.ServiceUser.UUID) + } + } + } + return func() {} +} + +func (s Service) getInMemoryServiceUser() proto.Account { + return proto.Account{ + AccountEnabled: true, + Id: s.Config.ServiceUser.UUID, + PreferredName: s.Config.ServiceUser.Username, + OnPremisesSamAccountName: s.Config.ServiceUser.Username, + DisplayName: s.Config.ServiceUser.Username, + UidNumber: s.Config.ServiceUser.UID, + GidNumber: s.Config.ServiceUser.GID, + } +} + // ListAccounts implements the AccountsServiceHandler interface // the query contains account properties func (s Service) ListAccounts(ctx context.Context, in *proto.ListAccountsRequest, out *proto.ListAccountsResponse) (err error) { @@ -113,6 +142,9 @@ func (s Service) ListAccounts(ctx context.Context, in *proto.ListAccountsRequest defer accLock.Unlock() var password string + teardownServiceUser := s.serviceUserToIndex() + defer teardownServiceUser() + // check if this looks like an auth request match := authQuery.FindStringSubmatch(in.Query) if len(match) == 3 { @@ -121,23 +153,6 @@ func (s Service) ListAccounts(ctx context.Context, in *proto.ListAccountsRequest if password == "" { return merrors.Unauthorized(s.id, "password must not be empty") } - - // hardcoded check against service user - if s.Config.ServiceUser.Username != "" && - strings.EqualFold(match[1], s.Config.ServiceUser.Username) && - match[2] == s.Config.ServiceUser.Password { - out.Accounts = []*proto.Account{ - { - Id: "95cb8724-03b2-11eb-a0a6-c33ef8ef53ad", - AccountEnabled: true, - PreferredName: s.Config.ServiceUser.Username, - DisplayName: s.Config.ServiceUser.Username, - UidNumber: s.Config.ServiceUser.UID, - GidNumber: s.Config.ServiceUser.GID, - }, - } - return nil - } } // only search for accounts @@ -179,7 +194,10 @@ func (s Service) ListAccounts(ctx context.Context, in *proto.ListAccountsRequest for _, hit := range searchResult.Hits { a := &proto.Account{} - if err = s.repo.LoadAccount(ctx, hit.ID, a); err != nil { + if hit.ID == s.Config.ServiceUser.UUID { + acc := s.getInMemoryServiceUser() + a = &acc + } else if err = s.repo.LoadAccount(ctx, hit.ID, a); err != nil { s.log.Error().Err(err).Str("account", hit.ID).Msg("could not load account, skipping") continue } diff --git a/accounts/pkg/storage/cs3.go b/accounts/pkg/storage/cs3.go index 12609a9f2b..b1b51fe2a5 100644 --- a/accounts/pkg/storage/cs3.go +++ b/accounts/pkg/storage/cs3.go @@ -211,10 +211,14 @@ func (r CS3Repo) DeleteGroup(ctx context.Context, id string) (err error) { } func (r CS3Repo) authenticate(ctx context.Context) (token string, err error) { - return r.tm.MintToken(ctx, &user.User{ + u := &user.User{ Id: &user.UserId{}, Groups: []string{}, - }) + } + if r.cfg.ServiceUser.Username != "" { + u.Id.OpaqueId = r.cfg.ServiceUser.UUID + } + return r.tm.MintToken(ctx, u) } func (r CS3Repo) accountURL(id string) string {