@ -1,4 +1,4 @@
package us er
package manag er
import (
"errors"
@ -8,6 +8,7 @@ import (
"github.com/coreos/dex/pkg/log"
"github.com/coreos/dex/repo"
"github.com/coreos/dex/user"
)
var (
@ -19,13 +20,13 @@ var (
// Manager performs user-related "business-logic" functions on user and related objects.
// This is in contrast to the Repos which perform little more than CRUD operations.
type Manager struct {
type User Manager struct {
Clock clockwork . Clock
userRepo UserRepo
pwRepo PasswordInfoRepo
userRepo user . UserRepo
pwRepo user . PasswordInfoRepo
begin repo . TransactionFactory
userIDGenerator UserIDGenerator
userIDGenerator user . UserIDGenerator
}
type ManagerOptions struct {
@ -34,58 +35,58 @@ type ManagerOptions struct {
// variable policies
}
func NewManager ( userRepo UserRepo , pwRepo PasswordInfoRepo , txnFactory repo . TransactionFactory , options ManagerOptions ) * Manager {
return & Manager {
func NewUser Manager ( userRepo user . UserRepo , pwRepo user . PasswordInfoRepo , txnFactory repo . TransactionFactory , options ManagerOptions ) * User Manager {
return & User Manager{
Clock : clockwork . NewRealClock ( ) ,
userRepo : userRepo ,
pwRepo : pwRepo ,
begin : txnFactory ,
userIDGenerator : DefaultUserIDGenerator ,
userIDGenerator : user . DefaultUserIDGenerator ,
}
}
func ( m * Manager ) Get ( id string ) ( User , error ) {
func ( m * User Manager) Get ( id string ) ( user . User , error ) {
return m . userRepo . Get ( nil , id )
}
func ( m * Manager ) List ( filter UserFilter , maxResults int , nextPageToken string ) ( [ ] User , string , error ) {
func ( m * User Manager) List ( filter user . UserFilter , maxResults int , nextPageToken string ) ( [ ] user . User , string , error ) {
return m . userRepo . List ( nil , filter , maxResults , nextPageToken )
}
// CreateUser creates a new user with the given hashedPassword; the connID should be the ID of the local connector.
// The userID of the created user is returned as the first argument.
func ( m * Manager ) CreateUser ( user User , hashedPassword Password , connID string ) ( string , error ) {
func ( m * User Manager) CreateUser ( usr us er . User , hashedPassword user . Password , connID string ) ( string , error ) {
tx , err := m . begin ( )
if err != nil {
return "" , err
}
insertedUser , err := m . insertNewUser ( tx , use r . Email , use r . EmailVerified )
insertedUser , err := m . insertNewUser ( tx , usr . Email , usr . EmailVerified )
if err != nil {
rollback ( tx )
return "" , err
}
use r . ID = insertedUser . ID
use r . CreatedAt = insertedUser . CreatedAt
err = m . userRepo . Update ( tx , use r )
usr . ID = insertedUser . ID
usr . CreatedAt = insertedUser . CreatedAt
err = m . userRepo . Update ( tx , usr )
if err != nil {
rollback ( tx )
return "" , err
}
rid := RemoteIdentity {
rid := user . RemoteIdentity {
ConnectorID : connID ,
ID : use r . ID ,
ID : usr . ID ,
}
if err := m . userRepo . AddRemoteIdentity ( tx , use r . ID , rid ) ; err != nil {
if err := m . userRepo . AddRemoteIdentity ( tx , usr . ID , rid ) ; err != nil {
rollback ( tx )
return "" , err
}
pwi := PasswordInfo {
UserID : use r . ID ,
pwi := user . PasswordInfo {
UserID : usr . ID ,
Password : hashedPassword ,
}
err = m . pwRepo . Create ( tx , pwi )
@ -99,10 +100,10 @@ func (m *Manager) CreateUser(user User, hashedPassword Password, connID string)
rollback ( tx )
return "" , err
}
return use r . ID , nil
return usr . ID , nil
}
func ( m * Manager ) Disable ( userID string , disabled bool ) error {
func ( m * User Manager) Disable ( userID string , disabled bool ) error {
tx , err := m . begin ( )
if err = m . userRepo . Disable ( tx , userID , disabled ) ; err != nil {
@ -119,7 +120,7 @@ func (m *Manager) Disable(userID string, disabled bool) error {
}
// RegisterWithRemoteIdentity creates new user and attaches the given remote identity.
func ( m * Manager ) RegisterWithRemoteIdentity ( email string , emailVerified bool , rid RemoteIdentity ) ( string , error ) {
func ( m * User Manager) RegisterWithRemoteIdentity ( email string , emailVerified bool , rid user . RemoteIdentity ) ( string , error ) {
tx , err := m . begin ( )
if err != nil {
return "" , err
@ -127,20 +128,20 @@ func (m *Manager) RegisterWithRemoteIdentity(email string, emailVerified bool, r
if _ , err = m . userRepo . GetByRemoteIdentity ( tx , rid ) ; err == nil {
rollback ( tx )
return "" , ErrorDuplicateRemoteIdentity
return "" , user . ErrorDuplicateRemoteIdentity
}
if err != ErrorNotFound {
if err != user . ErrorNotFound {
rollback ( tx )
return "" , err
}
use r , err := m . insertNewUser ( tx , email , emailVerified )
usr , err := m . insertNewUser ( tx , email , emailVerified )
if err != nil {
rollback ( tx )
return "" , err
}
if err := m . userRepo . AddRemoteIdentity ( tx , use r . ID , rid ) ; err != nil {
if err := m . userRepo . AddRemoteIdentity ( tx , usr . ID , rid ) ; err != nil {
rollback ( tx )
return "" , err
}
@ -150,44 +151,44 @@ func (m *Manager) RegisterWithRemoteIdentity(email string, emailVerified bool, r
rollback ( tx )
return "" , err
}
return use r . ID , nil
return usr . ID , nil
}
// RegisterWithPassword creates a new user with the given name and password.
// connID is the connector ID of the ConnectorLocal connector.
func ( m * Manager ) RegisterWithPassword ( email , plaintext , connID string ) ( string , error ) {
func ( m * User Manager) RegisterWithPassword ( email , plaintext , connID string ) ( string , error ) {
tx , err := m . begin ( )
if err != nil {
return "" , err
}
if ! ValidPassword ( plaintext ) {
if ! user . ValidPassword ( plaintext ) {
rollback ( tx )
return "" , ErrorInvalidPassword
return "" , user . ErrorInvalidPassword
}
use r , err := m . insertNewUser ( tx , email , false )
usr , err := m . insertNewUser ( tx , email , false )
if err != nil {
rollback ( tx )
return "" , err
}
rid := RemoteIdentity {
rid := user . RemoteIdentity {
ConnectorID : connID ,
ID : use r . ID ,
ID : usr . ID ,
}
if err := m . userRepo . AddRemoteIdentity ( tx , use r . ID , rid ) ; err != nil {
if err := m . userRepo . AddRemoteIdentity ( tx , usr . ID , rid ) ; err != nil {
rollback ( tx )
return "" , err
}
password , err := NewPasswordFromPlaintext ( plaintext )
password , err := user . NewPasswordFromPlaintext ( plaintext )
if err != nil {
rollback ( tx )
return "" , err
}
pwi := PasswordInfo {
UserID : use r . ID ,
pwi := user . PasswordInfo {
UserID : usr . ID ,
Password : password ,
}
@ -202,7 +203,7 @@ func (m *Manager) RegisterWithPassword(email, plaintext, connID string) (string,
rollback ( tx )
return "" , err
}
return use r . ID , nil
return usr . ID , nil
}
type EmailVerifiable interface {
@ -218,31 +219,31 @@ type EmailVerifiable interface {
// create it, ensuring that the token was signed and that the JWT was not
// expired.
// The callback url (i.e. where to send the user after the verification) is returned.
func ( m * Manager ) VerifyEmail ( ev EmailVerifiable ) ( * url . URL , error ) {
func ( m * User Manager) VerifyEmail ( ev EmailVerifiable ) ( * url . URL , error ) {
tx , err := m . begin ( )
if err != nil {
return nil , err
}
use r , err := m . userRepo . Get ( tx , ev . UserID ( ) )
usr , err := m . userRepo . Get ( tx , ev . UserID ( ) )
if err != nil {
rollback ( tx )
return nil , err
}
if use r . Email != ev . Email ( ) {
if usr . Email != ev . Email ( ) {
rollback ( tx )
return nil , ErrorEVEmailDoesntMatch
}
if use r . EmailVerified {
if usr . EmailVerified {
rollback ( tx )
return nil , ErrorEmailAlreadyVerified
}
use r . EmailVerified = true
usr . EmailVerified = true
err = m . userRepo . Update ( tx , use r )
err = m . userRepo . Update ( tx , usr )
if err != nil {
rollback ( tx )
return nil , err
@ -258,19 +259,19 @@ func (m *Manager) VerifyEmail(ev EmailVerifiable) (*url.URL, error) {
type PasswordChangeable interface {
UserID ( ) string
Password ( ) Password
Password ( ) user . Password
Callback ( ) * url . URL
}
func ( m * Manager ) ChangePassword ( pwr PasswordChangeable , plaintext string ) ( * url . URL , error ) {
func ( m * User Manager) ChangePassword ( pwr PasswordChangeable , plaintext string ) ( * url . URL , error ) {
tx , err := m . begin ( )
if err != nil {
return nil , err
}
if ! ValidPassword ( plaintext ) {
if ! user . ValidPassword ( plaintext ) {
rollback ( tx )
return nil , ErrorInvalidPassword
return nil , user . ErrorInvalidPassword
}
pwi , err := m . pwRepo . Get ( tx , pwr . UserID ( ) )
@ -284,7 +285,7 @@ func (m *Manager) ChangePassword(pwr PasswordChangeable, plaintext string) (*url
return nil , ErrorPasswordAlreadyChanged
}
newPass , err := NewPasswordFromPlaintext ( plaintext )
newPass , err := user . NewPasswordFromPlaintext ( plaintext )
if err != nil {
rollback ( tx )
return nil , err
@ -305,36 +306,36 @@ func (m *Manager) ChangePassword(pwr PasswordChangeable, plaintext string) (*url
return pwr . Callback ( ) , nil
}
func ( m * Manager ) insertNewUser ( tx repo . Transaction , email string , emailVerified bool ) ( User , error ) {
if ! ValidEmail ( email ) {
return User { } , ErrorInvalidEmail
func ( m * User Manager) insertNewUser ( tx repo . Transaction , email string , emailVerified bool ) ( user . User , error ) {
if ! user . ValidEmail ( email ) {
return user . User { } , user . ErrorInvalidEmail
}
var err error
if _ , err = m . userRepo . GetByEmail ( tx , email ) ; err == nil {
return User { } , ErrorDuplicateEmail
return user . User { } , user . ErrorDuplicateEmail
}
if err != ErrorNotFound {
return User { } , err
if err != user . ErrorNotFound {
return user . User { } , err
}
userID , err := m . userIDGenerator ( )
if err != nil {
return User { } , err
return user . User { } , err
}
use r := User {
usr := user . User {
ID : userID ,
Email : email ,
EmailVerified : emailVerified ,
CreatedAt : m . Clock . Now ( ) ,
}
err = m . userRepo . Create ( tx , use r )
err = m . userRepo . Create ( tx , usr )
if err != nil {
return User { } , err
return user . User { } , err
}
return use r , nil
return usr , nil
}
func rollback ( tx repo . Transaction ) {