mirror of
https://github.com/gogs/gogs.git
synced 2025-05-24 16:30:51 +00:00
all: unwrap database.TwoFactorsStore
interface (#7707)
This commit is contained in:
parent
4d05804729
commit
202012887a
@ -123,7 +123,6 @@ func NewConnection(w logger.Writer) (*gorm.DB, error) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Initialize stores, sorted in alphabetical order.
|
// Initialize stores, sorted in alphabetical order.
|
||||||
TwoFactors = &twoFactorsStore{DB: db}
|
|
||||||
Users = NewUsersStore(db)
|
Users = NewUsersStore(db)
|
||||||
|
|
||||||
Handle = &DB{db: db}
|
Handle = &DB{db: db}
|
||||||
@ -186,3 +185,7 @@ func (db *DB) PublicKey() *PublicKeysStore {
|
|||||||
func (db *DB) Repositories() *RepositoriesStore {
|
func (db *DB) Repositories() *RepositoriesStore {
|
||||||
return newReposStore(db.db)
|
return newReposStore(db.db)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (db *DB) TwoFactors() *TwoFactorsStore {
|
||||||
|
return newTwoFactorsStore(db.db)
|
||||||
|
}
|
||||||
|
@ -8,14 +8,6 @@ import (
|
|||||||
"testing"
|
"testing"
|
||||||
)
|
)
|
||||||
|
|
||||||
func SetMockTwoFactorsStore(t *testing.T, mock TwoFactorsStore) {
|
|
||||||
before := TwoFactors
|
|
||||||
TwoFactors = mock
|
|
||||||
t.Cleanup(func() {
|
|
||||||
TwoFactors = before
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func SetMockUsersStore(t *testing.T, mock UsersStore) {
|
func SetMockUsersStore(t *testing.T, mock UsersStore) {
|
||||||
before := Users
|
before := Users
|
||||||
Users = mock
|
Users = mock
|
||||||
|
@ -20,22 +20,6 @@ import (
|
|||||||
"gogs.io/gogs/internal/strutil"
|
"gogs.io/gogs/internal/strutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
// TwoFactorsStore is the persistent interface for 2FA.
|
|
||||||
type TwoFactorsStore interface {
|
|
||||||
// Create creates a new 2FA token and recovery codes for given user. The "key"
|
|
||||||
// is used to encrypt and later decrypt given "secret", which should be
|
|
||||||
// configured in site-level and change of the "key" will break all existing 2FA
|
|
||||||
// tokens.
|
|
||||||
Create(ctx context.Context, userID int64, key, secret string) error
|
|
||||||
// GetByUserID returns the 2FA token of given user. It returns
|
|
||||||
// ErrTwoFactorNotFound when not found.
|
|
||||||
GetByUserID(ctx context.Context, userID int64) (*TwoFactor, error)
|
|
||||||
// IsEnabled returns true if the user has enabled 2FA.
|
|
||||||
IsEnabled(ctx context.Context, userID int64) bool
|
|
||||||
}
|
|
||||||
|
|
||||||
var TwoFactors TwoFactorsStore
|
|
||||||
|
|
||||||
// BeforeCreate implements the GORM create hook.
|
// BeforeCreate implements the GORM create hook.
|
||||||
func (t *TwoFactor) BeforeCreate(tx *gorm.DB) error {
|
func (t *TwoFactor) BeforeCreate(tx *gorm.DB) error {
|
||||||
if t.CreatedUnix == 0 {
|
if t.CreatedUnix == 0 {
|
||||||
@ -50,13 +34,20 @@ func (t *TwoFactor) AfterFind(_ *gorm.DB) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ TwoFactorsStore = (*twoFactorsStore)(nil)
|
// TwoFactorsStore is the storage layer for two-factor authentication settings.
|
||||||
|
type TwoFactorsStore struct {
|
||||||
type twoFactorsStore struct {
|
db *gorm.DB
|
||||||
*gorm.DB
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *twoFactorsStore) Create(ctx context.Context, userID int64, key, secret string) error {
|
func newTwoFactorsStore(db *gorm.DB) *TwoFactorsStore {
|
||||||
|
return &TwoFactorsStore{db: db}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create creates a new 2FA token and recovery codes for given user. The "key"
|
||||||
|
// is used to encrypt and later decrypt given "secret", which should be
|
||||||
|
// configured in site-level and change of the "key" will break all existing 2FA
|
||||||
|
// tokens.
|
||||||
|
func (s *TwoFactorsStore) Create(ctx context.Context, userID int64, key, secret string) error {
|
||||||
encrypted, err := cryptoutil.AESGCMEncrypt(cryptoutil.MD5Bytes(key), []byte(secret))
|
encrypted, err := cryptoutil.AESGCMEncrypt(cryptoutil.MD5Bytes(key), []byte(secret))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return errors.Wrap(err, "encrypt secret")
|
return errors.Wrap(err, "encrypt secret")
|
||||||
@ -71,7 +62,7 @@ func (s *twoFactorsStore) Create(ctx context.Context, userID int64, key, secret
|
|||||||
return errors.Wrap(err, "generate recovery codes")
|
return errors.Wrap(err, "generate recovery codes")
|
||||||
}
|
}
|
||||||
|
|
||||||
return s.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
return s.db.WithContext(ctx).Transaction(func(tx *gorm.DB) error {
|
||||||
err := tx.Create(tf).Error
|
err := tx.Create(tf).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
@ -88,8 +79,7 @@ type ErrTwoFactorNotFound struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func IsErrTwoFactorNotFound(err error) bool {
|
func IsErrTwoFactorNotFound(err error) bool {
|
||||||
_, ok := err.(ErrTwoFactorNotFound)
|
return errors.As(err, &ErrTwoFactorNotFound{})
|
||||||
return ok
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func (err ErrTwoFactorNotFound) Error() string {
|
func (err ErrTwoFactorNotFound) Error() string {
|
||||||
@ -100,11 +90,13 @@ func (ErrTwoFactorNotFound) NotFound() bool {
|
|||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *twoFactorsStore) GetByUserID(ctx context.Context, userID int64) (*TwoFactor, error) {
|
// GetByUserID returns the 2FA token of given user. It returns
|
||||||
|
// ErrTwoFactorNotFound when not found.
|
||||||
|
func (s *TwoFactorsStore) GetByUserID(ctx context.Context, userID int64) (*TwoFactor, error) {
|
||||||
tf := new(TwoFactor)
|
tf := new(TwoFactor)
|
||||||
err := s.WithContext(ctx).Where("user_id = ?", userID).First(tf).Error
|
err := s.db.WithContext(ctx).Where("user_id = ?", userID).First(tf).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
if err == gorm.ErrRecordNotFound {
|
if errors.Is(err, gorm.ErrRecordNotFound) {
|
||||||
return nil, ErrTwoFactorNotFound{args: errutil.Args{"userID": userID}}
|
return nil, ErrTwoFactorNotFound{args: errutil.Args{"userID": userID}}
|
||||||
}
|
}
|
||||||
return nil, err
|
return nil, err
|
||||||
@ -112,9 +104,10 @@ func (s *twoFactorsStore) GetByUserID(ctx context.Context, userID int64) (*TwoFa
|
|||||||
return tf, nil
|
return tf, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (s *twoFactorsStore) IsEnabled(ctx context.Context, userID int64) bool {
|
// IsEnabled returns true if the user has enabled 2FA.
|
||||||
|
func (s *TwoFactorsStore) IsEnabled(ctx context.Context, userID int64) bool {
|
||||||
var count int64
|
var count int64
|
||||||
err := s.WithContext(ctx).Model(new(TwoFactor)).Where("user_id = ?", userID).Count(&count).Error
|
err := s.db.WithContext(ctx).Model(new(TwoFactor)).Where("user_id = ?", userID).Count(&count).Error
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.Error("Failed to count two factors [user_id: %d]: %v", userID, err)
|
log.Error("Failed to count two factors [user_id: %d]: %v", userID, err)
|
||||||
}
|
}
|
||||||
|
@ -67,13 +67,13 @@ func TestTwoFactors(t *testing.T) {
|
|||||||
t.Parallel()
|
t.Parallel()
|
||||||
|
|
||||||
ctx := context.Background()
|
ctx := context.Background()
|
||||||
db := &twoFactorsStore{
|
s := &TwoFactorsStore{
|
||||||
DB: newTestDB(t, "twoFactorsStore"),
|
db: newTestDB(t, "TwoFactorsStore"),
|
||||||
}
|
}
|
||||||
|
|
||||||
for _, tc := range []struct {
|
for _, tc := range []struct {
|
||||||
name string
|
name string
|
||||||
test func(t *testing.T, ctx context.Context, db *twoFactorsStore)
|
test func(t *testing.T, ctx context.Context, s *TwoFactorsStore)
|
||||||
}{
|
}{
|
||||||
{"Create", twoFactorsCreate},
|
{"Create", twoFactorsCreate},
|
||||||
{"GetByUserID", twoFactorsGetByUserID},
|
{"GetByUserID", twoFactorsGetByUserID},
|
||||||
@ -81,10 +81,10 @@ func TestTwoFactors(t *testing.T) {
|
|||||||
} {
|
} {
|
||||||
t.Run(tc.name, func(t *testing.T) {
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
t.Cleanup(func() {
|
t.Cleanup(func() {
|
||||||
err := clearTables(t, db.DB)
|
err := clearTables(t, s.db)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
})
|
})
|
||||||
tc.test(t, ctx, db)
|
tc.test(t, ctx, s)
|
||||||
})
|
})
|
||||||
if t.Failed() {
|
if t.Failed() {
|
||||||
break
|
break
|
||||||
@ -92,43 +92,43 @@ func TestTwoFactors(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
func twoFactorsCreate(t *testing.T, ctx context.Context, db *twoFactorsStore) {
|
func twoFactorsCreate(t *testing.T, ctx context.Context, s *TwoFactorsStore) {
|
||||||
// Create a 2FA token
|
// Create a 2FA token
|
||||||
err := db.Create(ctx, 1, "secure-key", "secure-secret")
|
err := s.Create(ctx, 1, "secure-key", "secure-secret")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Get it back and check the Created field
|
// Get it back and check the Created field
|
||||||
tf, err := db.GetByUserID(ctx, 1)
|
tf, err := s.GetByUserID(ctx, 1)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, db.NowFunc().Format(time.RFC3339), tf.Created.UTC().Format(time.RFC3339))
|
assert.Equal(t, s.db.NowFunc().Format(time.RFC3339), tf.Created.UTC().Format(time.RFC3339))
|
||||||
|
|
||||||
// Verify there are 10 recover codes generated
|
// Verify there are 10 recover codes generated
|
||||||
var count int64
|
var count int64
|
||||||
err = db.Model(new(TwoFactorRecoveryCode)).Count(&count).Error
|
err = s.db.Model(new(TwoFactorRecoveryCode)).Count(&count).Error
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
assert.Equal(t, int64(10), count)
|
assert.Equal(t, int64(10), count)
|
||||||
}
|
}
|
||||||
|
|
||||||
func twoFactorsGetByUserID(t *testing.T, ctx context.Context, db *twoFactorsStore) {
|
func twoFactorsGetByUserID(t *testing.T, ctx context.Context, s *TwoFactorsStore) {
|
||||||
// Create a 2FA token for user 1
|
// Create a 2FA token for user 1
|
||||||
err := db.Create(ctx, 1, "secure-key", "secure-secret")
|
err := s.Create(ctx, 1, "secure-key", "secure-secret")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// We should be able to get it back
|
// We should be able to get it back
|
||||||
_, err = db.GetByUserID(ctx, 1)
|
_, err = s.GetByUserID(ctx, 1)
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
// Try to get a non-existent 2FA token
|
// Try to get a non-existent 2FA token
|
||||||
_, err = db.GetByUserID(ctx, 2)
|
_, err = s.GetByUserID(ctx, 2)
|
||||||
wantErr := ErrTwoFactorNotFound{args: errutil.Args{"userID": int64(2)}}
|
wantErr := ErrTwoFactorNotFound{args: errutil.Args{"userID": int64(2)}}
|
||||||
assert.Equal(t, wantErr, err)
|
assert.Equal(t, wantErr, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func twoFactorsIsEnabled(t *testing.T, ctx context.Context, db *twoFactorsStore) {
|
func twoFactorsIsEnabled(t *testing.T, ctx context.Context, s *TwoFactorsStore) {
|
||||||
// Create a 2FA token for user 1
|
// Create a 2FA token for user 1
|
||||||
err := db.Create(ctx, 1, "secure-key", "secure-secret")
|
err := s.Create(ctx, 1, "secure-key", "secure-secret")
|
||||||
require.NoError(t, err)
|
require.NoError(t, err)
|
||||||
|
|
||||||
assert.True(t, db.IsEnabled(ctx, 1))
|
assert.True(t, s.IsEnabled(ctx, 1))
|
||||||
assert.False(t, db.IsEnabled(ctx, 2))
|
assert.False(t, s.IsEnabled(ctx, 2))
|
||||||
}
|
}
|
||||||
|
@ -14,407 +14,6 @@ import (
|
|||||||
lfsutil "gogs.io/gogs/internal/lfsutil"
|
lfsutil "gogs.io/gogs/internal/lfsutil"
|
||||||
)
|
)
|
||||||
|
|
||||||
// MockTwoFactorsStore is a mock implementation of the TwoFactorsStore
|
|
||||||
// interface (from the package gogs.io/gogs/internal/database) used for unit
|
|
||||||
// testing.
|
|
||||||
type MockTwoFactorsStore struct {
|
|
||||||
// CreateFunc is an instance of a mock function object controlling the
|
|
||||||
// behavior of the method Create.
|
|
||||||
CreateFunc *TwoFactorsStoreCreateFunc
|
|
||||||
// GetByUserIDFunc is an instance of a mock function object controlling
|
|
||||||
// the behavior of the method GetByUserID.
|
|
||||||
GetByUserIDFunc *TwoFactorsStoreGetByUserIDFunc
|
|
||||||
// IsEnabledFunc is an instance of a mock function object controlling
|
|
||||||
// the behavior of the method IsEnabled.
|
|
||||||
IsEnabledFunc *TwoFactorsStoreIsEnabledFunc
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewMockTwoFactorsStore creates a new mock of the TwoFactorsStore
|
|
||||||
// interface. All methods return zero values for all results, unless
|
|
||||||
// overwritten.
|
|
||||||
func NewMockTwoFactorsStore() *MockTwoFactorsStore {
|
|
||||||
return &MockTwoFactorsStore{
|
|
||||||
CreateFunc: &TwoFactorsStoreCreateFunc{
|
|
||||||
defaultHook: func(context.Context, int64, string, string) (r0 error) {
|
|
||||||
return
|
|
||||||
},
|
|
||||||
},
|
|
||||||
GetByUserIDFunc: &TwoFactorsStoreGetByUserIDFunc{
|
|
||||||
defaultHook: func(context.Context, int64) (r0 *database.TwoFactor, r1 error) {
|
|
||||||
return
|
|
||||||
},
|
|
||||||
},
|
|
||||||
IsEnabledFunc: &TwoFactorsStoreIsEnabledFunc{
|
|
||||||
defaultHook: func(context.Context, int64) (r0 bool) {
|
|
||||||
return
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewStrictMockTwoFactorsStore creates a new mock of the TwoFactorsStore
|
|
||||||
// interface. All methods panic on invocation, unless overwritten.
|
|
||||||
func NewStrictMockTwoFactorsStore() *MockTwoFactorsStore {
|
|
||||||
return &MockTwoFactorsStore{
|
|
||||||
CreateFunc: &TwoFactorsStoreCreateFunc{
|
|
||||||
defaultHook: func(context.Context, int64, string, string) error {
|
|
||||||
panic("unexpected invocation of MockTwoFactorsStore.Create")
|
|
||||||
},
|
|
||||||
},
|
|
||||||
GetByUserIDFunc: &TwoFactorsStoreGetByUserIDFunc{
|
|
||||||
defaultHook: func(context.Context, int64) (*database.TwoFactor, error) {
|
|
||||||
panic("unexpected invocation of MockTwoFactorsStore.GetByUserID")
|
|
||||||
},
|
|
||||||
},
|
|
||||||
IsEnabledFunc: &TwoFactorsStoreIsEnabledFunc{
|
|
||||||
defaultHook: func(context.Context, int64) bool {
|
|
||||||
panic("unexpected invocation of MockTwoFactorsStore.IsEnabled")
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// NewMockTwoFactorsStoreFrom creates a new mock of the MockTwoFactorsStore
|
|
||||||
// interface. All methods delegate to the given implementation, unless
|
|
||||||
// overwritten.
|
|
||||||
func NewMockTwoFactorsStoreFrom(i database.TwoFactorsStore) *MockTwoFactorsStore {
|
|
||||||
return &MockTwoFactorsStore{
|
|
||||||
CreateFunc: &TwoFactorsStoreCreateFunc{
|
|
||||||
defaultHook: i.Create,
|
|
||||||
},
|
|
||||||
GetByUserIDFunc: &TwoFactorsStoreGetByUserIDFunc{
|
|
||||||
defaultHook: i.GetByUserID,
|
|
||||||
},
|
|
||||||
IsEnabledFunc: &TwoFactorsStoreIsEnabledFunc{
|
|
||||||
defaultHook: i.IsEnabled,
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TwoFactorsStoreCreateFunc describes the behavior when the Create method
|
|
||||||
// of the parent MockTwoFactorsStore instance is invoked.
|
|
||||||
type TwoFactorsStoreCreateFunc struct {
|
|
||||||
defaultHook func(context.Context, int64, string, string) error
|
|
||||||
hooks []func(context.Context, int64, string, string) error
|
|
||||||
history []TwoFactorsStoreCreateFuncCall
|
|
||||||
mutex sync.Mutex
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create delegates to the next hook function in the queue and stores the
|
|
||||||
// parameter and result values of this invocation.
|
|
||||||
func (m *MockTwoFactorsStore) Create(v0 context.Context, v1 int64, v2 string, v3 string) error {
|
|
||||||
r0 := m.CreateFunc.nextHook()(v0, v1, v2, v3)
|
|
||||||
m.CreateFunc.appendCall(TwoFactorsStoreCreateFuncCall{v0, v1, v2, v3, r0})
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetDefaultHook sets function that is called when the Create method of the
|
|
||||||
// parent MockTwoFactorsStore instance is invoked and the hook queue is
|
|
||||||
// empty.
|
|
||||||
func (f *TwoFactorsStoreCreateFunc) SetDefaultHook(hook func(context.Context, int64, string, string) error) {
|
|
||||||
f.defaultHook = hook
|
|
||||||
}
|
|
||||||
|
|
||||||
// PushHook adds a function to the end of hook queue. Each invocation of the
|
|
||||||
// Create method of the parent MockTwoFactorsStore instance invokes the hook
|
|
||||||
// at the front of the queue and discards it. After the queue is empty, the
|
|
||||||
// default hook function is invoked for any future action.
|
|
||||||
func (f *TwoFactorsStoreCreateFunc) PushHook(hook func(context.Context, int64, string, string) error) {
|
|
||||||
f.mutex.Lock()
|
|
||||||
f.hooks = append(f.hooks, hook)
|
|
||||||
f.mutex.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetDefaultReturn calls SetDefaultHook with a function that returns the
|
|
||||||
// given values.
|
|
||||||
func (f *TwoFactorsStoreCreateFunc) SetDefaultReturn(r0 error) {
|
|
||||||
f.SetDefaultHook(func(context.Context, int64, string, string) error {
|
|
||||||
return r0
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// PushReturn calls PushHook with a function that returns the given values.
|
|
||||||
func (f *TwoFactorsStoreCreateFunc) PushReturn(r0 error) {
|
|
||||||
f.PushHook(func(context.Context, int64, string, string) error {
|
|
||||||
return r0
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *TwoFactorsStoreCreateFunc) nextHook() func(context.Context, int64, string, string) error {
|
|
||||||
f.mutex.Lock()
|
|
||||||
defer f.mutex.Unlock()
|
|
||||||
|
|
||||||
if len(f.hooks) == 0 {
|
|
||||||
return f.defaultHook
|
|
||||||
}
|
|
||||||
|
|
||||||
hook := f.hooks[0]
|
|
||||||
f.hooks = f.hooks[1:]
|
|
||||||
return hook
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *TwoFactorsStoreCreateFunc) appendCall(r0 TwoFactorsStoreCreateFuncCall) {
|
|
||||||
f.mutex.Lock()
|
|
||||||
f.history = append(f.history, r0)
|
|
||||||
f.mutex.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
// History returns a sequence of TwoFactorsStoreCreateFuncCall objects
|
|
||||||
// describing the invocations of this function.
|
|
||||||
func (f *TwoFactorsStoreCreateFunc) History() []TwoFactorsStoreCreateFuncCall {
|
|
||||||
f.mutex.Lock()
|
|
||||||
history := make([]TwoFactorsStoreCreateFuncCall, len(f.history))
|
|
||||||
copy(history, f.history)
|
|
||||||
f.mutex.Unlock()
|
|
||||||
|
|
||||||
return history
|
|
||||||
}
|
|
||||||
|
|
||||||
// TwoFactorsStoreCreateFuncCall is an object that describes an invocation
|
|
||||||
// of method Create on an instance of MockTwoFactorsStore.
|
|
||||||
type TwoFactorsStoreCreateFuncCall struct {
|
|
||||||
// Arg0 is the value of the 1st argument passed to this method
|
|
||||||
// invocation.
|
|
||||||
Arg0 context.Context
|
|
||||||
// Arg1 is the value of the 2nd argument passed to this method
|
|
||||||
// invocation.
|
|
||||||
Arg1 int64
|
|
||||||
// Arg2 is the value of the 3rd argument passed to this method
|
|
||||||
// invocation.
|
|
||||||
Arg2 string
|
|
||||||
// Arg3 is the value of the 4th argument passed to this method
|
|
||||||
// invocation.
|
|
||||||
Arg3 string
|
|
||||||
// Result0 is the value of the 1st result returned from this method
|
|
||||||
// invocation.
|
|
||||||
Result0 error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Args returns an interface slice containing the arguments of this
|
|
||||||
// invocation.
|
|
||||||
func (c TwoFactorsStoreCreateFuncCall) Args() []interface{} {
|
|
||||||
return []interface{}{c.Arg0, c.Arg1, c.Arg2, c.Arg3}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Results returns an interface slice containing the results of this
|
|
||||||
// invocation.
|
|
||||||
func (c TwoFactorsStoreCreateFuncCall) Results() []interface{} {
|
|
||||||
return []interface{}{c.Result0}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TwoFactorsStoreGetByUserIDFunc describes the behavior when the
|
|
||||||
// GetByUserID method of the parent MockTwoFactorsStore instance is invoked.
|
|
||||||
type TwoFactorsStoreGetByUserIDFunc struct {
|
|
||||||
defaultHook func(context.Context, int64) (*database.TwoFactor, error)
|
|
||||||
hooks []func(context.Context, int64) (*database.TwoFactor, error)
|
|
||||||
history []TwoFactorsStoreGetByUserIDFuncCall
|
|
||||||
mutex sync.Mutex
|
|
||||||
}
|
|
||||||
|
|
||||||
// GetByUserID delegates to the next hook function in the queue and stores
|
|
||||||
// the parameter and result values of this invocation.
|
|
||||||
func (m *MockTwoFactorsStore) GetByUserID(v0 context.Context, v1 int64) (*database.TwoFactor, error) {
|
|
||||||
r0, r1 := m.GetByUserIDFunc.nextHook()(v0, v1)
|
|
||||||
m.GetByUserIDFunc.appendCall(TwoFactorsStoreGetByUserIDFuncCall{v0, v1, r0, r1})
|
|
||||||
return r0, r1
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetDefaultHook sets function that is called when the GetByUserID method
|
|
||||||
// of the parent MockTwoFactorsStore instance is invoked and the hook queue
|
|
||||||
// is empty.
|
|
||||||
func (f *TwoFactorsStoreGetByUserIDFunc) SetDefaultHook(hook func(context.Context, int64) (*database.TwoFactor, error)) {
|
|
||||||
f.defaultHook = hook
|
|
||||||
}
|
|
||||||
|
|
||||||
// PushHook adds a function to the end of hook queue. Each invocation of the
|
|
||||||
// GetByUserID method of the parent MockTwoFactorsStore instance invokes the
|
|
||||||
// hook at the front of the queue and discards it. After the queue is empty,
|
|
||||||
// the default hook function is invoked for any future action.
|
|
||||||
func (f *TwoFactorsStoreGetByUserIDFunc) PushHook(hook func(context.Context, int64) (*database.TwoFactor, error)) {
|
|
||||||
f.mutex.Lock()
|
|
||||||
f.hooks = append(f.hooks, hook)
|
|
||||||
f.mutex.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetDefaultReturn calls SetDefaultHook with a function that returns the
|
|
||||||
// given values.
|
|
||||||
func (f *TwoFactorsStoreGetByUserIDFunc) SetDefaultReturn(r0 *database.TwoFactor, r1 error) {
|
|
||||||
f.SetDefaultHook(func(context.Context, int64) (*database.TwoFactor, error) {
|
|
||||||
return r0, r1
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// PushReturn calls PushHook with a function that returns the given values.
|
|
||||||
func (f *TwoFactorsStoreGetByUserIDFunc) PushReturn(r0 *database.TwoFactor, r1 error) {
|
|
||||||
f.PushHook(func(context.Context, int64) (*database.TwoFactor, error) {
|
|
||||||
return r0, r1
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *TwoFactorsStoreGetByUserIDFunc) nextHook() func(context.Context, int64) (*database.TwoFactor, error) {
|
|
||||||
f.mutex.Lock()
|
|
||||||
defer f.mutex.Unlock()
|
|
||||||
|
|
||||||
if len(f.hooks) == 0 {
|
|
||||||
return f.defaultHook
|
|
||||||
}
|
|
||||||
|
|
||||||
hook := f.hooks[0]
|
|
||||||
f.hooks = f.hooks[1:]
|
|
||||||
return hook
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *TwoFactorsStoreGetByUserIDFunc) appendCall(r0 TwoFactorsStoreGetByUserIDFuncCall) {
|
|
||||||
f.mutex.Lock()
|
|
||||||
f.history = append(f.history, r0)
|
|
||||||
f.mutex.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
// History returns a sequence of TwoFactorsStoreGetByUserIDFuncCall objects
|
|
||||||
// describing the invocations of this function.
|
|
||||||
func (f *TwoFactorsStoreGetByUserIDFunc) History() []TwoFactorsStoreGetByUserIDFuncCall {
|
|
||||||
f.mutex.Lock()
|
|
||||||
history := make([]TwoFactorsStoreGetByUserIDFuncCall, len(f.history))
|
|
||||||
copy(history, f.history)
|
|
||||||
f.mutex.Unlock()
|
|
||||||
|
|
||||||
return history
|
|
||||||
}
|
|
||||||
|
|
||||||
// TwoFactorsStoreGetByUserIDFuncCall is an object that describes an
|
|
||||||
// invocation of method GetByUserID on an instance of MockTwoFactorsStore.
|
|
||||||
type TwoFactorsStoreGetByUserIDFuncCall struct {
|
|
||||||
// Arg0 is the value of the 1st argument passed to this method
|
|
||||||
// invocation.
|
|
||||||
Arg0 context.Context
|
|
||||||
// Arg1 is the value of the 2nd argument passed to this method
|
|
||||||
// invocation.
|
|
||||||
Arg1 int64
|
|
||||||
// Result0 is the value of the 1st result returned from this method
|
|
||||||
// invocation.
|
|
||||||
Result0 *database.TwoFactor
|
|
||||||
// Result1 is the value of the 2nd result returned from this method
|
|
||||||
// invocation.
|
|
||||||
Result1 error
|
|
||||||
}
|
|
||||||
|
|
||||||
// Args returns an interface slice containing the arguments of this
|
|
||||||
// invocation.
|
|
||||||
func (c TwoFactorsStoreGetByUserIDFuncCall) Args() []interface{} {
|
|
||||||
return []interface{}{c.Arg0, c.Arg1}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Results returns an interface slice containing the results of this
|
|
||||||
// invocation.
|
|
||||||
func (c TwoFactorsStoreGetByUserIDFuncCall) Results() []interface{} {
|
|
||||||
return []interface{}{c.Result0, c.Result1}
|
|
||||||
}
|
|
||||||
|
|
||||||
// TwoFactorsStoreIsEnabledFunc describes the behavior when the IsEnabled
|
|
||||||
// method of the parent MockTwoFactorsStore instance is invoked.
|
|
||||||
type TwoFactorsStoreIsEnabledFunc struct {
|
|
||||||
defaultHook func(context.Context, int64) bool
|
|
||||||
hooks []func(context.Context, int64) bool
|
|
||||||
history []TwoFactorsStoreIsEnabledFuncCall
|
|
||||||
mutex sync.Mutex
|
|
||||||
}
|
|
||||||
|
|
||||||
// IsEnabled delegates to the next hook function in the queue and stores the
|
|
||||||
// parameter and result values of this invocation.
|
|
||||||
func (m *MockTwoFactorsStore) IsEnabled(v0 context.Context, v1 int64) bool {
|
|
||||||
r0 := m.IsEnabledFunc.nextHook()(v0, v1)
|
|
||||||
m.IsEnabledFunc.appendCall(TwoFactorsStoreIsEnabledFuncCall{v0, v1, r0})
|
|
||||||
return r0
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetDefaultHook sets function that is called when the IsEnabled method of
|
|
||||||
// the parent MockTwoFactorsStore instance is invoked and the hook queue is
|
|
||||||
// empty.
|
|
||||||
func (f *TwoFactorsStoreIsEnabledFunc) SetDefaultHook(hook func(context.Context, int64) bool) {
|
|
||||||
f.defaultHook = hook
|
|
||||||
}
|
|
||||||
|
|
||||||
// PushHook adds a function to the end of hook queue. Each invocation of the
|
|
||||||
// IsEnabled method of the parent MockTwoFactorsStore instance invokes the
|
|
||||||
// hook at the front of the queue and discards it. After the queue is empty,
|
|
||||||
// the default hook function is invoked for any future action.
|
|
||||||
func (f *TwoFactorsStoreIsEnabledFunc) PushHook(hook func(context.Context, int64) bool) {
|
|
||||||
f.mutex.Lock()
|
|
||||||
f.hooks = append(f.hooks, hook)
|
|
||||||
f.mutex.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
// SetDefaultReturn calls SetDefaultHook with a function that returns the
|
|
||||||
// given values.
|
|
||||||
func (f *TwoFactorsStoreIsEnabledFunc) SetDefaultReturn(r0 bool) {
|
|
||||||
f.SetDefaultHook(func(context.Context, int64) bool {
|
|
||||||
return r0
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
// PushReturn calls PushHook with a function that returns the given values.
|
|
||||||
func (f *TwoFactorsStoreIsEnabledFunc) PushReturn(r0 bool) {
|
|
||||||
f.PushHook(func(context.Context, int64) bool {
|
|
||||||
return r0
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *TwoFactorsStoreIsEnabledFunc) nextHook() func(context.Context, int64) bool {
|
|
||||||
f.mutex.Lock()
|
|
||||||
defer f.mutex.Unlock()
|
|
||||||
|
|
||||||
if len(f.hooks) == 0 {
|
|
||||||
return f.defaultHook
|
|
||||||
}
|
|
||||||
|
|
||||||
hook := f.hooks[0]
|
|
||||||
f.hooks = f.hooks[1:]
|
|
||||||
return hook
|
|
||||||
}
|
|
||||||
|
|
||||||
func (f *TwoFactorsStoreIsEnabledFunc) appendCall(r0 TwoFactorsStoreIsEnabledFuncCall) {
|
|
||||||
f.mutex.Lock()
|
|
||||||
f.history = append(f.history, r0)
|
|
||||||
f.mutex.Unlock()
|
|
||||||
}
|
|
||||||
|
|
||||||
// History returns a sequence of TwoFactorsStoreIsEnabledFuncCall objects
|
|
||||||
// describing the invocations of this function.
|
|
||||||
func (f *TwoFactorsStoreIsEnabledFunc) History() []TwoFactorsStoreIsEnabledFuncCall {
|
|
||||||
f.mutex.Lock()
|
|
||||||
history := make([]TwoFactorsStoreIsEnabledFuncCall, len(f.history))
|
|
||||||
copy(history, f.history)
|
|
||||||
f.mutex.Unlock()
|
|
||||||
|
|
||||||
return history
|
|
||||||
}
|
|
||||||
|
|
||||||
// TwoFactorsStoreIsEnabledFuncCall is an object that describes an
|
|
||||||
// invocation of method IsEnabled on an instance of MockTwoFactorsStore.
|
|
||||||
type TwoFactorsStoreIsEnabledFuncCall struct {
|
|
||||||
// Arg0 is the value of the 1st argument passed to this method
|
|
||||||
// invocation.
|
|
||||||
Arg0 context.Context
|
|
||||||
// Arg1 is the value of the 2nd argument passed to this method
|
|
||||||
// invocation.
|
|
||||||
Arg1 int64
|
|
||||||
// Result0 is the value of the 1st result returned from this method
|
|
||||||
// invocation.
|
|
||||||
Result0 bool
|
|
||||||
}
|
|
||||||
|
|
||||||
// Args returns an interface slice containing the arguments of this
|
|
||||||
// invocation.
|
|
||||||
func (c TwoFactorsStoreIsEnabledFuncCall) Args() []interface{} {
|
|
||||||
return []interface{}{c.Arg0, c.Arg1}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Results returns an interface slice containing the results of this
|
|
||||||
// invocation.
|
|
||||||
func (c TwoFactorsStoreIsEnabledFuncCall) Results() []interface{} {
|
|
||||||
return []interface{}{c.Result0}
|
|
||||||
}
|
|
||||||
|
|
||||||
// MockUsersStore is a mock implementation of the UsersStore interface (from
|
// MockUsersStore is a mock implementation of the UsersStore interface (from
|
||||||
// the package gogs.io/gogs/internal/database) used for unit testing.
|
// the package gogs.io/gogs/internal/database) used for unit testing.
|
||||||
type MockUsersStore struct {
|
type MockUsersStore struct {
|
||||||
@ -3968,6 +3567,9 @@ type MockStore struct {
|
|||||||
// GetRepositoryByNameFunc is an instance of a mock function object
|
// GetRepositoryByNameFunc is an instance of a mock function object
|
||||||
// controlling the behavior of the method GetRepositoryByName.
|
// controlling the behavior of the method GetRepositoryByName.
|
||||||
GetRepositoryByNameFunc *StoreGetRepositoryByNameFunc
|
GetRepositoryByNameFunc *StoreGetRepositoryByNameFunc
|
||||||
|
// IsTwoFactorEnabledFunc is an instance of a mock function object
|
||||||
|
// controlling the behavior of the method IsTwoFactorEnabled.
|
||||||
|
IsTwoFactorEnabledFunc *StoreIsTwoFactorEnabledFunc
|
||||||
// TouchAccessTokenByIDFunc is an instance of a mock function object
|
// TouchAccessTokenByIDFunc is an instance of a mock function object
|
||||||
// controlling the behavior of the method TouchAccessTokenByID.
|
// controlling the behavior of the method TouchAccessTokenByID.
|
||||||
TouchAccessTokenByIDFunc *StoreTouchAccessTokenByIDFunc
|
TouchAccessTokenByIDFunc *StoreTouchAccessTokenByIDFunc
|
||||||
@ -4007,6 +3609,11 @@ func NewMockStore() *MockStore {
|
|||||||
return
|
return
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
IsTwoFactorEnabledFunc: &StoreIsTwoFactorEnabledFunc{
|
||||||
|
defaultHook: func(context.Context, int64) (r0 bool) {
|
||||||
|
return
|
||||||
|
},
|
||||||
|
},
|
||||||
TouchAccessTokenByIDFunc: &StoreTouchAccessTokenByIDFunc{
|
TouchAccessTokenByIDFunc: &StoreTouchAccessTokenByIDFunc{
|
||||||
defaultHook: func(context.Context, int64) (r0 error) {
|
defaultHook: func(context.Context, int64) (r0 error) {
|
||||||
return
|
return
|
||||||
@ -4049,6 +3656,11 @@ func NewStrictMockStore() *MockStore {
|
|||||||
panic("unexpected invocation of MockStore.GetRepositoryByName")
|
panic("unexpected invocation of MockStore.GetRepositoryByName")
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
IsTwoFactorEnabledFunc: &StoreIsTwoFactorEnabledFunc{
|
||||||
|
defaultHook: func(context.Context, int64) bool {
|
||||||
|
panic("unexpected invocation of MockStore.IsTwoFactorEnabled")
|
||||||
|
},
|
||||||
|
},
|
||||||
TouchAccessTokenByIDFunc: &StoreTouchAccessTokenByIDFunc{
|
TouchAccessTokenByIDFunc: &StoreTouchAccessTokenByIDFunc{
|
||||||
defaultHook: func(context.Context, int64) error {
|
defaultHook: func(context.Context, int64) error {
|
||||||
panic("unexpected invocation of MockStore.TouchAccessTokenByID")
|
panic("unexpected invocation of MockStore.TouchAccessTokenByID")
|
||||||
@ -4079,6 +3691,9 @@ func NewMockStoreFrom(i Store) *MockStore {
|
|||||||
GetRepositoryByNameFunc: &StoreGetRepositoryByNameFunc{
|
GetRepositoryByNameFunc: &StoreGetRepositoryByNameFunc{
|
||||||
defaultHook: i.GetRepositoryByName,
|
defaultHook: i.GetRepositoryByName,
|
||||||
},
|
},
|
||||||
|
IsTwoFactorEnabledFunc: &StoreIsTwoFactorEnabledFunc{
|
||||||
|
defaultHook: i.IsTwoFactorEnabled,
|
||||||
|
},
|
||||||
TouchAccessTokenByIDFunc: &StoreTouchAccessTokenByIDFunc{
|
TouchAccessTokenByIDFunc: &StoreTouchAccessTokenByIDFunc{
|
||||||
defaultHook: i.TouchAccessTokenByID,
|
defaultHook: i.TouchAccessTokenByID,
|
||||||
},
|
},
|
||||||
@ -4763,6 +4378,111 @@ func (c StoreGetRepositoryByNameFuncCall) Results() []interface{} {
|
|||||||
return []interface{}{c.Result0, c.Result1}
|
return []interface{}{c.Result0, c.Result1}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// StoreIsTwoFactorEnabledFunc describes the behavior when the
|
||||||
|
// IsTwoFactorEnabled method of the parent MockStore instance is invoked.
|
||||||
|
type StoreIsTwoFactorEnabledFunc struct {
|
||||||
|
defaultHook func(context.Context, int64) bool
|
||||||
|
hooks []func(context.Context, int64) bool
|
||||||
|
history []StoreIsTwoFactorEnabledFuncCall
|
||||||
|
mutex sync.Mutex
|
||||||
|
}
|
||||||
|
|
||||||
|
// IsTwoFactorEnabled delegates to the next hook function in the queue and
|
||||||
|
// stores the parameter and result values of this invocation.
|
||||||
|
func (m *MockStore) IsTwoFactorEnabled(v0 context.Context, v1 int64) bool {
|
||||||
|
r0 := m.IsTwoFactorEnabledFunc.nextHook()(v0, v1)
|
||||||
|
m.IsTwoFactorEnabledFunc.appendCall(StoreIsTwoFactorEnabledFuncCall{v0, v1, r0})
|
||||||
|
return r0
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDefaultHook sets function that is called when the IsTwoFactorEnabled
|
||||||
|
// method of the parent MockStore instance is invoked and the hook queue is
|
||||||
|
// empty.
|
||||||
|
func (f *StoreIsTwoFactorEnabledFunc) SetDefaultHook(hook func(context.Context, int64) bool) {
|
||||||
|
f.defaultHook = hook
|
||||||
|
}
|
||||||
|
|
||||||
|
// PushHook adds a function to the end of hook queue. Each invocation of the
|
||||||
|
// IsTwoFactorEnabled method of the parent MockStore instance invokes the
|
||||||
|
// hook at the front of the queue and discards it. After the queue is empty,
|
||||||
|
// the default hook function is invoked for any future action.
|
||||||
|
func (f *StoreIsTwoFactorEnabledFunc) PushHook(hook func(context.Context, int64) bool) {
|
||||||
|
f.mutex.Lock()
|
||||||
|
f.hooks = append(f.hooks, hook)
|
||||||
|
f.mutex.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// SetDefaultReturn calls SetDefaultHook with a function that returns the
|
||||||
|
// given values.
|
||||||
|
func (f *StoreIsTwoFactorEnabledFunc) SetDefaultReturn(r0 bool) {
|
||||||
|
f.SetDefaultHook(func(context.Context, int64) bool {
|
||||||
|
return r0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
// PushReturn calls PushHook with a function that returns the given values.
|
||||||
|
func (f *StoreIsTwoFactorEnabledFunc) PushReturn(r0 bool) {
|
||||||
|
f.PushHook(func(context.Context, int64) bool {
|
||||||
|
return r0
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *StoreIsTwoFactorEnabledFunc) nextHook() func(context.Context, int64) bool {
|
||||||
|
f.mutex.Lock()
|
||||||
|
defer f.mutex.Unlock()
|
||||||
|
|
||||||
|
if len(f.hooks) == 0 {
|
||||||
|
return f.defaultHook
|
||||||
|
}
|
||||||
|
|
||||||
|
hook := f.hooks[0]
|
||||||
|
f.hooks = f.hooks[1:]
|
||||||
|
return hook
|
||||||
|
}
|
||||||
|
|
||||||
|
func (f *StoreIsTwoFactorEnabledFunc) appendCall(r0 StoreIsTwoFactorEnabledFuncCall) {
|
||||||
|
f.mutex.Lock()
|
||||||
|
f.history = append(f.history, r0)
|
||||||
|
f.mutex.Unlock()
|
||||||
|
}
|
||||||
|
|
||||||
|
// History returns a sequence of StoreIsTwoFactorEnabledFuncCall objects
|
||||||
|
// describing the invocations of this function.
|
||||||
|
func (f *StoreIsTwoFactorEnabledFunc) History() []StoreIsTwoFactorEnabledFuncCall {
|
||||||
|
f.mutex.Lock()
|
||||||
|
history := make([]StoreIsTwoFactorEnabledFuncCall, len(f.history))
|
||||||
|
copy(history, f.history)
|
||||||
|
f.mutex.Unlock()
|
||||||
|
|
||||||
|
return history
|
||||||
|
}
|
||||||
|
|
||||||
|
// StoreIsTwoFactorEnabledFuncCall is an object that describes an invocation
|
||||||
|
// of method IsTwoFactorEnabled on an instance of MockStore.
|
||||||
|
type StoreIsTwoFactorEnabledFuncCall struct {
|
||||||
|
// Arg0 is the value of the 1st argument passed to this method
|
||||||
|
// invocation.
|
||||||
|
Arg0 context.Context
|
||||||
|
// Arg1 is the value of the 2nd argument passed to this method
|
||||||
|
// invocation.
|
||||||
|
Arg1 int64
|
||||||
|
// Result0 is the value of the 1st result returned from this method
|
||||||
|
// invocation.
|
||||||
|
Result0 bool
|
||||||
|
}
|
||||||
|
|
||||||
|
// Args returns an interface slice containing the arguments of this
|
||||||
|
// invocation.
|
||||||
|
func (c StoreIsTwoFactorEnabledFuncCall) Args() []interface{} {
|
||||||
|
return []interface{}{c.Arg0, c.Arg1}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Results returns an interface slice containing the results of this
|
||||||
|
// invocation.
|
||||||
|
func (c StoreIsTwoFactorEnabledFuncCall) Results() []interface{} {
|
||||||
|
return []interface{}{c.Result0}
|
||||||
|
}
|
||||||
|
|
||||||
// StoreTouchAccessTokenByIDFunc describes the behavior when the
|
// StoreTouchAccessTokenByIDFunc describes the behavior when the
|
||||||
// TouchAccessTokenByID method of the parent MockStore instance is invoked.
|
// TouchAccessTokenByID method of the parent MockStore instance is invoked.
|
||||||
type StoreTouchAccessTokenByIDFunc struct {
|
type StoreTouchAccessTokenByIDFunc struct {
|
||||||
|
@ -69,7 +69,7 @@ func authenticate(store Store) macaron.Handler {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err == nil && database.TwoFactors.IsEnabled(c.Req.Context(), user.ID) {
|
if err == nil && store.IsTwoFactorEnabled(c.Req.Context(), user.ID) {
|
||||||
c.Error(http.StatusBadRequest, "Users with 2FA enabled are not allowed to authenticate via username and password.")
|
c.Error(http.StatusBadRequest, "Users with 2FA enabled are not allowed to authenticate via username and password.")
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,6 @@ func TestAuthenticate(t *testing.T) {
|
|||||||
name string
|
name string
|
||||||
header http.Header
|
header http.Header
|
||||||
mockUsersStore func() database.UsersStore
|
mockUsersStore func() database.UsersStore
|
||||||
mockTwoFactorsStore func() database.TwoFactorsStore
|
|
||||||
mockStore func() *MockStore
|
mockStore func() *MockStore
|
||||||
expStatusCode int
|
expStatusCode int
|
||||||
expHeader http.Header
|
expHeader http.Header
|
||||||
@ -50,10 +49,10 @@ func TestAuthenticate(t *testing.T) {
|
|||||||
mock.AuthenticateFunc.SetDefaultReturn(&database.User{}, nil)
|
mock.AuthenticateFunc.SetDefaultReturn(&database.User{}, nil)
|
||||||
return mock
|
return mock
|
||||||
},
|
},
|
||||||
mockTwoFactorsStore: func() database.TwoFactorsStore {
|
mockStore: func() *MockStore {
|
||||||
mock := NewMockTwoFactorsStore()
|
mockStore := NewMockStore()
|
||||||
mock.IsEnabledFunc.SetDefaultReturn(true)
|
mockStore.IsTwoFactorEnabledFunc.SetDefaultReturn(true)
|
||||||
return mock
|
return mockStore
|
||||||
},
|
},
|
||||||
expStatusCode: http.StatusBadRequest,
|
expStatusCode: http.StatusBadRequest,
|
||||||
expHeader: http.Header{},
|
expHeader: http.Header{},
|
||||||
@ -92,10 +91,10 @@ func TestAuthenticate(t *testing.T) {
|
|||||||
mock.AuthenticateFunc.SetDefaultReturn(&database.User{ID: 1, Name: "unknwon"}, nil)
|
mock.AuthenticateFunc.SetDefaultReturn(&database.User{ID: 1, Name: "unknwon"}, nil)
|
||||||
return mock
|
return mock
|
||||||
},
|
},
|
||||||
mockTwoFactorsStore: func() database.TwoFactorsStore {
|
mockStore: func() *MockStore {
|
||||||
mock := NewMockTwoFactorsStore()
|
mockStore := NewMockStore()
|
||||||
mock.IsEnabledFunc.SetDefaultReturn(false)
|
mockStore.IsTwoFactorEnabledFunc.SetDefaultReturn(false)
|
||||||
return mock
|
return mockStore
|
||||||
},
|
},
|
||||||
expStatusCode: http.StatusOK,
|
expStatusCode: http.StatusOK,
|
||||||
expHeader: http.Header{},
|
expHeader: http.Header{},
|
||||||
@ -152,9 +151,6 @@ func TestAuthenticate(t *testing.T) {
|
|||||||
if test.mockUsersStore != nil {
|
if test.mockUsersStore != nil {
|
||||||
database.SetMockUsersStore(t, test.mockUsersStore())
|
database.SetMockUsersStore(t, test.mockUsersStore())
|
||||||
}
|
}
|
||||||
if test.mockTwoFactorsStore != nil {
|
|
||||||
database.SetMockTwoFactorsStore(t, test.mockTwoFactorsStore())
|
|
||||||
}
|
|
||||||
if test.mockStore == nil {
|
if test.mockStore == nil {
|
||||||
test.mockStore = NewMockStore
|
test.mockStore = NewMockStore
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,9 @@ type Store interface {
|
|||||||
// GetRepositoryByName returns the repository with given owner and name. It
|
// GetRepositoryByName returns the repository with given owner and name. It
|
||||||
// returns database.ErrRepoNotExist when not found.
|
// returns database.ErrRepoNotExist when not found.
|
||||||
GetRepositoryByName(ctx context.Context, ownerID int64, name string) (*database.Repository, error)
|
GetRepositoryByName(ctx context.Context, ownerID int64, name string) (*database.Repository, error)
|
||||||
|
|
||||||
|
// IsTwoFactorEnabled returns true if the user has enabled 2FA.
|
||||||
|
IsTwoFactorEnabled(ctx context.Context, userID int64) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type store struct{}
|
type store struct{}
|
||||||
@ -70,3 +73,7 @@ func (*store) AuthorizeRepositoryAccess(ctx context.Context, userID, repoID int6
|
|||||||
func (*store) GetRepositoryByName(ctx context.Context, ownerID int64, name string) (*database.Repository, error) {
|
func (*store) GetRepositoryByName(ctx context.Context, ownerID int64, name string) (*database.Repository, error) {
|
||||||
return database.Handle.Repositories().GetByName(ctx, ownerID, name)
|
return database.Handle.Repositories().GetByName(ctx, ownerID, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*store) IsTwoFactorEnabled(ctx context.Context, userID int64) bool {
|
||||||
|
return database.Handle.TwoFactors().IsEnabled(ctx, userID)
|
||||||
|
}
|
||||||
|
@ -152,7 +152,7 @@ func HTTPContexter(store Store) macaron.Handler {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if database.TwoFactors.IsEnabled(c.Req.Context(), authUser.ID) {
|
} else if store.IsTwoFactorEnabled(c.Req.Context(), authUser.ID) {
|
||||||
askCredentials(c, http.StatusUnauthorized, `User with two-factor authentication enabled cannot perform HTTP/HTTPS operations via plain username and password
|
askCredentials(c, http.StatusUnauthorized, `User with two-factor authentication enabled cannot perform HTTP/HTTPS operations via plain username and password
|
||||||
Please create and use personal access token on user settings page`)
|
Please create and use personal access token on user settings page`)
|
||||||
return
|
return
|
||||||
|
@ -20,6 +20,9 @@ type Store interface {
|
|||||||
// GetRepositoryByName returns the repository with given owner and name. It
|
// GetRepositoryByName returns the repository with given owner and name. It
|
||||||
// returns database.ErrRepoNotExist when not found.
|
// returns database.ErrRepoNotExist when not found.
|
||||||
GetRepositoryByName(ctx context.Context, ownerID int64, name string) (*database.Repository, error)
|
GetRepositoryByName(ctx context.Context, ownerID int64, name string) (*database.Repository, error)
|
||||||
|
|
||||||
|
// IsTwoFactorEnabled returns true if the user has enabled 2FA.
|
||||||
|
IsTwoFactorEnabled(ctx context.Context, userID int64) bool
|
||||||
}
|
}
|
||||||
|
|
||||||
type store struct{}
|
type store struct{}
|
||||||
@ -40,3 +43,7 @@ func (*store) TouchAccessTokenByID(ctx context.Context, id int64) error {
|
|||||||
func (*store) GetRepositoryByName(ctx context.Context, ownerID int64, name string) (*database.Repository, error) {
|
func (*store) GetRepositoryByName(ctx context.Context, ownerID int64, name string) (*database.Repository, error) {
|
||||||
return database.Handle.Repositories().GetByName(ctx, ownerID, name)
|
return database.Handle.Repositories().GetByName(ctx, ownerID, name)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (*store) IsTwoFactorEnabled(ctx context.Context, userID int64) bool {
|
||||||
|
return database.Handle.TwoFactors().IsEnabled(ctx, userID)
|
||||||
|
}
|
||||||
|
@ -187,7 +187,7 @@ func LoginPost(c *context.Context, f form.SignIn) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if !database.TwoFactors.IsEnabled(c.Req.Context(), u.ID) {
|
if !database.Handle.TwoFactors().IsEnabled(c.Req.Context(), u.ID) {
|
||||||
afterLogin(c, u, f.Remember)
|
afterLogin(c, u, f.Remember)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -214,7 +214,7 @@ func LoginTwoFactorPost(c *context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
t, err := database.TwoFactors.GetByUserID(c.Req.Context(), userID)
|
t, err := database.Handle.TwoFactors().GetByUserID(c.Req.Context(), userID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
c.Error(err, "get two factor by user ID")
|
c.Error(err, "get two factor by user ID")
|
||||||
return
|
return
|
||||||
|
@ -398,7 +398,7 @@ func SettingsSecurity(c *context.Context) {
|
|||||||
c.Title("settings.security")
|
c.Title("settings.security")
|
||||||
c.PageIs("SettingsSecurity")
|
c.PageIs("SettingsSecurity")
|
||||||
|
|
||||||
t, err := database.TwoFactors.GetByUserID(c.Req.Context(), c.UserID())
|
t, err := database.Handle.TwoFactors().GetByUserID(c.Req.Context(), c.UserID())
|
||||||
if err != nil && !database.IsErrTwoFactorNotFound(err) {
|
if err != nil && !database.IsErrTwoFactorNotFound(err) {
|
||||||
c.Errorf(err, "get two factor by user ID")
|
c.Errorf(err, "get two factor by user ID")
|
||||||
return
|
return
|
||||||
@ -409,7 +409,7 @@ func SettingsSecurity(c *context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func SettingsTwoFactorEnable(c *context.Context) {
|
func SettingsTwoFactorEnable(c *context.Context) {
|
||||||
if database.TwoFactors.IsEnabled(c.Req.Context(), c.User.ID) {
|
if database.Handle.TwoFactors().IsEnabled(c.Req.Context(), c.User.ID) {
|
||||||
c.NotFound()
|
c.NotFound()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -466,7 +466,7 @@ func SettingsTwoFactorEnablePost(c *context.Context) {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
if err := database.TwoFactors.Create(c.Req.Context(), c.UserID(), conf.Security.SecretKey, secret); err != nil {
|
if err := database.Handle.TwoFactors().Create(c.Req.Context(), c.UserID(), conf.Security.SecretKey, secret); err != nil {
|
||||||
c.Flash.Error(c.Tr("settings.two_factor_enable_error", err))
|
c.Flash.Error(c.Tr("settings.two_factor_enable_error", err))
|
||||||
c.RedirectSubpath("/user/settings/security/two_factor_enable")
|
c.RedirectSubpath("/user/settings/security/two_factor_enable")
|
||||||
return
|
return
|
||||||
@ -479,7 +479,7 @@ func SettingsTwoFactorEnablePost(c *context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func SettingsTwoFactorRecoveryCodes(c *context.Context) {
|
func SettingsTwoFactorRecoveryCodes(c *context.Context) {
|
||||||
if !database.TwoFactors.IsEnabled(c.Req.Context(), c.User.ID) {
|
if !database.Handle.TwoFactors().IsEnabled(c.Req.Context(), c.User.ID) {
|
||||||
c.NotFound()
|
c.NotFound()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -498,7 +498,7 @@ func SettingsTwoFactorRecoveryCodes(c *context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func SettingsTwoFactorRecoveryCodesPost(c *context.Context) {
|
func SettingsTwoFactorRecoveryCodesPost(c *context.Context) {
|
||||||
if !database.TwoFactors.IsEnabled(c.Req.Context(), c.User.ID) {
|
if !database.Handle.TwoFactors().IsEnabled(c.Req.Context(), c.User.ID) {
|
||||||
c.NotFound()
|
c.NotFound()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
@ -513,7 +513,7 @@ func SettingsTwoFactorRecoveryCodesPost(c *context.Context) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
func SettingsTwoFactorDisable(c *context.Context) {
|
func SettingsTwoFactorDisable(c *context.Context) {
|
||||||
if !database.TwoFactors.IsEnabled(c.Req.Context(), c.User.ID) {
|
if !database.Handle.TwoFactors().IsEnabled(c.Req.Context(), c.User.ID) {
|
||||||
c.NotFound()
|
c.NotFound()
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
@ -37,7 +37,6 @@ mocks:
|
|||||||
- path: gogs.io/gogs/internal/database
|
- path: gogs.io/gogs/internal/database
|
||||||
interfaces:
|
interfaces:
|
||||||
- UsersStore
|
- UsersStore
|
||||||
- TwoFactorsStore
|
|
||||||
- path: gogs.io/gogs/internal/route/lfs
|
- path: gogs.io/gogs/internal/route/lfs
|
||||||
interfaces:
|
interfaces:
|
||||||
- Store
|
- Store
|
||||||
|
Loading…
x
Reference in New Issue
Block a user