Skip to content

Commit

Permalink
found way to enable userID
Browse files Browse the repository at this point in the history
  • Loading branch information
Rob Archibald committed Jan 21, 2017
1 parent b7ac85c commit 2a94ddd
Show file tree
Hide file tree
Showing 11 changed files with 132 additions and 77 deletions.
15 changes: 10 additions & 5 deletions authStore.go
Original file line number Diff line number Diff line change
Expand Up @@ -220,7 +220,7 @@ func (s *authStore) createSession(email string, rememberMe bool) (*loginSession,
return nil, newLoggedError("Problem generating sessionId", nil)
}

session, remember, err := s.backend.CreateSession(email, sessionHash, time.Now().UTC().Add(sessionRenewDuration), time.Now().UTC().Add(sessionExpireDuration), rememberMe, selector, tokenHash, time.Now().UTC().Add(rememberMeRenewDuration), time.Now().UTC().Add(rememberMeExpireDuration))
session, remember, err := s.backend.CreateSession(1, email, sessionHash, time.Now().UTC().Add(sessionRenewDuration), time.Now().UTC().Add(sessionExpireDuration), rememberMe, selector, tokenHash, time.Now().UTC().Add(rememberMeRenewDuration), time.Now().UTC().Add(rememberMeExpireDuration))
if err != nil {
return nil, newLoggedError("Unable to create new session", err)
}
Expand Down Expand Up @@ -353,7 +353,7 @@ func (s *authStore) createProfile(fullName, organization, password, picturePath
return newLoggedError("Error while creating profile", err)
}

_, err = s.createLogin(session.Email, fullName, password, mailQuota, fileQuota)
_, err = s.createLogin(session.UserID, session.Email, fullName, password, mailQuota, fileQuota)
if err != nil {
return newLoggedError("Unable to create login", err)
}
Expand All @@ -368,7 +368,7 @@ func (s *authStore) createProfile(fullName, organization, password, picturePath
}

