Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 14 additions & 14 deletions users/client/cache.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,18 +38,18 @@ type CachingClientConfig struct {
}

type cachingClient struct {
users.UsersClient
users.AuthServiceClient
probeCredCache gcache.Cache
orgCredCache gcache.Cache
userCache gcache.Cache
}

func newCachingClient(cfg CachingClientConfig, client users.UsersClient) *cachingClient {
func newCachingClient(cfg CachingClientConfig, client users.AuthServiceClient) *cachingClient {
return &cachingClient{
UsersClient: client,
probeCredCache: gcache.New(cfg.ProbeCredCacheSize).LRU().Expiration(cfg.ProbeCredCacheExpiration).Build(),
orgCredCache: gcache.New(cfg.OrgCredCacheSize).LRU().Expiration(cfg.OrgCredCacheExpiration).Build(),
userCache: gcache.New(cfg.UserCacheSize).LRU().Expiration(cfg.UserCacheExpiration).Build(),
AuthServiceClient: client,
probeCredCache: gcache.New(cfg.ProbeCredCacheSize).LRU().Expiration(cfg.ProbeCredCacheExpiration).Build(),
orgCredCache: gcache.New(cfg.OrgCredCacheSize).LRU().Expiration(cfg.OrgCredCacheExpiration).Build(),
userCache: gcache.New(cfg.UserCacheSize).LRU().Expiration(cfg.UserCacheExpiration).Build(),
}
}

Expand All @@ -59,9 +59,9 @@ type cacheValue struct {
}

// LookupOrg authenticates a cookie for access to an org by extenal ID.
func (c *cachingClient) LookupOrg(ctx context.Context, in *users.LookupOrgRequest, opts ...grpc.CallOption) (*users.LookupOrgResponse, error) {
func (c *cachingClient) AuthUserForOrg(ctx context.Context, in *users.LookupOrgRequest, opts ...grpc.CallOption) (*users.LookupOrgResponse, error) {
if c.orgCredCache == nil {
return c.UsersClient.LookupOrg(ctx, in, opts...)
return c.AuthServiceClient.AuthUserForOrg(ctx, in, opts...)
}

org, err := c.orgCredCache.Get(*in)
Expand All @@ -70,17 +70,17 @@ func (c *cachingClient) LookupOrg(ctx context.Context, in *users.LookupOrgReques
return org.(cacheValue).out.(*users.LookupOrgResponse), org.(cacheValue).err
}

out, err := c.UsersClient.LookupOrg(ctx, in, opts...)
out, err := c.AuthServiceClient.AuthUserForOrg(ctx, in, opts...)
if err == nil || isErrorCachable(err) {
c.orgCredCache.Set(*in, cacheValue{out, err})
}
return out, err
}

// LookupUsingToken authenticates a token for access to an org.
func (c *cachingClient) LookupUsingToken(ctx context.Context, in *users.LookupUsingTokenRequest, opts ...grpc.CallOption) (*users.LookupUsingTokenResponse, error) {
func (c *cachingClient) AuthTokenForOrg(ctx context.Context, in *users.LookupUsingTokenRequest, opts ...grpc.CallOption) (*users.LookupUsingTokenResponse, error) {
if c.probeCredCache == nil {
return c.UsersClient.LookupUsingToken(ctx, in, opts...)
return c.AuthServiceClient.AuthTokenForOrg(ctx, in, opts...)
}

org, err := c.probeCredCache.Get(*in)
Expand All @@ -89,7 +89,7 @@ func (c *cachingClient) LookupUsingToken(ctx context.Context, in *users.LookupUs
return org.(cacheValue).out.(*users.LookupUsingTokenResponse), org.(cacheValue).err
}

out, err := c.UsersClient.LookupUsingToken(ctx, in, opts...)
out, err := c.AuthServiceClient.AuthTokenForOrg(ctx, in, opts...)
if err == nil || isErrorCachable(err) {
c.probeCredCache.Set(*in, cacheValue{out, err})
}
Expand All @@ -98,7 +98,7 @@ func (c *cachingClient) LookupUsingToken(ctx context.Context, in *users.LookupUs

func (c *cachingClient) GetUser(ctx context.Context, in *users.GetUserRequest, opts ...grpc.CallOption) (*users.GetUserResponse, error) {
if c.userCache == nil {
return c.UsersClient.GetUser(ctx, in, opts...)
return c.AuthServiceClient.GetUser(ctx, in, opts...)
}

out, err := c.userCache.Get(*in)
Expand All @@ -107,7 +107,7 @@ func (c *cachingClient) GetUser(ctx context.Context, in *users.GetUserRequest, o
return out.(*users.GetUserResponse), nil
}

out, err = c.UsersClient.GetUser(ctx, in, opts...)
out, err = c.AuthServiceClient.GetUser(ctx, in, opts...)
if err == nil {
c.userCache.Set(*in, out)
}
Expand Down
26 changes: 14 additions & 12 deletions users/client/client.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,31 +12,33 @@ import (
)

// New is a factory for Authenticators
func New(kind, address string, opts CachingClientConfig) (users.UsersClient, error) {
var client users.UsersClient
func New(kind, address string, opts CachingClientConfig) (users.UsersClient, users.AuthServiceClient, error) {
var usersClient users.UsersClient
var authClient users.AuthServiceClient
var err error
switch kind {
case "mock":
client = MockClient{}
usersClient = MockClient{}
authClient = MockAuthClient{}
case "grpc":
client, err = newGRPCClient(address)
usersClient, authClient, err = newGRPCClient(address)
if err != nil {
return nil, err
return nil, nil, err
}
default:
log.Fatal("Incorrect authenticator type: ", kind)
return nil, nil
return nil, nil, nil
}
if opts.CacheEnabled {
client = newCachingClient(opts, client)
authClient = newCachingClient(opts, authClient)
}
return client, nil
return usersClient, authClient, nil
}

func newGRPCClient(address string) (users.UsersClient, error) {
func newGRPCClient(address string) (users.UsersClient, users.AuthServiceClient, error) {
address, dialOptions, err := httpgrpc_server.ParseURL(address)
if err != nil {
return nil, err
return nil, nil, err
}

dialOptions = append(dialOptions,
Expand All @@ -51,7 +53,7 @@ func newGRPCClient(address string) (users.UsersClient, error) {
dialOptions...,
)
if err != nil {
return nil, err
return nil, nil, err
}
return users.NewUsersClient(conn), nil
return users.NewUsersClient(conn), users.NewAuthServiceClient(conn), nil
}
21 changes: 11 additions & 10 deletions users/client/middleware.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,8 +44,8 @@ const (
// AuthOrgMiddleware is a middleware.Interface for authentication organisations based on the
// cookie and an org name in the path
type AuthOrgMiddleware struct {
UsersClient users.UsersClient
OrgExternalID func(*http.Request) (string, bool)
AuthServiceClient users.AuthServiceClient
OrgExternalID func(*http.Request) (string, bool)

UserIDHeader string
FeatureFlagsHeader string
Expand All @@ -72,7 +72,7 @@ func (a AuthOrgMiddleware) Wrap(next http.Handler) http.Handler {
return
}

response, err := a.UsersClient.LookupOrg(ctx, &users.LookupOrgRequest{
response, err := a.AuthServiceClient.AuthUserForOrg(ctx, &users.LookupOrgRequest{
Cookie: authCookie.Value,
OrgExternalID: orgExternalID,
AuthorizeFor: a.AuthorizeFor,
Expand Down Expand Up @@ -103,7 +103,7 @@ func (a AuthOrgMiddleware) Wrap(next http.Handler) http.Handler {

// AuthProbeMiddleware is a middleware.Interface for authentication probes based on the headers
type AuthProbeMiddleware struct {
UsersClient users.UsersClient
AuthServiceClient users.AuthServiceClient
FeatureFlagsHeader string
RequireFeatureFlags []string
AuthorizeFor users.AuthorizedAction
Expand All @@ -121,7 +121,7 @@ func (a AuthProbeMiddleware) Wrap(next http.Handler) http.Handler {
return
}

response, err := a.UsersClient.LookupUsingToken(ctx, &users.LookupUsingTokenRequest{
response, err := a.AuthServiceClient.AuthTokenForOrg(ctx, &users.LookupUsingTokenRequest{
Token: token,
AuthorizeFor: a.AuthorizeFor,
})
Expand Down Expand Up @@ -149,7 +149,7 @@ func (a AuthProbeMiddleware) Wrap(next http.Handler) http.Handler {

// AuthAdminMiddleware is a middleware.Interface for authentication probes based on the headers
type AuthAdminMiddleware struct {
UsersClient users.UsersClient
AuthServiceClient users.AuthServiceClient
}

// Wrap implements middleware.Interface
Expand All @@ -164,7 +164,7 @@ func (a AuthAdminMiddleware) Wrap(next http.Handler) http.Handler {
return
}

response, err := a.UsersClient.LookupAdmin(ctx, &users.LookupAdminRequest{
response, err := a.AuthServiceClient.AuthUserForAdmin(ctx, &users.LookupAdminRequest{
Cookie: authCookie.Value,
})
if err != nil {
Expand All @@ -182,7 +182,7 @@ func (a AuthAdminMiddleware) Wrap(next http.Handler) http.Handler {
// AuthUserMiddleware is a middleware.Interface for authentication users based on the
// cookie (and not to any specific org)
type AuthUserMiddleware struct {
UsersClient users.UsersClient
AuthServiceClient users.AuthServiceClient
UserIDHeader string
RequireFeatureFlags []string
}
Expand All @@ -198,7 +198,7 @@ func (a AuthUserMiddleware) Wrap(next http.Handler) http.Handler {
return
}

response, err := a.UsersClient.LookupUser(ctx, &users.LookupUserRequest{
response, err := a.AuthServiceClient.AuthUser(ctx, &users.LookupUserRequest{
Cookie: authCookie.Value,
})

Expand Down Expand Up @@ -352,6 +352,7 @@ func validateGCPExternalAccountID(externalAccountID string) (string, error) {
// WebhooksMiddleware is a middleware.Interface for authentication request based
// on the webhook secret (and signing key if one exists).
type WebhooksMiddleware struct {
AuthServiceClient users.AuthServiceClient
UsersClient users.UsersClient
WebhooksIntegrationTypeHeader string
}
Expand All @@ -362,7 +363,7 @@ func (a WebhooksMiddleware) Wrap(next http.Handler) http.Handler {
secretID := mux.Vars(r)["secretID"]

// Verify the secretID
response, err := a.UsersClient.LookupOrganizationWebhookUsingSecretID(r.Context(), &users.LookupOrganizationWebhookUsingSecretIDRequest{
response, err := a.AuthServiceClient.AuthWebhookSecretForOrg(r.Context(), &users.LookupOrganizationWebhookUsingSecretIDRequest{
SecretID: secretID,
})
if err != nil {
Expand Down
66 changes: 51 additions & 15 deletions users/client/mock_client.go
Original file line number Diff line number Diff line change
@@ -1,44 +1,58 @@
package client

import (
"errors"

"golang.org/x/net/context"
"google.golang.org/grpc"

"github.com/weaveworks/service/users"
)

// MockClient is a mock usersClient that can be used in testing
type MockClient struct{}
// MockAuthClient is a mock users.AuthServiceClient that can be used in testing
type MockAuthClient struct{}

// LookupOrg authenticates a cookie for access to an org by external ID.
func (MockClient) LookupOrg(ctx context.Context, in *users.LookupOrgRequest, opts ...grpc.CallOption) (*users.LookupOrgResponse, error) {
var _ users.AuthServiceClient = &MockAuthClient{}

// AuthUserForOrg authenticates a cookie for access to an org by external ID.
func (MockAuthClient) AuthUserForOrg(ctx context.Context, in *users.LookupOrgRequest, opts ...grpc.CallOption) (*users.LookupOrgResponse, error) {
return &users.LookupOrgResponse{
OrganizationID: "mockID",
UserID: "mockUserID",
}, nil
}

// LookupUsingToken authenticates a token for access to an org.
func (MockClient) LookupUsingToken(ctx context.Context, in *users.LookupUsingTokenRequest, opts ...grpc.CallOption) (*users.LookupUsingTokenResponse, error) {
// AuthTokenForOrg authenticates a token for access to an org.
func (MockAuthClient) AuthTokenForOrg(ctx context.Context, in *users.LookupUsingTokenRequest, opts ...grpc.CallOption) (*users.LookupUsingTokenResponse, error) {
return &users.LookupUsingTokenResponse{
OrganizationID: "mockID",
}, nil
}

// LookupAdmin authenticates a cookie for admin access.
func (MockClient) LookupAdmin(ctx context.Context, in *users.LookupAdminRequest, opts ...grpc.CallOption) (*users.LookupAdminResponse, error) {
// AuthUserForAdmin authenticates a cookie for admin access.
func (MockAuthClient) AuthUserForAdmin(ctx context.Context, in *users.LookupAdminRequest, opts ...grpc.CallOption) (*users.LookupAdminResponse, error) {
return &users.LookupAdminResponse{
AdminID: "mockUserID",
}, nil
}

// LookupUser authenticates a cookie.
func (MockClient) LookupUser(ctx context.Context, in *users.LookupUserRequest, opts ...grpc.CallOption) (*users.LookupUserResponse, error) {
// AuthUser authenticates a cookie.
func (MockAuthClient) AuthUser(ctx context.Context, in *users.LookupUserRequest, opts ...grpc.CallOption) (*users.LookupUserResponse, error) {
return &users.LookupUserResponse{
UserID: "mockUserID",
}, nil
}

// AuthWebhookSecretForOrg gets the webhook given the external org ID and the secret ID of the webhook.
func (MockAuthClient) AuthWebhookSecretForOrg(ctx context.Context, in *users.LookupOrganizationWebhookUsingSecretIDRequest, opts ...grpc.CallOption) (*users.LookupOrganizationWebhookUsingSecretIDResponse, error) {
return &users.LookupOrganizationWebhookUsingSecretIDResponse{}, nil
}

// MockClient is a mock usersClient that can be used in testing
type MockClient struct{}

var _ users.UsersClient = &MockClient{}

// GetOrganizations gets the organizations for a user
func (MockClient) GetOrganizations(ctx context.Context, in *users.GetOrganizationsRequest, opts ...grpc.CallOption) (*users.GetOrganizationsResponse, error) {
return &users.GetOrganizationsResponse{}, nil
Expand Down Expand Up @@ -125,12 +139,34 @@ func (MockClient) GetSummary(ctx context.Context, in *users.Empty, opts ...grpc.
return &users.Summary{}, nil
}

// LookupOrganizationWebhookUsingSecretID gets the webhook given the external org ID and the secret ID of the webhook.
func (MockClient) LookupOrganizationWebhookUsingSecretID(ctx context.Context, in *users.LookupOrganizationWebhookUsingSecretIDRequest, opts ...grpc.CallOption) (*users.LookupOrganizationWebhookUsingSecretIDResponse, error) {
return &users.LookupOrganizationWebhookUsingSecretIDResponse{}, nil
}

// SetOrganizationWebhookFirstSeenAt sets the FirstSeenAt field on the webhook to the current time
func (MockClient) SetOrganizationWebhookFirstSeenAt(ctx context.Context, in *users.SetOrganizationWebhookFirstSeenAtRequest, opts ...grpc.CallOption) (*users.SetOrganizationWebhookFirstSeenAtResponse, error) {
return &users.SetOrganizationWebhookFirstSeenAtResponse{}, nil
}

var errLegacy = errors.New("Legacy mocks methods, to be removed once we remove these from the proto file")

// LookupOrg authenticates a cookie for access to an org by external ID.
func (MockClient) LookupOrg(ctx context.Context, in *users.LookupOrgRequest, opts ...grpc.CallOption) (*users.LookupOrgResponse, error) {
return nil, errLegacy
}

// LookupUsingToken authenticates a token for access to an org.
func (MockClient) LookupUsingToken(ctx context.Context, in *users.LookupUsingTokenRequest, opts ...grpc.CallOption) (*users.LookupUsingTokenResponse, error) {
return nil, errLegacy
}

// LookupAdmin authenticates a cookie for admin access.
func (MockClient) LookupAdmin(ctx context.Context, in *users.LookupAdminRequest, opts ...grpc.CallOption) (*users.LookupAdminResponse, error) {
return nil, errLegacy
}

// LookupUser authenticates a cookie.
func (MockClient) LookupUser(ctx context.Context, in *users.LookupUserRequest, opts ...grpc.CallOption) (*users.LookupUserResponse, error) {
return nil, errLegacy
}

// LookupOrganizationWebhookUsingSecretID gets the webhook given the external org ID and the secret ID of the webhook.
func (MockClient) LookupOrganizationWebhookUsingSecretID(ctx context.Context, in *users.LookupOrganizationWebhookUsingSecretIDRequest, opts ...grpc.CallOption) (*users.LookupOrganizationWebhookUsingSecretIDResponse, error) {
return nil, errLegacy
}
Loading