| OLD | NEW |
| 1 // Copyright 2015 The LUCI Authors. All rights reserved. | 1 // Copyright 2015 The LUCI Authors. All rights reserved. |
| 2 // Use of this source code is governed under the Apache License, Version 2.0 | 2 // Use of this source code is governed under the Apache License, Version 2.0 |
| 3 // that can be found in the LICENSE file. | 3 // that can be found in the LICENSE file. |
| 4 | 4 |
| 5 package auth | 5 package auth |
| 6 | 6 |
| 7 import ( | 7 import ( |
| 8 "errors" | 8 "errors" |
| 9 "net" | 9 "net" |
| 10 | 10 |
| 11 "golang.org/x/net/context" | 11 "golang.org/x/net/context" |
| 12 | 12 |
| 13 "github.com/luci/luci-go/server/auth/authdb" | 13 "github.com/luci/luci-go/server/auth/authdb" |
| 14 "github.com/luci/luci-go/server/auth/identity" | 14 "github.com/luci/luci-go/server/auth/identity" |
| 15 ) | 15 ) |
| 16 | 16 |
| 17 // ErrNoAuthState is returned when a function requires State to be in the | 17 // ErrNoAuthState is returned when a function requires State to be in the |
| 18 // context, but it is not there. In particular `IsMember` requires an existing | 18 // context, but it is not there. In particular `IsMember` requires an existing |
| 19 // state. | 19 // state. |
| 20 var ErrNoAuthState = errors.New("auth: auth.State is not in the context") | 20 var ErrNoAuthState = errors.New("auth: auth.State is not in the context") |
| 21 | 21 |
| 22 // State is stored in the context when handling an incoming request. It | 22 // State is stored in the context when handling an incoming request. It |
| 23 // contains authentication related state of the current request. | 23 // contains authentication related state of the current request. |
| 24 type State interface { | 24 type State interface { |
| 25 // Authenticator is an Authenticator used to authenticate the request. |
| 26 Authenticator() *Authenticator |
| 27 |
| 25 // DB is authdb.DB snapshot with authorization information to use when | 28 // DB is authdb.DB snapshot with authorization information to use when |
| 26 // processing this request. | 29 // processing this request. |
| 27 // | 30 // |
| 28 // Use directly only when you know what your are doing. Prefer to use wr
apping | 31 // Use directly only when you know what your are doing. Prefer to use wr
apping |
| 29 // functions (e.g. IsMember) instead. | 32 // functions (e.g. IsMember) instead. |
| 30 DB() authdb.DB | 33 DB() authdb.DB |
| 31 | 34 |
| 32 // Method returns authentication method used for current request or nil
if | 35 // Method returns authentication method used for current request or nil
if |
| 33 // request is anonymous. | 36 // request is anonymous. |
| 37 // |
| 38 // If non-nil, its one of the methods in Authenticator.Methods. |
| 34 Method() Method | 39 Method() Method |
| 35 | 40 |
| 36 // User holds the identity and profile of the current caller. User.Ident
ity | 41 // User holds the identity and profile of the current caller. User.Ident
ity |
| 37 // usually matches PeerIdentity(), but can be different if delegation is
used. | 42 // usually matches PeerIdentity(), but can be different if delegation is
used. |
| 38 // This field is never nil. For anonymous call it contains User with ide
ntity | 43 // This field is never nil. For anonymous call it contains User with ide
ntity |
| 39 // AnonymousIdentity. Do not modify it. | 44 // AnonymousIdentity. Do not modify it. |
| 40 User() *User | 45 User() *User |
| 41 | 46 |
| 42 // PeerIdentity identifies whoever is making the request. It's an identi
ty | 47 // PeerIdentity identifies whoever is making the request. It's an identi
ty |
| 43 // directly extracted from user credentials (ignoring delegation tokens)
. | 48 // directly extracted from user credentials (ignoring delegation tokens)
. |
| (...skipping 15 matching lines...) Expand all Loading... |
| 59 } | 64 } |
| 60 | 65 |
| 61 // GetState return State stored in the context or nil if it is not available. | 66 // GetState return State stored in the context or nil if it is not available. |
| 62 func GetState(c context.Context) State { | 67 func GetState(c context.Context) State { |
| 63 if s, ok := c.Value(stateContextKey(0)).(State); ok && s != nil { | 68 if s, ok := c.Value(stateContextKey(0)).(State); ok && s != nil { |
| 64 return s | 69 return s |
| 65 } | 70 } |
| 66 return nil | 71 return nil |
| 67 } | 72 } |
| 68 | 73 |
| 69 // CurrentUser represents the current caller. Shortcut for GetState(c).User(). | 74 // CurrentUser represents the current caller. |
| 70 // Returns user that represents identity.AnonymousIdentity if the context | 75 // |
| 71 // doesn't have State. | 76 // Shortcut for GetState(c).User(). Returns user with AnonymousIdentity if |
| 77 // the context doesn't have State. |
| 72 func CurrentUser(c context.Context) *User { | 78 func CurrentUser(c context.Context) *User { |
| 73 if s := GetState(c); s != nil { | 79 if s := GetState(c); s != nil { |
| 74 return s.User() | 80 return s.User() |
| 75 } | 81 } |
| 76 return &User{Identity: identity.AnonymousIdentity} | 82 return &User{Identity: identity.AnonymousIdentity} |
| 77 } | 83 } |
| 78 | 84 |
| 79 // CurrentIdentity return identity of the current caller. Shortcut for | 85 // CurrentIdentity return identity of the current caller. |
| 80 // GetState(c).User().Identity(). Returns identity.AnonymousIdentity if | 86 // |
| 87 // Shortcut for GetState(c).User().Identity(). Returns AnonymousIdentity if |
| 81 // the context doesn't have State. | 88 // the context doesn't have State. |
| 82 func CurrentIdentity(c context.Context) identity.Identity { | 89 func CurrentIdentity(c context.Context) identity.Identity { |
| 83 if s := GetState(c); s != nil { | 90 if s := GetState(c); s != nil { |
| 84 return s.User().Identity | 91 return s.User().Identity |
| 85 } | 92 } |
| 86 return identity.AnonymousIdentity | 93 return identity.AnonymousIdentity |
| 87 } | 94 } |
| 88 | 95 |
| 89 // IsMember returns true if the current caller is in any of the given groups. | 96 // IsMember returns true if the current caller is in any of the given groups. |
| 90 // | 97 // |
| 91 // Unknown groups are considered empty (the function returns false). | 98 // Unknown groups are considered empty (the function returns false). |
| 92 // If the context doesn't have State installed returns ErrNoAuthState. | 99 // If the context doesn't have State installed returns ErrNoAuthState. |
| 93 // | 100 // |
| 94 // May also return errors if the check can not be performed (e.g. on datastore | 101 // May also return errors if the check can not be performed (e.g. on datastore |
| 95 // issues). | 102 // issues). |
| 96 func IsMember(c context.Context, groups ...string) (bool, error) { | 103 func IsMember(c context.Context, groups ...string) (bool, error) { |
| 97 if s := GetState(c); s != nil { | 104 if s := GetState(c); s != nil { |
| 98 return s.DB().IsMember(c, s.User().Identity, groups...) | 105 return s.DB().IsMember(c, s.User().Identity, groups...) |
| 99 } | 106 } |
| 100 return false, ErrNoAuthState | 107 return false, ErrNoAuthState |
| 101 } | 108 } |
| 102 | 109 |
| 110 // LoginURL returns a URL that, when visited, prompts the user to sign in, |
| 111 // then redirects the user to the URL specified by dest. |
| 112 // |
| 113 // Shortcut for GetState(c).Authenticator().LoginURL(...). |
| 114 func LoginURL(c context.Context, dest string) (string, error) { |
| 115 if s := GetState(c); s != nil { |
| 116 return s.Authenticator().LoginURL(c, dest) |
| 117 } |
| 118 return "", ErrNoAuthState |
| 119 } |
| 120 |
| 121 // LogoutURL returns a URL that, when visited, signs the user out, then |
| 122 // redirects the user to the URL specified by dest. |
| 123 // |
| 124 // Shortcut for GetState(c).Authenticator().LogoutURL(...). |
| 125 func LogoutURL(c context.Context, dest string) (string, error) { |
| 126 if s := GetState(c); s != nil { |
| 127 return s.Authenticator().LogoutURL(c, dest) |
| 128 } |
| 129 return "", ErrNoAuthState |
| 130 } |
| 131 |
| 103 /// | 132 /// |
| 104 | 133 |
| 105 // state implements State. Immutable. | 134 // state implements State. Immutable. |
| 106 type state struct { | 135 type state struct { |
| 107 » db authdb.DB | 136 » authenticator *Authenticator |
| 108 » method Method | 137 » db authdb.DB |
| 109 » user *User | 138 » method Method |
| 110 » peerIdent identity.Identity | 139 » user *User |
| 111 » peerIP net.IP | 140 » peerIdent identity.Identity |
| 141 » peerIP net.IP |
| 112 } | 142 } |
| 113 | 143 |
| 144 func (s *state) Authenticator() *Authenticator { return s.authenticator } |
| 114 func (s *state) DB() authdb.DB { return s.db } | 145 func (s *state) DB() authdb.DB { return s.db } |
| 115 func (s *state) Method() Method { return s.method } | 146 func (s *state) Method() Method { return s.method } |
| 116 func (s *state) User() *User { return s.user } | 147 func (s *state) User() *User { return s.user } |
| 117 func (s *state) PeerIdentity() identity.Identity { return s.peerIdent } | 148 func (s *state) PeerIdentity() identity.Identity { return s.peerIdent } |
| 118 func (s *state) PeerIP() net.IP { return s.peerIP } | 149 func (s *state) PeerIP() net.IP { return s.peerIP } |
| OLD | NEW |