Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(274)

Unified Diff: server/auth/auth.go

Issue 2830443003: auth: Refactor how authentication methods are passed to server/auth library. (Closed)
Patch Set: Created 3 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: server/auth/auth.go
diff --git a/server/auth/auth.go b/server/auth/auth.go
index 706d7fc9ea716b398442edbab85c25fe40501423..b64842e98017db1e29e6d61be6052d55c3a6510a 100644
--- a/server/auth/auth.go
+++ b/server/auth/auth.go
@@ -36,11 +36,16 @@ var (
ErrIPNotWhitelisted = errors.New("auth: IP is not whitelisted")
)
-// Method implements particular kind of low level authentication mechanism for
-// incoming requests. It may also optionally implement UsersAPI (if the method
-// support login and logout URLs). Use type sniffing to figure out.
+// Method implements a particular kind of low-level authentication mechanism.
+//
+// It may also optionally implement UsersAPI (if the method support login and
+// logout URLs).
+//
+// Methods are not usually used directly, but passed to Authenticator{...} that
+// knows how to apply them.
type Method interface {
// Authenticate extracts user information from the incoming request.
+ //
// It returns:
// * (*User, nil) on success.
// * (nil, nil) if the method is not applicable.
@@ -88,22 +93,25 @@ type User struct {
ClientID string
}
-// Authenticator perform authentication of incoming requests. It is stateless
-// object that just describes what methods to try when authenticating current
-// request. It is fine to create it on per-request basis.
-type Authenticator []Method
-
-// Authenticate authenticates incoming requests and returns new context.Context
-// with State stored into it. Returns error if credentials are provided, but
-// invalid. If no credentials are provided (i.e. the request is anonymous),
-// finishes successfully, but in that case State.Identity() will return
-// AnonymousIdentity.
-func (a Authenticator) Authenticate(c context.Context, r *http.Request) (context.Context, error) {
- report := durationReporter(c, authenticateDuration)
+// Authenticator perform authentication of incoming requests.
+//
+// It is stateless object configured with a list of methods to try when
+// authenticating incoming requests. It implements Authenticate method that
+// performs high-level authentication logic using the provided list of low-level
+// auth methods.
+//
+// Usually used through Authenticate(...) middelware.
+type Authenticator struct {
+ Methods []Method // a list of authentication methods to try
+}
- // Make it known to handlers what authentication methods are allowed.
- // This is important for LoginURL and LogoutURL functions.
- c = SetAuthenticator(c, a)
+// Authenticate authenticates the requests and adds State into the context.
+//
+// Returns an error if credentials are provided, but invalid. If no credentials
+// are provided (i.e. the request is anonymous), finishes successfully, but in
+// that case State.Identity() returns AnonymousIdentity.
+func (a *Authenticator) Authenticate(c context.Context, r *http.Request) (context.Context, error) {
+ report := durationReporter(c, authenticateDuration)
// We will need working DB factory below to check IP whitelist.
cfg := GetConfig(c)
@@ -113,8 +121,8 @@ func (a Authenticator) Authenticate(c context.Context, r *http.Request) (context
}
// Pick first authentication method that applies.
- var s state
- for _, m := range a {
+ s := state{authenticator: a}
+ for _, m := range a.Methods {
var err error
s.user, err = m.Authenticate(c, r)
if err != nil {
@@ -237,10 +245,11 @@ func (a Authenticator) Authenticate(c context.Context, r *http.Request) (context
return WithState(c, &s), nil
}
-// usersAPI returns implementation of UsersAPI by examining Methods. Returns nil
-// if none of Methods implement UsersAPI.
-func (a Authenticator) usersAPI() UsersAPI {
- for _, m := range a {
+// usersAPI returns implementation of UsersAPI by examining Methods.
+//
+// Returns nil if none of Methods implement UsersAPI.
+func (a *Authenticator) usersAPI() UsersAPI {
+ for _, m := range a.Methods {
if api, ok := m.(UsersAPI); ok {
return api
}
@@ -250,16 +259,22 @@ func (a Authenticator) usersAPI() UsersAPI {
// LoginURL returns a URL that, when visited, prompts the user to sign in,
// then redirects the user to the URL specified by dest.
-func (a Authenticator) LoginURL(c context.Context, dest string) (string, error) {
+//
+// Returns ErrNoUsersAPI if none of the authentication methods support login
+// URLs.
+func (a *Authenticator) LoginURL(c context.Context, dest string) (string, error) {
if api := a.usersAPI(); api != nil {
return api.LoginURL(c, dest)
}
return "", ErrNoUsersAPI
}
-// LogoutURL returns a URL that, when visited, signs the user out,
-// then redirects the user to the URL specified by dest.
-func (a Authenticator) LogoutURL(c context.Context, dest string) (string, error) {
+// LogoutURL returns a URL that, when visited, signs the user out, then
+// redirects the user to the URL specified by dest.
+//
+// Returns ErrNoUsersAPI if none of the authentication methods support login
+// URLs.
+func (a *Authenticator) LogoutURL(c context.Context, dest string) (string, error) {
if api := a.usersAPI(); api != nil {
return api.LogoutURL(c, dest)
}

Powered by Google App Engine
This is Rietveld 408576698