mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	Do not allow to reuse TOTP passcode (#3878)
This commit is contained in:
		@@ -176,6 +176,8 @@ var migrations = []Migration{
 | 
			
		||||
	NewMigration("add is_fsck_enabled column for repos", addFsckEnabledToRepo),
 | 
			
		||||
	// v61 -> v62
 | 
			
		||||
	NewMigration("add size column for attachments", addSizeToAttachment),
 | 
			
		||||
	// v62 -> v63
 | 
			
		||||
	NewMigration("add last used passcode column for TOTP", addLastUsedPasscodeTOTP),
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// Migrate database to current version
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										22
									
								
								models/migrations/v62.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										22
									
								
								models/migrations/v62.go
									
									
									
									
									
										Normal 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
 | 
			
		||||
}
 | 
			
		||||
@@ -23,12 +23,13 @@ import (
 | 
			
		||||
 | 
			
		||||
// TwoFactor represents a two-factor authentication token.
 | 
			
		||||
type TwoFactor struct {
 | 
			
		||||
	ID           int64 `xorm:"pk autoincr"`
 | 
			
		||||
	UID          int64 `xorm:"UNIQUE"`
 | 
			
		||||
	Secret       string
 | 
			
		||||
	ScratchToken string
 | 
			
		||||
	CreatedUnix  util.TimeStamp `xorm:"INDEX created"`
 | 
			
		||||
	UpdatedUnix  util.TimeStamp `xorm:"INDEX updated"`
 | 
			
		||||
	ID               int64 `xorm:"pk autoincr"`
 | 
			
		||||
	UID              int64 `xorm:"UNIQUE"`
 | 
			
		||||
	Secret           string
 | 
			
		||||
	ScratchToken     string
 | 
			
		||||
	LastUsedPasscode string         `xorm:"VARCHAR(10)"`
 | 
			
		||||
	CreatedUnix      util.TimeStamp `xorm:"INDEX created"`
 | 
			
		||||
	UpdatedUnix      util.TimeStamp `xorm:"INDEX updated"`
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
// GenerateScratchToken recreates the scratch token the user is using.
 | 
			
		||||
 
 | 
			
		||||
@@ -221,7 +221,7 @@ func TwoFactorPost(ctx *context.Context, form auth.TwoFactorAuthForm) {
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if ok {
 | 
			
		||||
	if ok && twofa.LastUsedPasscode != form.Passcode {
 | 
			
		||||
		remember := ctx.Session.Get("twofaRemember").(bool)
 | 
			
		||||
		u, err := models.GetUserByID(id)
 | 
			
		||||
		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)
 | 
			
		||||
		return
 | 
			
		||||
	}
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user