/**************** TODO: send 0 for UID and GID numbers and empty quotas if mailQuota and fileQuota are 0 **********************/
func (s *authStore) createLogin(email, fullName, password string, mailQuota, fileQuota int) (*userLogin, error) {
func (s *authStore) createLogin(userID int, email, fullName, password string, mailQuota, fileQuota int) (*userLogin, error) {
passwordHash, err := cryptoHash(password)
if err != nil {
return nil, newLoggedError("Unable to create login", err)
Expand All @@ -379,7 +379,7 @@ func (s *authStore) createLogin(email, fullName, password string, mailQuota, fil
homeDirectory := "/home"
mQuota := fmt.Sprintf("%dGB", mailQuota)
fQuota := fmt.Sprintf("%dGB", fileQuota)
login, err := s.backend.CreateLogin(email, passwordHash, fullName, homeDirectory, uidNumber, gidNumber, mQuota, fQuota)
login, err := s.backend.CreateLogin(userID, email, passwordHash, fullName, homeDirectory, uidNumber, gidNumber, mQuota, fQuota)
if err != nil {
return nil, newLoggedError("Unable to create login", err)
}
Expand Down Expand Up @@ -409,11 +409,16 @@ func (s *authStore) verifyEmail(emailVerificationCode string) error {
return newLoggedError("Failed to verify email", err)
}

err = s.backend.AddUser(session.Email)
userID, err := s.backend.AddUser(session.Email)
if err != nil {
return newLoggedError("Failed to create new user in database", err)
}

err = s.backend.UpdateEmailSession(emailVerifyHash, userID, session.Email)
if err != nil {
return newLoggedError("Failed to update email session", err)
}

err = s.saveEmailCookie(emailVerificationCode, time.Now().UTC().Add(emailExpireDuration))
if err != nil {
return newLoggedError("Failed to save email cookie", err)
Expand Down
40 changes: 29 additions & 11 deletions authStore_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -561,13 +561,15 @@ func TestAuthCreateProfile(t *testing.T) {
}

var verifyEmailTests = []struct {
Scenario string
EmailVerificationCode string
HasCookiePutError bool
getEmailSessionReturn *getEmailSessionReturn
MailErr error
MethodsCalled []string
ExpectedErr string
Scenario string
EmailVerificationCode string
HasCookiePutError bool
getEmailSessionReturn *getEmailSessionReturn
AddUserReturn error
UpdateEmailSessionReturn error
MailErr error
MethodsCalled []string
ExpectedErr string
}{
{
Scenario: "Decode error",
Expand All @@ -582,33 +584,49 @@ var verifyEmailTests = []struct {
MethodsCalled: []string{"GetEmailSession"},
ExpectedErr: "Failed to verify email",
},
{
Scenario: "Add User fail",
EmailVerificationCode: "nfwRDzfxxJj2_HY-_mLz6jWyWU7bF0zUlIUUVkQgbZ0",
getEmailSessionReturn: getEmailSessionSuccess(),
AddUserReturn: errors.New("fail"),
MethodsCalled: []string{"GetEmailSession", "AddUser"},
ExpectedErr: "Failed to create new user in database",
},
{
Scenario: "Email session update fail",
EmailVerificationCode: "nfwRDzfxxJj2_HY-_mLz6jWyWU7bF0zUlIUUVkQgbZ0",
getEmailSessionReturn: getEmailSessionSuccess(),
UpdateEmailSessionReturn: errors.New("fail"),
MethodsCalled: []string{"GetEmailSession", "AddUser", "UpdateEmailSession"},
ExpectedErr: "Failed to update email session",
},
{
Scenario: "Cookie Save Error",
EmailVerificationCode: "nfwRDzfxxJj2_HY-_mLz6jWyWU7bF0zUlIUUVkQgbZ0",
getEmailSessionReturn: getEmailSessionSuccess(),
HasCookiePutError: true,
MethodsCalled: []string{"GetEmailSession", "AddUser"},
MethodsCalled: []string{"GetEmailSession", "AddUser", "UpdateEmailSession"},
ExpectedErr: "Failed to save email cookie",
},
{
Scenario: "Mail Error",
EmailVerificationCode: "nfwRDzfxxJj2_HY-_mLz6jWyWU7bF0zUlIUUVkQgbZ0",
getEmailSessionReturn: getEmailSessionSuccess(),
MethodsCalled: []string{"GetEmailSession", "AddUser"},
MethodsCalled: []string{"GetEmailSession", "AddUser", "UpdateEmailSession"},
MailErr: errors.New("test"),
ExpectedErr: "Failed to send welcome email",
},
{
Scenario: "Email sent",
EmailVerificationCode: "nfwRDzfxxJj2_HY-_mLz6jWyWU7bF0zUlIUUVkQgbZ0",
getEmailSessionReturn: getEmailSessionSuccess(),
MethodsCalled: []string{"GetEmailSession", "AddUser"},
MethodsCalled: []string{"GetEmailSession", "AddUser", "UpdateEmailSession"},
},
}

func TestAuthVerifyEmail(t *testing.T) {
for i, test := range verifyEmailTests {
backend := &mockBackend{getEmailSessionReturn: test.getEmailSessionReturn}
backend := &mockBackend{getEmailSessionReturn: test.getEmailSessionReturn, AddUserReturn: test.AddUserReturn, UpdateEmailSessionReturn: test.UpdateEmailSessionReturn}
store := getAuthStore(nil, nil, nil, false, test.HasCookiePutError, test.MailErr, backend)
err := store.verifyEmail(test.EmailVerificationCode)
methods := store.backend.(*mockBackend).MethodsCalled
Expand Down
58 changes: 34 additions & 24 deletions backend.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,28 @@ import (
"time"
)

var errEmailVerifyHashExists = errors.New("DB: Email verify hash already exists")
var errInvalidEmailVerifyHash = errors.New("DB: Invalid verify code")
var errInvalidRenewTimeUTC = errors.New("DB: Invalid RenewTimeUTC")
var errInvalidSessionHash = errors.New("DB: Invalid SessionHash")
var errRememberMeSelectorExists = errors.New("DB: RememberMe selector already exists")
var errUserNotFound = errors.New("DB: User not found")
var errLoginNotFound = errors.New("DB: Login not found")
var errSessionNotFound = errors.New("DB: Session not found")
var errSessionAlreadyExists = errors.New("DB: Session already exists")
var errRememberMeNotFound = errors.New("DB: RememberMe not found")
var errRememberMeNeedsRenew = errors.New("DB: RememberMe needs to be renewed")
var errRememberMeExpired = errors.New("DB: RememberMe is expired")
var errUserAlreadyExists = errors.New("DB: User already exists")

type backender interface {
// UserBackender. Write out since it contains duplicate BackendCloser
AddUser(email string) error
AddUser(email string) (int, error)
GetUser(email string) (*user, error)
UpdateUser(email, fullname string, company string, pictureURL string) error

// LoginBackender. Write out since it contains duplicate BackendCloser
CreateLogin(email, passwordHash, fullName, homeDirectory string, uidNumber, gidNumber int, mailQuota, fileQuota string) (*userLogin, error)
CreateLogin(userID int, email, passwordHash, fullName, homeDirectory string, uidNumber, gidNumber int, mailQuota, fileQuota string) (*userLogin, error)
GetLogin(email, loginProvider string) (*userLogin, error)
UpdateEmail(email string, password string, newEmail string) (*loginSession, error)
UpdatePassword(email string, oldPassword string, newPassword string) (*loginSession, error)
Expand All @@ -25,14 +39,14 @@ type backendCloser interface {
}

type userBackender interface {
AddUser(email string) error
AddUser(email string) (int, error)
GetUser(email string) (*user, error)
UpdateUser(email, fullname string, company string, pictureURL string) error
backendCloser
}

type loginBackender interface {
CreateLogin(email, passwordHash, fullName, homeDirectory string, uidNumber, gidNumber int, mailQuota, fileQuota string) (*userLogin, error)
CreateLogin(userID int, email, passwordHash, fullName, homeDirectory string, uidNumber, gidNumber int, mailQuota, fileQuota string) (*userLogin, error)
GetLogin(email, loginProvider string) (*userLogin, error)
UpdateEmail(email string, password string, newEmail string) (*loginSession, error)
UpdatePassword(email string, oldPassword string, newPassword string) (*loginSession, error)
Expand All @@ -42,9 +56,10 @@ type loginBackender interface {
type sessionBackender interface {
CreateEmailSession(email, emailVerifyHash string) error
GetEmailSession(verifyHash string) (*emailSession, error)
UpdateEmailSession(verifyHash string, userID int, email string) error
DeleteEmailSession(verifyHash string) error

CreateSession(email string, sessionHash string, sessionRenewTimeUTC, sessionExpireTimeUTC time.Time, rememberMe bool, rememberMeSelector, rememberMeTokenHash string, rememberMeRenewTimeUTC, rememberMeExpireTimeUTC time.Time) (*loginSession, *rememberMeSession, error)
CreateSession(userID int, email string, sessionHash string, sessionRenewTimeUTC, sessionExpireTimeUTC time.Time, rememberMe bool, rememberMeSelector, rememberMeTokenHash string, rememberMeRenewTimeUTC, rememberMeExpireTimeUTC time.Time) (*loginSession, *rememberMeSession, error)
GetSession(sessionHash string) (*loginSession, error)
RenewSession(sessionHash string, renewTimeUTC time.Time) (*loginSession, error)
InvalidateSession(sessionHash string) error
Expand All @@ -56,46 +71,37 @@ type sessionBackender interface {
backendCloser
}

var errEmailVerifyHashExists = errors.New("DB: Email verify hash already exists")
var errInvalidEmailVerifyHash = errors.New("DB: Invalid verify code")
var errInvalidRenewTimeUTC = errors.New("DB: Invalid RenewTimeUTC")
var errInvalidSessionHash = errors.New("DB: Invalid SessionHash")
var errRememberMeSelectorExists = errors.New("DB: RememberMe selector already exists")
var errUserNotFound = errors.New("DB: User not found")
var errLoginNotFound = errors.New("DB: Login not found")
var errSessionNotFound = errors.New("DB: Session not found")
var errSessionAlreadyExists = errors.New("DB: Session already exists")
var errRememberMeNotFound = errors.New("DB: RememberMe not found")
var errRememberMeNeedsRenew = errors.New("DB: RememberMe needs to be renewed")
var errRememberMeExpired = errors.New("DB: RememberMe is expired")
var errUserAlreadyExists = errors.New("DB: User already exists")

type emailSession struct {
UserID int
Email string
EmailVerifyHash string
}

type user struct {
UserID int
FullName string
PrimaryEmail string
LockoutEndTimeUTC *time.Time
AccessFailedCount int
}

type userLogin struct {
UserID int
Email string
LoginProviderID int
ProviderKey string
}

type loginSession struct {
UserID int
Email string
SessionHash string
RenewTimeUTC time.Time
ExpireTimeUTC time.Time
}

type rememberMeSession struct {
UserID int
Email string
Selector string
TokenHash string
Expand Down Expand Up @@ -157,8 +163,8 @@ func (b *backend) GetLogin(email, loginProvider string) (*userLogin, error) {
return b.l.GetLogin(email, loginProvider)
}

func (b *backend) CreateSession(email, sessionHash string, sessionRenewTimeUTC, sessionExpireTimeUTC time.Time, rememberMe bool, rememberMeSelector, rememberMeTokenHash string, rememberMeRenewTimeUTC, rememberMeExpireTimeUTC time.Time) (*loginSession, *rememberMeSession, error) {
return b.s.CreateSession(email, sessionHash, sessionRenewTimeUTC, sessionExpireTimeUTC, rememberMe, rememberMeSelector, rememberMeTokenHash, rememberMeRenewTimeUTC, rememberMeExpireTimeUTC)
func (b *backend) CreateSession(userID int, email, sessionHash string, sessionRenewTimeUTC, sessionExpireTimeUTC time.Time, rememberMe bool, rememberMeSelector, rememberMeTokenHash string, rememberMeRenewTimeUTC, rememberMeExpireTimeUTC time.Time) (*loginSession, *rememberMeSession, error) {
return b.s.CreateSession(userID, email, sessionHash, sessionRenewTimeUTC, sessionExpireTimeUTC, rememberMe, rememberMeSelector, rememberMeTokenHash, rememberMeRenewTimeUTC, rememberMeExpireTimeUTC)
}

func (b *backend) GetSession(sessionHash string) (*loginSession, error) {
Expand All @@ -185,11 +191,15 @@ func (b *backend) GetEmailSession(emailVerifyHash string) (*emailSession, error)
return b.s.GetEmailSession(emailVerifyHash)
}

func (b *backend) UpdateEmailSession(emailVerifyHash string, userID int, email string) error {
return b.s.UpdateEmailSession(emailVerifyHash, userID, email)
}

func (b *backend) DeleteEmailSession(emailVerifyHash string) error {
return b.s.DeleteEmailSession(emailVerifyHash)
}

func (b *backend) AddUser(email string) error {
func (b *backend) AddUser(email string) (int, error) {
return b.u.AddUser(email)
}

Expand All @@ -201,8 +211,8 @@ func (b *backend) UpdateUser(email, fullname string, company string, pictureURL
return b.u.UpdateUser(email, fullname, company, pictureURL)
}

func (b *backend) CreateLogin(email, passwordHash, fullName, homeDirectory string, uidNumber, gidNumber int, mailQuota, fileQuota string) (*userLogin, error) {
return b.l.CreateLogin(email, passwordHash, fullName, homeDirectory, uidNumber, gidNumber, mailQuota, fileQuota)
func (b *backend) CreateLogin(userID int, email, passwordHash, fullName, homeDirectory string, uidNumber, gidNumber int, mailQuota, fileQuota string) (*userLogin, error) {
return b.l.CreateLogin(userID, email, passwordHash, fullName, homeDirectory, uidNumber, gidNumber, mailQuota, fileQuota)
}

func (b *backend) UpdateEmail(email string, password string, newEmail string) (*loginSession, error) {
Expand Down
5 changes: 3 additions & 2 deletions backendDbUser.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,9 @@ func (u *backendDbUser) GetLogin(email, loginProvider string) (*userLogin, error
return login, u.Db.QueryStruct(onedb.NewSqlQuery(u.GetUserLoginQuery, email, loginProvider), login)
}

func (u *backendDbUser) AddUser(email string) error {
return u.Db.Execute(onedb.NewSqlQuery(u.AddUserQuery, email))
func (u *backendDbUser) AddUser(email string) (int, error) {
var userId int
return userId, u.Db.Execute(onedb.NewSqlQuery(u.AddUserQuery, email))
}

func (u *backendDbUser) GetUser(email string) (*user, error) {
Expand Down
2 changes: 1 addition & 1 deletion backendLDAPLogin.go
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ func (l *backendLDAPLogin) GetLogin(email, loginProvider string) (*userLogin, er
}

/**************** TODO: create different type of user if not using file and mail quotas **********************/
func (l *backendLDAPLogin) CreateLogin(email, passwordHash, fullName, homeDirectory string, uidNumber, gidNumber int, mailQuota, fileQuota string) (*userLogin, error) {
func (l *backendLDAPLogin) CreateLogin(userID int, email, passwordHash, fullName, homeDirectory string, uidNumber, gidNumber int, mailQuota, fileQuota string) (*userLogin, error) {
req := ldap.NewAddRequest("uid=" + email + ",ou=Users,dc=endfirst,dc=com")
req.Attribute("objectClass", []string{"posixAccount", "account", "ownCloud", "systemQuotas"})
req.Attribute("uid", []string{email})
Expand Down
2 changes: 1 addition & 1 deletion backendLDAPLogin_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ func TestLdapGetLogin(t *testing.T) {
func TestLdapCreateLogin(t *testing.T) {
m := onedb.NewMock(nil, nil, nil)
l := backendLDAPLogin{db: m}
_, err := l.CreateLogin("email", "hash", "name", "homeDir", 1, 1, "mailQuota", "fileQuota")
_, err := l.CreateLogin(1, "email", "hash", "name", "homeDir", 1, 1, "mailQuota", "fileQuota")
if err != nil {
t.Error("expected success")
}
Expand Down
28 changes: 19 additions & 9 deletions backendMemory.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,13 +32,13 @@ func (m *backendMemory) GetLogin(email, loginProvider string) (*userLogin, error
return login, nil
}

func (m *backendMemory) CreateSession(email, sessionHash string, sessionRenewTimeUTC, sessionExpireTimeUTC time.Time, rememberMe bool, rememberMeSelector, rememberMeTokenHash string, rememberMeRenewTimeUTC, rememberMeExpireTimeUTC time.Time) (*loginSession, *rememberMeSession, error) {
func (m *backendMemory) CreateSession(userID int, email, sessionHash string, sessionRenewTimeUTC, sessionExpireTimeUTC time.Time, rememberMe bool, rememberMeSelector, rememberMeTokenHash string, rememberMeRenewTimeUTC, rememberMeExpireTimeUTC time.Time) (*loginSession, *rememberMeSession, error) {
session := m.getSessionByHash(sessionHash)
if session != nil {
return nil, nil, errSessionAlreadyExists
}

session = &loginSession{email, sessionHash, sessionRenewTimeUTC, sessionExpireTimeUTC}
session = &loginSession{userID, email, sessionHash, sessionRenewTimeUTC, sessionExpireTimeUTC}
m.Sessions = append(m.Sessions, session)
var rememberItem *rememberMeSession
if rememberMe {
Expand All @@ -47,7 +47,7 @@ func (m *backendMemory) CreateSession(email, sessionHash string, sessionRenewTim
return nil, nil, errRememberMeSelectorExists
}

rememberItem = &rememberMeSession{email, rememberMeSelector, rememberMeTokenHash, rememberMeRenewTimeUTC, rememberMeExpireTimeUTC}
rememberItem = &rememberMeSession{userID, email, rememberMeSelector, rememberMeTokenHash, rememberMeRenewTimeUTC, rememberMeExpireTimeUTC}
m.RememberMes = append(m.RememberMes, rememberItem)
}
return session, rememberItem, nil
Expand Down Expand Up @@ -113,19 +113,29 @@ func (m *backendMemory) GetEmailSession(emailVerifyHash string) (*emailSession,
return session, nil
}

func (m *backendMemory) UpdateEmailSession(verifyHash string, userID int, email string) error {
session := m.getEmailSessionByEmailVerifyHash(verifyHash)
if session == nil {
return errEmailVerifyHashExists
}
session.UserID = userID
return nil
}

// ***************** TODO: need to come up with a way to clean up all sessions for this email **************
func (m *backendMemory) DeleteEmailSession(emailVerifyHash string) error {
m.removeEmailSession(emailVerifyHash)
return nil
}

func (m *backendMemory) AddUser(email string) error {
func (m *backendMemory) AddUser(email string) (int, error) {
u := m.getUserByEmail(email)
if u != nil {
return errUserAlreadyExists
return -1, errUserAlreadyExists
}
m.Users = append(m.Users, &user{"", email, nil, 0})
return nil
m.LastUserID++
m.Users = append(m.Users, &user{m.LastUserID, "", email, nil, 0})
return m.LastUserID, nil
}

func (m *backendMemory) GetUser(email string) (*user, error) {
Expand All @@ -147,8 +157,8 @@ func (m *backendMemory) UpdateUser(email, fullname string, company string, pictu
}

// This method needs to be fixed to work with the new data model using LDAP
func (m *backendMemory) CreateLogin(email, passwordHash, fullName, homeDirectory string, uidNumber, gidNumber int, mailQuota, fileQuota string) (*userLogin, error) {
login := userLogin{email, 1, passwordHash}
func (m *backendMemory) CreateLogin(userID int, email, passwordHash, fullName, homeDirectory string, uidNumber, gidNumber int, mailQuota, fileQuota string) (*userLogin, error) {
login := userLogin{userID, email, 1, passwordHash}
m.Logins = append(m.Logins, &login)

return &login, nil
Expand Down
Loading

0 comments on commit 2a94ddd

Please sign in to comment.