-
-
Notifications
You must be signed in to change notification settings - Fork 5.8k
Enforce two-factor auth (2FA: TOTP or WebAuthn) #34187
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Changes from all commits
7ffd745
3804e6c
e0e7384
18d4861
10075b6
4cd65e7
d90564c
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
// Copyright 2025 The Gitea Authors. All rights reserved. | ||
// SPDX-License-Identifier: MIT | ||
|
||
package v1_24 //nolint | ||
|
||
import ( | ||
"code.gitea.io/gitea/modules/json" | ||
|
||
"xorm.io/xorm" | ||
) | ||
|
||
func MigrateSkipTwoFactor(x *xorm.Engine) error { | ||
type LoginSource struct { | ||
TwoFactorPolicy string `xorm:"two_factor_policy NOT NULL DEFAULT ''"` | ||
} | ||
err := x.Sync(new(LoginSource)) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
type LoginSourceSimple struct { | ||
ID int64 | ||
Cfg string | ||
} | ||
|
||
var loginSources []LoginSourceSimple | ||
err = x.Table("login_source").Find(&loginSources) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
for _, source := range loginSources { | ||
if source.Cfg == "" { | ||
continue | ||
} | ||
|
||
var cfg map[string]any | ||
err = json.Unmarshal([]byte(source.Cfg), &cfg) | ||
if err != nil { | ||
return err | ||
} | ||
|
||
if cfg["SkipLocalTwoFA"] == true { | ||
_, err = x.Exec("UPDATE login_source SET two_factor_policy = 'skip' WHERE id = ?", source.ID) | ||
if err != nil { | ||
return err | ||
} | ||
} | ||
} | ||
return nil | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,11 @@ | ||
// Copyright 2025 The Gitea Authors. All rights reserved. | ||
// SPDX-License-Identifier: MIT | ||
|
||
package session | ||
|
||
const ( | ||
KeyUID = "uid" | ||
KeyUname = "uname" | ||
|
||
KeyUserHasTwoFactorAuth = "userHasTwoFactorAuth" | ||
) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -39,6 +39,7 @@ var ( | |
CSRFCookieName = "_csrf" | ||
CSRFCookieHTTPOnly = true | ||
RecordUserSignupMetadata = false | ||
TwoFactorAuthEnforced = false | ||
) | ||
|
||
// loadSecret load the secret from ini by uriKey or verbatimKey, only one of them could be set | ||
|
@@ -142,6 +143,15 @@ func loadSecurityFrom(rootCfg ConfigProvider) { | |
PasswordCheckPwn = sec.Key("PASSWORD_CHECK_PWN").MustBool(false) | ||
SuccessfulTokensCacheSize = sec.Key("SUCCESSFUL_TOKENS_CACHE_SIZE").MustInt(20) | ||
|
||
twoFactorAuth := sec.Key("TWO_FACTOR_AUTH").String() | ||
switch twoFactorAuth { | ||
case "": | ||
case "enforced": | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think the
This config option is "string enum" based, so there are always chances to choose better names in the future without breaking. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think this configuration could be extend in the future so that the name should match it's behaviour. The current behaviour will display dashboard, explores but all repositories related operations will require two factor verify. So that the name
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You decide, feel free to edit this PR directly |
||
TwoFactorAuthEnforced = true | ||
default: | ||
log.Fatal("Invalid two-factor auth option: %s", twoFactorAuth) | ||
} | ||
|
||
InternalToken = loadSecret(sec, "INTERNAL_TOKEN_URI", "INTERNAL_TOKEN") | ||
if InstallLock && InternalToken == "" { | ||
// if Gitea has been installed but the InternalToken hasn't been generated (upgrade from an old release), we should generate | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Use
SyncWithOptions
to avoidindex
sync.There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand the details. Feel free to edit directly and document it