Skip to content

Commit

Permalink
Restructure
Browse files Browse the repository at this point in the history
  • Loading branch information
IljaN committed Dec 9, 2020
1 parent 86be993 commit dc13422
Show file tree
Hide file tree
Showing 8 changed files with 177 additions and 162 deletions.
8 changes: 4 additions & 4 deletions proxy/pkg/command/server.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@ package command
import (
"context"
"crypto/tls"
"github.com/owncloud/ocis/proxy/pkg/provider"
"fmt"
"github.com/owncloud/ocis/proxy/pkg/user/backend"
"net/http"
"os"
"os/signal"
Expand Down Expand Up @@ -254,16 +254,16 @@ func loadMiddlewares(ctx context.Context, l log.Logger, cfg *config.Config) alic

rolesClient := settings.NewRoleService("com.owncloud.api.settings", grpc.DefaultClient)
revaClient, err := cs3.GetGatewayServiceClient(cfg.Reva.Address)
var userProvider provider.UserProvider
var userProvider backend.UserBackend
switch cfg.AccountBackendType {
case "accounts":
userProvider = provider.NewAccountsServiceProvider(
userProvider = backend.NewAccountsServiceUserBackend(
acc.NewAccountsService("com.owncloud.api.accounts", grpc.DefaultClient),
rolesClient,
cfg.OIDC.Issuer,
)
case "cs3":
userProvider = provider.NewCS3UserProvider(revaClient, rolesClient, revaClient)
userProvider = backend.NewCS3UserBackend(revaClient, rolesClient, revaClient)
default:
l.Fatal().Msgf("Invalid accounts backend type '%s'", cfg.AccountBackendType)
}
Expand Down
4 changes: 2 additions & 2 deletions proxy/pkg/middleware/account_resolver.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package middleware

import (
"github.com/owncloud/ocis/proxy/pkg/provider"
"github.com/owncloud/ocis/proxy/pkg/user/backend"
"net/http"

tokenPkg "github.com/cs3org/reva/pkg/token"
Expand Down Expand Up @@ -39,7 +39,7 @@ type accountResolverCS3 struct {
next http.Handler
logger log.Logger
tokenManager tokenPkg.Manager
userProvider provider.UserProvider
userProvider backend.UserBackend
}

func (m accountResolverCS3) ServeHTTP(w http.ResponseWriter, req *http.Request) {
Expand Down
10 changes: 4 additions & 6 deletions proxy/pkg/middleware/basic_auth.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,12 @@
package middleware

import (
"net/http"
"strings"
"fmt"
"github.com/owncloud/ocis/ocis-pkg/log"
"github.com/owncloud/ocis/ocis-pkg/oidc"
"github.com/owncloud/ocis/proxy/pkg/provider"


"github.com/owncloud/ocis/proxy/pkg/user/backend"
"net/http"
"strings"
)

const publicFilesEndpoint = "/remote.php/dav/public-files/"
Expand Down Expand Up @@ -83,7 +81,7 @@ func BasicAuth(optionSetters ...Option) func(next http.Handler) http.Handler {
type basicAuth struct {
logger log.Logger
enabled bool
userProvider provider.UserProvider
userProvider backend.UserBackend
}

func (m basicAuth) isPublicLink(req *http.Request) bool {
Expand Down
6 changes: 3 additions & 3 deletions proxy/pkg/middleware/options.go
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
package middleware

import (
"github.com/owncloud/ocis/proxy/pkg/provider"
"github.com/owncloud/ocis/proxy/pkg/user/backend"
"net/http"
"time"

Expand All @@ -28,7 +28,7 @@ type Options struct {
// AccountsClient for resolving accounts
AccountsClient acc.AccountsService
// UP
UserProvider provider.UserProvider
UserProvider backend.UserBackend
// SettingsRoleService for the roles API in settings
SettingsRoleService settings.RoleService
// OIDCProviderFunc to lazily initialize an oidc provider, must be set for the oidc_auth middleware
Expand Down Expand Up @@ -170,7 +170,7 @@ func TokenCacheTTL(ttl time.Duration) Option {
}

// UserProvider sets the accounts user provider
func UserProvider(up provider.UserProvider) Option {
func UserProvider(up backend.UserBackend) Option {
return func(o *Options) {
o.UserProvider = up
}
Expand Down
4 changes: 2 additions & 2 deletions proxy/pkg/middleware/signed_url_auth.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ import (
"errors"
"fmt"
revauser "github.com/cs3org/reva/pkg/user"
"github.com/owncloud/ocis/proxy/pkg/provider"
"github.com/owncloud/ocis/proxy/pkg/user/backend"
"net/http"
"net/url"
"strings"
Expand Down Expand Up @@ -38,7 +38,7 @@ type signedURLAuth struct {
next http.Handler
logger log.Logger
preSignedURLConfig config.PreSignedURL
userProvider provider.UserProvider
userProvider backend.UserBackend
store store.StoreService
}

Expand Down
163 changes: 18 additions & 145 deletions proxy/pkg/provider/user.go → proxy/pkg/user/backend/accounts.go
Original file line number Diff line number Diff line change
@@ -1,129 +1,33 @@
package provider
package backend

import (
"context"
"encoding/json"
"fmt"
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
cs3 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
rpcv1beta1 "github.com/cs3org/go-cs3apis/cs3/rpc/v1beta1"
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
accounts "github.com/owncloud/ocis/accounts/pkg/proto/v0"
settings "github.com/owncloud/ocis/settings/pkg/proto/v0"
"google.golang.org/grpc"
"net/http"
"strconv"
"strings"
)

// UserProvider allows the proxy to retrieve users from different user-backends (accounts-service, CS3)
type UserProvider interface {
GetUserByClaims(ctx context.Context, claim, value string, withRoles bool) (*cs3.User, error)
Authenticate(ctx context.Context, username string, password string) (*cs3.User, error)
GetUserGroups(ctx context.Context, userID string)
}

// RevaAuthenticator helper interface to mock auth-method from reva gateway-client.
type RevaAuthenticator interface {
Authenticate(ctx context.Context, in *gateway.AuthenticateRequest, opts ...grpc.CallOption) (*gateway.AuthenticateResponse, error)
}

// NewCS3UserProvider creates a user-provider which fetches users from a CS3 Backend
func NewCS3UserProvider(up cs3.UserAPIClient, rs settings.RoleService, ap RevaAuthenticator) UserProvider {
return &cs3provider{
userProvider: up,
settingsRoleService: rs,
authProvider: ap,
}
}

type cs3provider struct {
userProvider cs3.UserAPIClient
settingsRoleService settings.RoleService
authProvider RevaAuthenticator
}

func (c cs3provider) GetUserByClaims(ctx context.Context, claim, value string, withRoles bool) (*cs3.User, error) {
res, err := c.userProvider.GetUserByClaim(ctx, &cs3.GetUserByClaimRequest{
Claim: claim,
Value: value,
})

switch {
case err != nil:
return nil, fmt.Errorf("could not get user by claim %v with value %v", claim, value)
case res.Status.Code != rpcv1beta1.Code_CODE_OK:
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
}

roleIDs, err := loadRolesIDs(ctx, user.Id.OpaqueId, c.settingsRoleService)
if err != nil {
//TODO: LOG
_ = 1
}

if len(roleIDs) == 0 {
return user, nil

}

enc, err := encodeRoleIDs(roleIDs)
if err != nil {
//TODO: LOG
_ = 1
}

user.Opaque = &types.Opaque{
Map: map[string]*types.OpaqueEntry{
"roles": enc,
},
}

return res.User, nil
}

func (c *cs3provider) Authenticate(ctx context.Context, username string, password string) (*cs3.User, error) {
res, err := c.authProvider.Authenticate(ctx, &gateway.AuthenticateRequest{
ClientId: username,
ClientSecret: password,
})

switch {
case err != nil:
return nil, fmt.Errorf("could not authenticate with username and password user: %s", username)
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 res.User, nil
}

func (c cs3provider) GetUserGroups(ctx context.Context, userID string) {
panic("implement me")
}

// NewAccountsServiceProvider creates a user-provider which fetches users from the ocis accounts-service
func NewAccountsServiceProvider(ac accounts.AccountsService, rs settings.RoleService, oidcISS string) UserProvider {
return &accountsServiceProvider{
// NewAccountsServiceUserBackend creates a user-provider which fetches users from the ocis accounts-service
func NewAccountsServiceUserBackend(ac accounts.AccountsService, rs settings.RoleService, oidcISS string) UserBackend {
return &accountsServiceBackend{
accountsClient: ac,
settingsRoleService: rs,
OIDCIss: oidcISS,
}
}

type accountsServiceProvider struct {
type accountsServiceBackend struct {
accountsClient accounts.AccountsService
settingsRoleService settings.RoleService
OIDCIss string
}

func (a accountsServiceProvider) 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, error) {
var account *accounts.Account
var status int
var query string
Expand Down Expand Up @@ -184,16 +88,7 @@ func (a accountsServiceProvider) GetUserByClaims(ctx context.Context, claim, val

}

func expandGroups(account *accounts.Account) []string {
groups := make([]string, len(account.MemberOf))
for i := range account.MemberOf {
// reva needs the unix group name
groups[i] = account.MemberOf[i].OnPremisesSamAccountName
}
return groups
}

func (a *accountsServiceProvider) Authenticate(ctx context.Context, username string, password string) (*cs3.User, error) {
func (a *accountsServiceBackend) Authenticate(ctx context.Context, username string, password string) (*cs3.User, error) {
query := fmt.Sprintf(
"login eq '%s' and password eq '%s'",
strings.ReplaceAll(username, "'", "''"),
Expand Down Expand Up @@ -234,11 +129,11 @@ func (a *accountsServiceProvider) Authenticate(ctx context.Context, username str
return user, nil
}

func (a accountsServiceProvider) GetUserGroups(ctx context.Context, userID string) {
func (a accountsServiceBackend) GetUserGroups(ctx context.Context, userID string) {
panic("implement me")
}

func (a accountsServiceProvider) getAccount(ctx context.Context, query string) (account *accounts.Account, status int) {
func (a *accountsServiceBackend) getAccount(ctx context.Context, query string) (account *accounts.Account, status int) {
resp, err := a.accountsClient.ListAccounts(ctx, &accounts.ListAccountsRequest{
Query: query,
PageSize: 2,
Expand Down Expand Up @@ -266,6 +161,15 @@ func (a accountsServiceProvider) getAccount(ctx context.Context, query string) (
return
}

func expandGroups(account *accounts.Account) []string {
groups := make([]string, len(account.MemberOf))
for i := range account.MemberOf {
// reva needs the unix group name
groups[i] = account.MemberOf[i].OnPremisesSamAccountName
}
return groups
}

func lazyLoadRoles(ctx context.Context, u *cs3.User, ss settings.RoleService) error {
roleIDs, err := loadRolesIDs(ctx, u.Id.OpaqueId, ss)
if err != nil {
Expand All @@ -291,35 +195,4 @@ func lazyLoadRoles(ctx context.Context, u *cs3.User, ss settings.RoleService) er
}

return nil

}

func loadRolesIDs(ctx context.Context, opaqueUserID string, rs settings.RoleService) ([]string, error) {
req := &settings.ListRoleAssignmentsRequest{AccountUuid: opaqueUserID}
assignmentResponse, err := rs.ListRoleAssignments(ctx, req)

if err != nil {
return nil, err
}

roleIDs := make([]string, 0)

for _, assignment := range assignmentResponse.Assignments {
roleIDs = append(roleIDs, assignment.RoleId)
}

return roleIDs, nil
}

func encodeRoleIDs(roleIDs []string) (*types.OpaqueEntry, error) {
roleIDsJSON, err := json.Marshal(roleIDs)
if err != nil {
return nil, err
}

return &types.OpaqueEntry{
Decoder: "json",
Value: roleIDsJSON,
}, nil

}
53 changes: 53 additions & 0 deletions proxy/pkg/user/backend/backend.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package backend

import (
"context"
"encoding/json"
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
cs3 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
types "github.com/cs3org/go-cs3apis/cs3/types/v1beta1"
settings "github.com/owncloud/ocis/settings/pkg/proto/v0"
"google.golang.org/grpc"
)

// 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)
GetUserGroups(ctx context.Context, userID string)
}

// RevaAuthenticator helper interface to mock auth-method from reva gateway-client.
type RevaAuthenticator interface {
Authenticate(ctx context.Context, in *gateway.AuthenticateRequest, opts ...grpc.CallOption) (*gateway.AuthenticateResponse, error)
}

func loadRolesIDs(ctx context.Context, opaqueUserID string, rs settings.RoleService) ([]string, error) {
req := &settings.ListRoleAssignmentsRequest{AccountUuid: opaqueUserID}
assignmentResponse, err := rs.ListRoleAssignments(ctx, req)

if err != nil {
return nil, err
}

roleIDs := make([]string, 0)

for _, assignment := range assignmentResponse.Assignments {
roleIDs = append(roleIDs, assignment.RoleId)
}

return roleIDs, nil
}

func encodeRoleIDs(roleIDs []string) (*types.OpaqueEntry, error) {
roleIDsJSON, err := json.Marshal(roleIDs)
if err != nil {
return nil, err
}

return &types.OpaqueEntry{
Decoder: "json",
Value: roleIDsJSON,
}, nil

}
Loading

0 comments on commit dc13422

Please sign in to comment.