Add credential authenticator interface
Signed-off-by: Derek McGowan <derek@mcgstyle.net> (github: dmcgowan)master
							parent
							
								
									bf991fec01
								
							
						
					
					
						commit
						98620458e3
					
				|  | @ -33,6 +33,7 @@ | |||
| package auth | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| 
 | ||||
|  | @ -49,6 +50,14 @@ const ( | |||
| 	UserNameKey = "auth.user.name" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	// ErrInvalidCredential is returned when the auth token does not authenticate correctly.
 | ||||
| 	ErrInvalidCredential = errors.New("invalid authorization credential") | ||||
| 
 | ||||
| 	// ErrAuthenticationFailure returned when authentication failure to be presented to agent.
 | ||||
| 	ErrAuthenticationFailure = errors.New("authentication failure") | ||||
| ) | ||||
| 
 | ||||
| // UserInfo carries information about
 | ||||
| // an autenticated/authorized client.
 | ||||
| type UserInfo struct { | ||||
|  | @ -97,6 +106,11 @@ type AccessController interface { | |||
| 	Authorized(ctx context.Context, access ...Access) (context.Context, error) | ||||
| } | ||||
| 
 | ||||
| // CredentialAuthenticator is an object which is able to validate credentials
 | ||||
| type CredentialAuthenticator interface { | ||||
| 	AuthenticateUser(username, password string) error | ||||
| } | ||||
| 
 | ||||
| // WithUser returns a context with the authorized user info.
 | ||||
| func WithUser(ctx context.Context, user UserInfo) context.Context { | ||||
| 	return userInfoContext{ | ||||
|  |  | |||
|  | @ -6,7 +6,6 @@ | |||
| package htpasswd | ||||
| 
 | ||||
| import ( | ||||
| 	"errors" | ||||
| 	"fmt" | ||||
| 	"net/http" | ||||
| 	"os" | ||||
|  | @ -15,14 +14,6 @@ import ( | |||
| 	"github.com/docker/distribution/registry/auth" | ||||
| ) | ||||
| 
 | ||||
| var ( | ||||
| 	// ErrInvalidCredential is returned when the auth token does not authenticate correctly.
 | ||||
| 	ErrInvalidCredential = errors.New("invalid authorization credential") | ||||
| 
 | ||||
| 	// ErrAuthenticationFailure returned when authentication failure to be presented to agent.
 | ||||
| 	ErrAuthenticationFailure = errors.New("authentication failure") | ||||
| ) | ||||
| 
 | ||||
| type accessController struct { | ||||
| 	realm    string | ||||
| 	htpasswd *htpasswd | ||||
|  | @ -65,21 +56,25 @@ func (ac *accessController) Authorized(ctx context.Context, accessRecords ...aut | |||
| 	if !ok { | ||||
| 		return nil, &challenge{ | ||||
| 			realm: ac.realm, | ||||
| 			err:   ErrInvalidCredential, | ||||
| 			err:   auth.ErrInvalidCredential, | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	if err := ac.htpasswd.authenticateUser(username, password); err != nil { | ||||
| 	if err := ac.AuthenticateUser(username, password); err != nil { | ||||
| 		context.GetLogger(ctx).Errorf("error authenticating user %q: %v", username, err) | ||||
| 		return nil, &challenge{ | ||||
| 			realm: ac.realm, | ||||
| 			err:   ErrAuthenticationFailure, | ||||
| 			err:   auth.ErrAuthenticationFailure, | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 	return auth.WithUser(ctx, auth.UserInfo{Name: username}), nil | ||||
| } | ||||
| 
 | ||||
| func (ac *accessController) AuthenticateUser(username, password string) error { | ||||
| 	return ac.htpasswd.authenticateUser(username, password) | ||||
| } | ||||
| 
 | ||||
| // challenge implements the auth.Challenge interface.
 | ||||
| type challenge struct { | ||||
| 	realm string | ||||
|  |  | |||
|  | @ -6,6 +6,8 @@ import ( | |||
| 	"io" | ||||
| 	"strings" | ||||
| 
 | ||||
| 	"github.com/docker/distribution/registry/auth" | ||||
| 
 | ||||
| 	"golang.org/x/crypto/bcrypt" | ||||
| ) | ||||
| 
 | ||||
|  | @ -33,12 +35,12 @@ func (htpasswd *htpasswd) authenticateUser(username string, password string) err | |||
| 		// timing attack paranoia
 | ||||
| 		bcrypt.CompareHashAndPassword([]byte{}, []byte(password)) | ||||
| 
 | ||||
| 		return ErrAuthenticationFailure | ||||
| 		return auth.ErrAuthenticationFailure | ||||
| 	} | ||||
| 
 | ||||
| 	err := bcrypt.CompareHashAndPassword([]byte(credentials), []byte(password)) | ||||
| 	if err != nil { | ||||
| 		return ErrAuthenticationFailure | ||||
| 		return auth.ErrAuthenticationFailure | ||||
| 	} | ||||
| 
 | ||||
| 	return nil | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue