Files
opencloud/services/proxy/pkg/middleware/options.go
Ralf Haferkamp cb8934081f proxy(oidc): Emit a UserSignedIn event on new session
Every time the OIDC middleware sees a new access token (i.e when it needs
to update the userinfo cache) we consider that as a new login. In this case
the middleware add a new flag to the context, which is then used by the
accountresolver middleware to publish a UserSignedIn event.
The event needs to be sent by the accountresolver middleware, because only
at that point we know the user id of the user that just logged in.

(It would probably makes sense to merge the auth and account middleware into a
single component to avoid passing flags around via context)
2024-09-17 16:02:47 +02:00

248 lines
7.3 KiB
Go

package middleware
import (
"net/http"
"time"
gateway "github.com/cs3org/go-cs3apis/cs3/gateway/v1beta1"
"github.com/cs3org/reva/v2/pkg/events"
"github.com/cs3org/reva/v2/pkg/rgrpc/todo/pool"
"github.com/owncloud/ocis/v2/ocis-pkg/log"
"github.com/owncloud/ocis/v2/ocis-pkg/oidc"
policiessvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/policies/v0"
settingssvc "github.com/owncloud/ocis/v2/protogen/gen/ocis/services/settings/v0"
"github.com/owncloud/ocis/v2/services/proxy/pkg/config"
"github.com/owncloud/ocis/v2/services/proxy/pkg/user/backend"
"github.com/owncloud/ocis/v2/services/proxy/pkg/userroles"
"go-micro.dev/v4/store"
"go.opentelemetry.io/otel/trace"
)
// Option defines a single option function.
type Option func(o *Options)
// Options defines the available options for this package.
type Options struct {
// Logger to use for logging, must be set
Logger log.Logger
// PolicySelectorConfig for using the policy selector
PolicySelector config.PolicySelector
// HTTPClient to use for communication with the oidcAuth provider
HTTPClient *http.Client
// UserProvider backend to use for resolving User
UserProvider backend.UserBackend
// UserRoleAssigner to user for assign a users default role
UserRoleAssigner userroles.UserRoleAssigner
// SettingsRoleService for the roles API in settings
SettingsRoleService settingssvc.RoleService
// PoliciesProviderService for policy evaluation
PoliciesProviderService policiessvc.PoliciesProviderService
// OIDCClient to fetch user info and verify tokens, must be set for the oidc_auth middleware
OIDCClient oidc.OIDCClient
// OIDCIss is the oidcAuth-issuer
OIDCIss string
// RevaGatewaySelector to send requests to the reva gateway
RevaGatewaySelector pool.Selectable[gateway.GatewayAPIClient]
// PreSignedURLConfig to configure the middleware
PreSignedURLConfig config.PreSignedURL
// UserOIDCClaim to read from the oidc claims
UserOIDCClaim string
// UserCS3Claim to use when looking up a user in the CS3 API
UserCS3Claim string
// AutoprovisionAccounts when an accountResolver does not exist.
AutoprovisionAccounts bool
// EnableBasicAuth to allow basic auth
EnableBasicAuth bool
// DefaultAccessTokenTTL is used to calculate the expiration when an access token has no expiration set
DefaultAccessTokenTTL time.Duration
// UserInfoCache sets the access token cache store
UserInfoCache store.Store
// CredentialsByUserAgent sets the auth challenges on a per user-agent basis
CredentialsByUserAgent map[string]string
// AccessTokenVerifyMethod configures how access_tokens should be verified but the oidc_auth middleware.
// Possible values currently: "jwt" and "none"
AccessTokenVerifyMethod string
// JWKS sets the options for fetching the JWKS from the IDP
JWKS config.JWKS
// RoleQuotas hold userid:quota mappings. These will be used when provisioning new users.
// The users will get as much quota as is set for their role.
RoleQuotas map[string]uint64
// TraceProvider sets the tracing provider.
TraceProvider trace.TracerProvider
// SkipUserInfo prevents the oidc middleware from querying the userinfo endpoint and read any claims directly from the access token instead
SkipUserInfo bool
EventsPublisher events.Publisher
}
// newOptions initializes the available default options.
func newOptions(opts ...Option) Options {
opt := Options{}
for _, o := range opts {
o(&opt)
}
return opt
}
// Logger provides a function to set the logger option.
func Logger(l log.Logger) Option {
return func(o *Options) {
o.Logger = l
}
}
// PolicySelectorConfig provides a function to set the policy selector config option.
func PolicySelectorConfig(cfg config.PolicySelector) Option {
return func(o *Options) {
o.PolicySelector = cfg
}
}
// HTTPClient provides a function to set the http client config option.
func HTTPClient(c *http.Client) Option {
return func(o *Options) {
o.HTTPClient = c
}
}
// SettingsRoleService provides a function to set the role service option.
func SettingsRoleService(rc settingssvc.RoleService) Option {
return func(o *Options) {
o.SettingsRoleService = rc
}
}
// PoliciesProviderService provides a function to set the policies provider option.
func PoliciesProviderService(pps policiessvc.PoliciesProviderService) Option {
return func(o *Options) {
o.PoliciesProviderService = pps
}
}
// OIDCClient provides a function to set the oidc client option.
func OIDCClient(val oidc.OIDCClient) Option {
return func(o *Options) {
o.OIDCClient = val
}
}
// OIDCIss sets the oidcAuth issuer url
func OIDCIss(iss string) Option {
return func(o *Options) {
o.OIDCIss = iss
}
}
// CredentialsByUserAgent sets UserAgentChallenges.
func CredentialsByUserAgent(v map[string]string) Option {
return func(o *Options) {
o.CredentialsByUserAgent = v
}
}
// WithRevaGatewaySelector provides a function to set the reva gateway service selector option.
func WithRevaGatewaySelector(val pool.Selectable[gateway.GatewayAPIClient]) Option {
return func(o *Options) {
o.RevaGatewaySelector = val
}
}
// PreSignedURLConfig provides a function to set the PreSignedURL config
func PreSignedURLConfig(cfg config.PreSignedURL) Option {
return func(o *Options) {
o.PreSignedURLConfig = cfg
}
}
// UserOIDCClaim provides a function to set the UserClaim config
func UserOIDCClaim(val string) Option {
return func(o *Options) {
o.UserOIDCClaim = val
}
}
// UserCS3Claim provides a function to set the UserClaimType config
func UserCS3Claim(val string) Option {
return func(o *Options) {
o.UserCS3Claim = val
}
}
// AutoprovisionAccounts provides a function to set the AutoprovisionAccounts config
func AutoprovisionAccounts(val bool) Option {
return func(o *Options) {
o.AutoprovisionAccounts = val
}
}
// EnableBasicAuth provides a function to set the EnableBasicAuth config
func EnableBasicAuth(enableBasicAuth bool) Option {
return func(o *Options) {
o.EnableBasicAuth = enableBasicAuth
}
}
// DefaultAccessTokenTTL provides a function to set the DefaultAccessTokenTTL
func DefaultAccessTokenTTL(ttl time.Duration) Option {
return func(o *Options) {
o.DefaultAccessTokenTTL = ttl
}
}
// UserInfoCache provides a function to set the UserInfoCache
func UserInfoCache(val store.Store) Option {
return func(o *Options) {
o.UserInfoCache = val
}
}
// UserProvider sets the accounts user provider
func UserProvider(up backend.UserBackend) Option {
return func(o *Options) {
o.UserProvider = up
}
}
// UserRoleAssigner sets the mechanism for assigning the default user roles
func UserRoleAssigner(ra userroles.UserRoleAssigner) Option {
return func(o *Options) {
o.UserRoleAssigner = ra
}
}
// AccessTokenVerifyMethod set the mechanism for access token verification
func AccessTokenVerifyMethod(method string) Option {
return func(o *Options) {
o.AccessTokenVerifyMethod = method
}
}
// RoleQuotas sets the role quota mapping setting
func RoleQuotas(roleQuotas map[string]uint64) Option {
return func(o *Options) {
o.RoleQuotas = roleQuotas
}
}
// TraceProvider sets the tracing provider.
func TraceProvider(tp trace.TracerProvider) Option {
return func(o *Options) {
o.TraceProvider = tp
}
}
// SkipUserInfo sets the skipUserInfo flag.
func SkipUserInfo(val bool) Option {
return func(o *Options) {
o.SkipUserInfo = val
}
}
// EventsPublisher sets the events publisher.
func EventsPublisher(ep events.Publisher) Option {
return func(o *Options) {
o.EventsPublisher = ep
}
}