Do not allow to reuse TOTP passcode (#3878)

release/v1.15
Lauris BH 2018-05-02 18:02:02 +03:00 committed by GitHub
parent c58e1e437b
commit 1e1ece8f3d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 38 additions and 7 deletions

View File

@ -176,6 +176,8 @@ var migrations = []Migration{
NewMigration("add is_fsck_enabled column for repos", addFsckEnabledToRepo), NewMigration("add is_fsck_enabled column for repos", addFsckEnabledToRepo),
// v61 -> v62 // v61 -> v62
NewMigration("add size column for attachments", addSizeToAttachment), NewMigration("add size column for attachments", addSizeToAttachment),
// v62 -> v63
NewMigration("add last used passcode column for TOTP", addLastUsedPasscodeTOTP),
} }
// Migrate database to current version // Migrate database to current version

22
models/migrations/v62.go Normal file
View File

@ -0,0 +1,22 @@
// Copyright 2018 The Gitea Authors. All rights reserved.
// Use of this source code is governed by a MIT-style
// license that can be found in the LICENSE file.
package migrations
import (
"fmt"
"github.com/go-xorm/xorm"
)
func addLastUsedPasscodeTOTP(x *xorm.Engine) error {
type TwoFactor struct {
LastUsedPasscode string `xorm:"VARCHAR(10)"`
}
if err := x.Sync2(new(TwoFactor)); err != nil {
return fmt.Errorf("Sync2: %v", err)
}
return nil
}

View File

@ -23,12 +23,13 @@ import (
// TwoFactor represents a two-factor authentication token. // TwoFactor represents a two-factor authentication token.
type TwoFactor struct { type TwoFactor struct {
ID int64 `xorm:"pk autoincr"` ID int64 `xorm:"pk autoincr"`
UID int64 `xorm:"UNIQUE"` UID int64 `xorm:"UNIQUE"`
Secret string Secret string
ScratchToken string ScratchToken string
CreatedUnix util.TimeStamp `xorm:"INDEX created"` LastUsedPasscode string `xorm:"VARCHAR(10)"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"` CreatedUnix util.TimeStamp `xorm:"INDEX created"`
UpdatedUnix util.TimeStamp `xorm:"INDEX updated"`
} }
// GenerateScratchToken recreates the scratch token the user is using. // GenerateScratchToken recreates the scratch token the user is using.

View File

@ -221,7 +221,7 @@ func TwoFactorPost(ctx *context.Context, form auth.TwoFactorAuthForm) {
return return
} }
if ok { if ok && twofa.LastUsedPasscode != form.Passcode {
remember := ctx.Session.Get("twofaRemember").(bool) remember := ctx.Session.Get("twofaRemember").(bool)
u, err := models.GetUserByID(id) u, err := models.GetUserByID(id)
if err != nil { if err != nil {
@ -243,6 +243,12 @@ func TwoFactorPost(ctx *context.Context, form auth.TwoFactorAuthForm) {
} }
} }
twofa.LastUsedPasscode = form.Passcode
if err = models.UpdateTwoFactor(twofa); err != nil {
ctx.ServerError("UserSignIn", err)
return
}
handleSignIn(ctx, u, remember) handleSignIn(ctx, u, remember)
return return
} }