Use reva's Authenticate method instead of spawning token managers

This commit is contained in:
Ishank Arora
2021-09-21 15:33:58 +02:00
parent ed6ed61b87
commit 08c51ee8c8
15 changed files with 140 additions and 93 deletions

View File

@@ -0,0 +1,11 @@
Enhancement: Use reva's Authenticate method instead of spawning token managers
When using the CS3 proxy backend, we previously obtained the user from reva's
userprovider service and minted the token ourselves. This required maintaining
a shared JWT secret between ocis and reva, as well duplication of logic. This
PR delegates this logic by using the `Authenticate` method provided by the reva
gateway service to obtain this token, making it an arbitrary, indestructible
entry. Currently, the changes have been made to the proxy service but will be
extended to others as well.
https://github.com/owncloud/ocis/pull/2528

View File

@@ -9,6 +9,7 @@ import (
"time"
"github.com/coreos/go-oidc/v3/oidc"
"github.com/cs3org/reva/pkg/token/manager/jwt"
chimiddleware "github.com/go-chi/chi/v5/middleware"
"github.com/justinas/alice"
"github.com/micro/cli/v2"
@@ -148,14 +149,23 @@ func loadMiddlewares(ctx context.Context, l log.Logger, cfg *config.Config) alic
var userProvider backend.UserBackend
switch cfg.AccountBackend {
case "accounts":
tokenManager, err := jwt.New(map[string]interface{}{
"secret": cfg.TokenManager.JWTSecret,
"expires": int64(24 * 60 * 60),
})
if err != nil {
l.Error().Err(err).
Msg("Failed to create token manager")
}
userProvider = backend.NewAccountsServiceUserBackend(
acc.NewAccountsService("com.owncloud.api.accounts", grpc.DefaultClient),
rolesClient,
cfg.OIDC.Issuer,
tokenManager,
l,
)
case "cs3":
userProvider = backend.NewCS3UserBackend(revaClient, rolesClient, revaClient, l)
userProvider = backend.NewCS3UserBackend(rolesClient, revaClient, cfg.MachineAuthAPIKey, l)
default:
l.Fatal().Msgf("Invalid accounts backend type '%s'", cfg.AccountBackend)
}
@@ -217,7 +227,6 @@ func loadMiddlewares(ctx context.Context, l log.Logger, cfg *config.Config) alic
middleware.AccountResolver(
middleware.Logger(l),
middleware.UserProvider(userProvider),
middleware.TokenManagerConfig(cfg.TokenManager),
middleware.UserOIDCClaim(cfg.UserOIDCClaim),
middleware.UserCS3Claim(cfg.UserCS3Claim),
middleware.AutoprovisionAccounts(cfg.AutoprovisionAccounts),
@@ -232,7 +241,6 @@ func loadMiddlewares(ctx context.Context, l log.Logger, cfg *config.Config) alic
// finally, trigger home creation when a user logs in
middleware.CreateHome(
middleware.Logger(l),
middleware.TokenManagerConfig(cfg.TokenManager),
middleware.RevaGatewayClient(revaClient),
),
)

View File

@@ -121,8 +121,9 @@ type Config struct {
Reva Reva
PreSignedURL PreSignedURL
AccountBackend string
UserOIDCClaim string
UserCS3Claim string
UserOIDCClaim string
UserCS3Claim string
MachineAuthAPIKey string
AutoprovisionAccounts bool
EnableBasicAuth bool
InsecureBackends bool

View File

@@ -291,6 +291,14 @@ func ServerWithConfig(cfg *config.Config) []cli.Flag {
Destination: &cfg.AccountBackend,
},
&cli.StringFlag{
Name: "machine-auth-api-key",
Value: flags.OverrideDefaultString(cfg.MachineAuthAPIKey, "change-me-please"),
Usage: "the API key to be used for the machine auth driver in reva",
EnvVars: []string{"PROXY_MACHINE_AUTH_API_KEY"},
Destination: &cfg.MachineAuthAPIKey,
},
// Reva Middlewares Config
&cli.StringSliceFlag{
Name: "proxy-user-agent-lock-in",

View File

@@ -4,12 +4,9 @@ import (
"errors"
"net/http"
"github.com/cs3org/reva/pkg/auth/scope"
"github.com/owncloud/ocis/proxy/pkg/user/backend"
revactx "github.com/cs3org/reva/pkg/ctx"
"github.com/cs3org/reva/pkg/token"
"github.com/cs3org/reva/pkg/token/manager/jwt"
"github.com/owncloud/ocis/ocis-pkg/log"
"github.com/owncloud/ocis/ocis-pkg/oidc"
)
@@ -21,18 +18,9 @@ func AccountResolver(optionSetters ...Option) func(next http.Handler) http.Handl
logger := options.Logger
return func(next http.Handler) http.Handler {
tokenManager, err := jwt.New(map[string]interface{}{
"secret": options.TokenManagerConfig.JWTSecret,
"expires": int64(60),
})
if err != nil {
logger.Fatal().Err(err).Msg("Could not initialize token-manager")
}
return &accountResolver{
next: next,
logger: logger,
tokenManager: tokenManager,
userProvider: options.UserProvider,
userOIDCClaim: options.UserOIDCClaim,
userCS3Claim: options.UserCS3Claim,
@@ -44,7 +32,6 @@ func AccountResolver(optionSetters ...Option) func(next http.Handler) http.Handl
type accountResolver struct {
next http.Handler
logger log.Logger
tokenManager token.Manager
userProvider backend.UserBackend
autoProvisionAccounts bool
userOIDCClaim string
@@ -56,6 +43,7 @@ func (m accountResolver) ServeHTTP(w http.ResponseWriter, req *http.Request) {
ctx := req.Context()
claims := oidc.FromContext(ctx)
u, ok := revactx.ContextGetUser(ctx)
token := ""
// TODO what if an X-Access-Token is set? happens eg for download requests to the /data endpoint in the reva frontend
if claims == nil && !ok {
@@ -74,7 +62,7 @@ func (m accountResolver) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
u, err = m.userProvider.GetUserByClaims(req.Context(), m.userCS3Claim, value, true)
u, token, err = m.userProvider.GetUserByClaims(req.Context(), m.userCS3Claim, value, true)
if errors.Is(err, backend.ErrAccountNotFound) {
m.logger.Debug().Str("claim", m.userOIDCClaim).Str("value", value).Msg("User by claim not found")
@@ -108,18 +96,6 @@ func (m accountResolver) ServeHTTP(w http.ResponseWriter, req *http.Request) {
m.logger.Debug().Interface("claims", claims).Interface("user", u).Msg("associated claims with user")
}
s, err := scope.AddOwnerScope(nil)
if err != nil {
m.logger.Error().Err(err).Msg("could not get owner scope")
return
}
token, err := m.tokenManager.MintToken(ctx, u, s)
if err != nil {
m.logger.Error().Err(err).Msg("could not mint token")
w.WriteHeader(http.StatusInternalServerError)
return
}
req.Header.Set(revactx.TokenHeader, token)
m.next.ServeHTTP(w, req)

View File

@@ -7,7 +7,9 @@ import (
"testing"
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
"github.com/cs3org/reva/pkg/auth/scope"
revactx "github.com/cs3org/reva/pkg/ctx"
"github.com/cs3org/reva/pkg/token/manager/jwt"
"github.com/owncloud/ocis/ocis-pkg/log"
"github.com/owncloud/ocis/ocis-pkg/oidc"
"github.com/owncloud/ocis/proxy/pkg/config"
@@ -106,9 +108,20 @@ func TestInternalServerErrorOnMissingMailAndUsername(t *testing.T) {
}
func newMockAccountResolver(userBackendResult *userv1beta1.User, userBackendErr error, oidcclaim, cs3claim string) http.Handler {
tokenManager, _ := jwt.New(map[string]interface{}{
"secret": "change-me",
"expires": int64(60),
})
token := ""
if userBackendResult != nil {
s, _ := scope.AddOwnerScope(nil)
token, _ = tokenManager.MintToken(context.Background(), userBackendResult, s)
}
mock := &test.UserBackendMock{
GetUserByClaimsFunc: func(ctx context.Context, claim string, value string, withRoles bool) (*userv1beta1.User, error) {
return userBackendResult, userBackendErr
GetUserByClaimsFunc: func(ctx context.Context, claim string, value string, withRoles bool) (*userv1beta1.User, string, error) {
return userBackendResult, token, userBackendErr
},
}

View File

@@ -41,7 +41,7 @@ func BasicAuth(optionSetters ...Option) func(next http.Handler) http.Handler {
removeSuperfluousAuthenticate(w)
login, password, _ := req.BasicAuth()
user, err := h.userProvider.Authenticate(req.Context(), login, password)
user, _, err := h.userProvider.Authenticate(req.Context(), login, password)
// touch is a user agent locking guard, when touched changes to true it indicates the User-Agent on the
// request is configured to support only one challenge, it it remains untouched, there are no considera-

View File

@@ -8,8 +8,6 @@ import (
provider "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
revactx "github.com/cs3org/reva/pkg/ctx"
"github.com/cs3org/reva/pkg/rgrpc/status"
"github.com/cs3org/reva/pkg/token"
"github.com/cs3org/reva/pkg/token/manager/jwt"
"github.com/owncloud/ocis/ocis-pkg/log"
"google.golang.org/grpc/metadata"
)
@@ -20,17 +18,9 @@ func CreateHome(optionSetters ...Option) func(next http.Handler) http.Handler {
logger := options.Logger
return func(next http.Handler) http.Handler {
tokenManager, err := jwt.New(map[string]interface{}{
"secret": options.TokenManagerConfig.JWTSecret,
})
if err != nil {
logger.Fatal().Err(err).Msgf("Could not initialize token-manager")
}
return &createHome{
next: next,
logger: logger,
tokenManager: tokenManager,
revaGatewayClient: options.RevaGatewayClient,
}
}
@@ -39,7 +29,6 @@ func CreateHome(optionSetters ...Option) func(next http.Handler) http.Handler {
type createHome struct {
next http.Handler
logger log.Logger
tokenManager token.Manager
revaGatewayClient gateway.GatewayAPIClient
}

View File

@@ -45,9 +45,9 @@ type Options struct {
// PreSignedURLConfig to configure the middleware
PreSignedURLConfig config.PreSignedURL
// UserOIDCClaim to read from the oidc claims
UserOIDCClaim string
UserOIDCClaim string
// UserCS3Claim to use when looking up a user in the CS3 API
UserCS3Claim string
UserCS3Claim string
// AutoprovisionAccounts when an accountResolver does not exist.
AutoprovisionAccounts bool
// EnableBasicAuth to allow basic auth

View File

@@ -48,7 +48,7 @@ func (m signedURLAuth) ServeHTTP(w http.ResponseWriter, req *http.Request) {
return
}
user, err := m.userProvider.GetUserByClaims(req.Context(), "username", req.URL.Query().Get("OC-Credential"), true)
user, _, err := m.userProvider.GetUserByClaims(req.Context(), "username", req.URL.Query().Get("OC-Credential"), true)
if err != nil {
m.logger.Error().Err(err).Msg("Could not get user by claim")
w.WriteHeader(http.StatusInternalServerError)

View File

@@ -8,6 +8,8 @@ import (
cs3 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
"github.com/cs3org/reva/pkg/auth/scope"
"github.com/cs3org/reva/pkg/token"
accounts "github.com/owncloud/ocis/accounts/pkg/proto/v0"
"github.com/owncloud/ocis/ocis-pkg/log"
"github.com/owncloud/ocis/ocis-pkg/oidc"
@@ -15,11 +17,12 @@ import (
)
// NewAccountsServiceUserBackend creates a user-provider which fetches users from the ocis accounts-service
func NewAccountsServiceUserBackend(ac accounts.AccountsService, rs settings.RoleService, oidcISS string, logger log.Logger) UserBackend {
func NewAccountsServiceUserBackend(ac accounts.AccountsService, rs settings.RoleService, oidcISS string, tokenManager token.Manager, logger log.Logger) UserBackend {
return &accountsServiceBackend{
accountsClient: ac,
settingsRoleService: rs,
OIDCIss: oidcISS,
tokenManager: tokenManager,
logger: logger,
}
}
@@ -29,9 +32,10 @@ type accountsServiceBackend struct {
settingsRoleService settings.RoleService
OIDCIss string
logger log.Logger
tokenManager token.Manager
}
func (a accountsServiceBackend) GetUserByClaims(ctx context.Context, claim, value string, withRoles bool) (*cs3.User, error) {
func (a accountsServiceBackend) GetUserByClaims(ctx context.Context, claim, value string, withRoles bool) (*cs3.User, string, error) {
var account *accounts.Account
var status int
var query string
@@ -44,38 +48,43 @@ func (a accountsServiceBackend) GetUserByClaims(ctx context.Context, claim, valu
case "id":
query = fmt.Sprintf("id eq '%s'", strings.ReplaceAll(value, "'", "''"))
default:
return nil, fmt.Errorf("invalid user by claim lookup must be 'mail', 'username' or 'id")
return nil, "", fmt.Errorf("invalid user by claim lookup must be 'mail', 'username' or 'id")
}
account, status = a.getAccount(ctx, query)
if status == http.StatusNotFound {
return nil, ErrAccountNotFound
return nil, "", ErrAccountNotFound
}
if status != 0 || account == nil {
return nil, fmt.Errorf("could not get account, got status: %d", status)
return nil, "", fmt.Errorf("could not get account, got status: %d", status)
}
if !account.AccountEnabled {
return nil, ErrAccountDisabled
return nil, "", ErrAccountDisabled
}
user := a.accountToUser(account)
token, err := a.generateToken(ctx, user)
if err != nil {
return nil, "", err
}
if !withRoles {
return user, nil
return user, token, nil
}
if err := injectRoles(ctx, user, a.settingsRoleService); err != nil {
a.logger.Warn().Err(err).Msgf("Could not load roles... continuing without")
}
return user, nil
return user, token, nil
}
// Authenticate authenticates against the accounts services and returns the user on success
func (a *accountsServiceBackend) Authenticate(ctx context.Context, username string, password string) (*cs3.User, error) {
func (a *accountsServiceBackend) Authenticate(ctx context.Context, username string, password string) (*cs3.User, string, error) {
query := fmt.Sprintf(
"login eq '%s' and password eq '%s'",
strings.ReplaceAll(username, "'", "''"),
@@ -84,23 +93,28 @@ func (a *accountsServiceBackend) Authenticate(ctx context.Context, username stri
account, status := a.getAccount(ctx, query)
if status != 0 {
return nil, fmt.Errorf("could not authenticate with username, password for user %s. Status: %d", username, status)
return nil, "", fmt.Errorf("could not authenticate with username, password for user %s. Status: %d", username, status)
}
user := a.accountToUser(account)
token, err := a.generateToken(ctx, user)
if err != nil {
return nil, "", err
}
if err := injectRoles(ctx, user, a.settingsRoleService); err != nil {
a.logger.Warn().Err(err).Msgf("Could not load roles... continuing without")
}
return user, nil
return user, token, nil
}
func (a accountsServiceBackend) CreateUserFromClaims(ctx context.Context, claims map[string]interface{}) (*cs3.User, error) {
req := &accounts.CreateAccountRequest{
Account: &accounts.Account{
CreationType: "LocalAccount",
AccountEnabled: true,
CreationType: "LocalAccount",
AccountEnabled: true,
},
}
var ok bool
@@ -144,7 +158,7 @@ func (a *accountsServiceBackend) accountToUser(account *accounts.Account) *cs3.U
Id: &cs3.UserId{
OpaqueId: account.Id,
Idp: a.OIDCIss,
Type: cs3.UserType_USER_TYPE_PRIMARY, // TODO: once we have support for other user types, this needs to be inferred
Type: cs3.UserType_USER_TYPE_PRIMARY, // TODO: once we have support for other user types, this needs to be inferred
},
Username: account.OnPremisesSamAccountName,
DisplayName: account.DisplayName,
@@ -185,6 +199,21 @@ func (a *accountsServiceBackend) getAccount(ctx context.Context, query string) (
return
}
func (a *accountsServiceBackend) generateToken(ctx context.Context, u *cs3.User) (string, error) {
s, err := scope.AddOwnerScope(nil)
if err != nil {
a.logger.Error().Err(err).Msg("could not get owner scope")
return "", err
}
token, err := a.tokenManager.MintToken(ctx, u, s)
if err != nil {
a.logger.Error().Err(err).Msg("could not mint token")
return "", err
}
return token, nil
}
func expandGroups(account *accounts.Account) []string {
groups := make([]string, len(account.MemberOf))
for i := range account.MemberOf {

View File

@@ -6,6 +6,7 @@ import (
"github.com/asim/go-micro/v3/client"
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
"github.com/cs3org/reva/pkg/token/manager/jwt"
accounts "github.com/owncloud/ocis/accounts/pkg/proto/v0"
"github.com/owncloud/ocis/ocis-pkg/log"
"github.com/owncloud/ocis/ocis-pkg/oidc"
@@ -51,7 +52,7 @@ func TestGetUserByClaimsFound(t *testing.T) {
for k := range tests {
t.Run(tests[k].id, func(t *testing.T) {
u, err := accBackend.GetUserByClaims(context.Background(), tests[k].claim, tests[k].value, true)
u, _, err := accBackend.GetUserByClaims(context.Background(), tests[k].claim, tests[k].value, true)
assert.NoError(t, err)
assert.NotNil(t, u)
@@ -64,7 +65,7 @@ func TestGetUserByClaimsFound(t *testing.T) {
func TestGetUserByClaimsNotFound(t *testing.T) {
accBackend := newAccountsBackend([]*accounts.Account{}, expectedRoles)
u, err := accBackend.GetUserByClaims(context.Background(), "mail", "foo@example.com", true)
u, _, err := accBackend.GetUserByClaims(context.Background(), "mail", "foo@example.com", true)
assert.Error(t, err)
assert.Nil(t, u)
@@ -73,7 +74,7 @@ func TestGetUserByClaimsNotFound(t *testing.T) {
func TestGetUserByClaimsInvalidClaim(t *testing.T) {
accBackend := newAccountsBackend([]*accounts.Account{}, expectedRoles)
u, err := accBackend.GetUserByClaims(context.Background(), "invalidClaimName", "efwfwfwfe", true)
u, _, err := accBackend.GetUserByClaims(context.Background(), "invalidClaimName", "efwfwfwfe", true)
assert.Nil(t, u)
assert.Error(t, err)
@@ -81,7 +82,7 @@ func TestGetUserByClaimsInvalidClaim(t *testing.T) {
func TestGetUserByClaimsDisabledAccount(t *testing.T) {
accBackend := newAccountsBackend([]*accounts.Account{{AccountEnabled: false}}, expectedRoles)
u, err := accBackend.GetUserByClaims(context.Background(), "mail", "foo@example.com", true)
u, _, err := accBackend.GetUserByClaims(context.Background(), "mail", "foo@example.com", true)
assert.Nil(t, u)
assert.Error(t, err)
@@ -90,7 +91,7 @@ func TestGetUserByClaimsDisabledAccount(t *testing.T) {
func TestAuthenticate(t *testing.T) {
accBackend := newAccountsBackend(mockAccResp, expectedRoles)
u, err := accBackend.Authenticate(context.Background(), "foo", "secret")
u, _, err := accBackend.Authenticate(context.Background(), "foo", "secret")
assert.NoError(t, err)
assert.NotNil(t, u)
@@ -99,7 +100,7 @@ func TestAuthenticate(t *testing.T) {
func TestAuthenticateFailed(t *testing.T) {
accBackend := newAccountsBackend([]*accounts.Account{}, expectedRoles)
u, err := accBackend.Authenticate(context.Background(), "foo", "secret")
u, _, err := accBackend.Authenticate(context.Background(), "foo", "secret")
assert.Nil(t, u)
assert.Error(t, err)
@@ -151,7 +152,11 @@ func assertUserMatchesAccount(t *testing.T, exp *accounts.Account, act *userv1be
func newAccountsBackend(mockAccounts []*accounts.Account, mockRoles []*settings.UserRoleAssignment) UserBackend {
accSvc, roleSvc := getAccountService(mockAccounts, nil), getRoleService(mockRoles, nil)
accBackend := NewAccountsServiceUserBackend(accSvc, roleSvc, "https://idp.example.org", log.NewLogger())
tokenManager, _ := jwt.New(map[string]interface{}{
"secret": "change-me",
"expires": int64(24 * 60 * 60),
})
accBackend := NewAccountsServiceUserBackend(accSvc, roleSvc, "https://idp.example.org", tokenManager, log.NewLogger())
zerolog.SetGlobalLevel(zerolog.Disabled)
return accBackend
}

View File

@@ -23,8 +23,8 @@ var (
// UserBackend allows the proxy to retrieve users from different user-backends (accounts-service, CS3)
type UserBackend interface {
GetUserByClaims(ctx context.Context, claim, value string, withRoles bool) (*cs3.User, error)
Authenticate(ctx context.Context, username string, password string) (*cs3.User, error)
GetUserByClaims(ctx context.Context, claim, value string, withRoles bool) (*cs3.User, string, error)
Authenticate(ctx context.Context, username string, password string) (*cs3.User, string, error)
CreateUserFromClaims(ctx context.Context, claims map[string]interface{}) (*cs3.User, error)
GetUserGroups(ctx context.Context, userID string)
}

View File

@@ -14,42 +14,48 @@ import (
)
type cs3backend struct {
userProvider cs3.UserAPIClient
settingsRoleService settings.RoleService
authProvider RevaAuthenticator
machineAuthAPIKey string
logger log.Logger
}
// NewCS3UserBackend creates a user-provider which fetches users from a CS3 UserBackend
func NewCS3UserBackend(up cs3.UserAPIClient, rs settings.RoleService, ap RevaAuthenticator, logger log.Logger) UserBackend {
func NewCS3UserBackend(rs settings.RoleService, ap RevaAuthenticator, machineAuthAPIKey string, logger log.Logger) UserBackend {
return &cs3backend{
userProvider: up,
settingsRoleService: rs,
authProvider: ap,
machineAuthAPIKey: machineAuthAPIKey,
logger: logger,
}
}
func (c *cs3backend) GetUserByClaims(ctx context.Context, claim, value string, withRoles bool) (*cs3.User, error) {
res, err := c.userProvider.GetUserByClaim(ctx, &cs3.GetUserByClaimRequest{
Claim: claim,
Value: value,
func (c *cs3backend) GetUserByClaims(ctx context.Context, claim, value string, withRoles bool) (*cs3.User, string, error) {
// We only support authentication via username for now
if claim != "username" {
return nil, "", fmt.Errorf("claim: %s not supported", claim)
}
res, err := c.authProvider.Authenticate(ctx, &gateway.AuthenticateRequest{
Type: "machine",
ClientId: value,
ClientSecret: c.machineAuthAPIKey,
})
switch {
case err != nil:
return nil, fmt.Errorf("could not get user by claim %v with value %v: %w", claim, value, err)
return nil, "", fmt.Errorf("could not get user by claim %v with value %v: %w", claim, value, err)
case res.Status.Code != rpcv1beta1.Code_CODE_OK:
if res.Status.Code == rpcv1beta1.Code_CODE_NOT_FOUND {
return nil, ErrAccountNotFound
return nil, "", ErrAccountNotFound
}
return nil, fmt.Errorf("could not get user by claim %v with value %v : %w ", claim, value, err)
return nil, "", fmt.Errorf("could not get user by claim %v with value %v : %w ", claim, value, err)
}
user := res.User
if !withRoles {
return user, nil
return user, res.Token, nil
}
var roleIDs []string
@@ -82,10 +88,10 @@ func (c *cs3backend) GetUserByClaims(ctx context.Context, claim, value string, w
user.Opaque.Map["roles"] = enc
}
return res.User, nil
return user, res.Token, nil
}
func (c *cs3backend) Authenticate(ctx context.Context, username string, password string) (*cs3.User, error) {
func (c *cs3backend) Authenticate(ctx context.Context, username string, password string) (*cs3.User, string, error) {
res, err := c.authProvider.Authenticate(ctx, &gateway.AuthenticateRequest{
Type: "basic",
ClientId: username,
@@ -94,12 +100,12 @@ func (c *cs3backend) Authenticate(ctx context.Context, username string, password
switch {
case err != nil:
return nil, fmt.Errorf("could not authenticate with username and password user: %s, %w", username, err)
return nil, "", fmt.Errorf("could not authenticate with username and password user: %s, %w", username, err)
case res.Status.Code != rpcv1beta1.Code_CODE_OK:
return nil, fmt.Errorf("could not authenticate with username and password user: %s, got code: %d", username, res.Status.Code)
return nil, "", fmt.Errorf("could not authenticate with username and password user: %s, got code: %d", username, res.Status.Code)
}
return res.User, nil
return res.User, res.Token, nil
}
func (c *cs3backend) CreateUserFromClaims(ctx context.Context, claims map[string]interface{}) (*cs3.User, error) {

View File

@@ -5,9 +5,10 @@ package test
import (
"context"
"github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
"github.com/owncloud/ocis/proxy/pkg/user/backend"
"sync"
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
"github.com/owncloud/ocis/proxy/pkg/user/backend"
)
// Ensure, that UserBackendMock does implement UserBackend.
@@ -40,13 +41,13 @@ var _ backend.UserBackend = &UserBackendMock{}
// }
type UserBackendMock struct {
// AuthenticateFunc mocks the Authenticate method.
AuthenticateFunc func(ctx context.Context, username string, password string) (*userv1beta1.User, error)
AuthenticateFunc func(ctx context.Context, username string, password string) (*userv1beta1.User, string, error)
// CreateUserFromClaimsFunc mocks the CreateUserFromClaims method.
CreateUserFromClaimsFunc func(ctx context.Context, claims map[string]interface{}) (*userv1beta1.User, error)
// GetUserByClaimsFunc mocks the GetUserByClaims method.
GetUserByClaimsFunc func(ctx context.Context, claim string, value string, withRoles bool) (*userv1beta1.User, error)
GetUserByClaimsFunc func(ctx context.Context, claim string, value string, withRoles bool) (*userv1beta1.User, string, error)
// GetUserGroupsFunc mocks the GetUserGroups method.
GetUserGroupsFunc func(ctx context.Context, userID string)
@@ -95,7 +96,7 @@ type UserBackendMock struct {
}
// Authenticate calls AuthenticateFunc.
func (mock *UserBackendMock) Authenticate(ctx context.Context, username string, password string) (*userv1beta1.User, error) {
func (mock *UserBackendMock) Authenticate(ctx context.Context, username string, password string) (*userv1beta1.User, string, error) {
if mock.AuthenticateFunc == nil {
panic("UserBackendMock.AuthenticateFunc: method is nil but UserBackend.Authenticate was just called")
}
@@ -169,7 +170,7 @@ func (mock *UserBackendMock) CreateUserFromClaimsCalls() []struct {
}
// GetUserByClaims calls GetUserByClaimsFunc.
func (mock *UserBackendMock) GetUserByClaims(ctx context.Context, claim string, value string, withRoles bool) (*userv1beta1.User, error) {
func (mock *UserBackendMock) GetUserByClaims(ctx context.Context, claim string, value string, withRoles bool) (*userv1beta1.User, string, error) {
if mock.GetUserByClaimsFunc == nil {
panic("UserBackendMock.GetUserByClaimsFunc: method is nil but UserBackend.GetUserByClaims was just called")
}