diff options
author | Lunny Xiao <xiaolunwen@gmail.com> | 2022-01-14 23:03:31 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-01-14 16:03:31 +0100 |
commit | 35c3553870e35b2e7cfcc599645791acda6afcef (patch) | |
tree | 0ad600c2d1cd94ef12566482832768c9efcf8a69 /modules | |
parent | 8808293247bebd20482c3c625c64937174503781 (diff) | |
download | gitea-35c3553870e35b2e7cfcc599645791acda6afcef.tar.gz gitea-35c3553870e35b2e7cfcc599645791acda6afcef.zip |
Support webauthn (#17957)
Migrate from U2F to Webauthn
Co-authored-by: Andrew Thornton <art27@cantab.net>
Co-authored-by: 6543 <6543@obermui.de>
Co-authored-by: wxiaoguang <wxiaoguang@gmail.com>
Diffstat (limited to 'modules')
-rw-r--r-- | modules/auth/webauthn/webauthn.go | 78 | ||||
-rw-r--r-- | modules/auth/webauthn/webauthn_test.go | 26 | ||||
-rw-r--r-- | modules/generate/generate.go | 2 | ||||
-rw-r--r-- | modules/setting/setting.go | 11 |
4 files changed, 109 insertions, 8 deletions
diff --git a/modules/auth/webauthn/webauthn.go b/modules/auth/webauthn/webauthn.go new file mode 100644 index 0000000000..8f380e7c34 --- /dev/null +++ b/modules/auth/webauthn/webauthn.go @@ -0,0 +1,78 @@ +// Copyright 2021 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 webauthn + +import ( + "encoding/binary" + "encoding/gob" + "net/url" + + "code.gitea.io/gitea/models/auth" + user_model "code.gitea.io/gitea/models/user" + "code.gitea.io/gitea/modules/setting" + + "github.com/duo-labs/webauthn/protocol" + "github.com/duo-labs/webauthn/webauthn" +) + +//WebAuthn represents the global WebAuthn instance +var WebAuthn *webauthn.WebAuthn + +//Init initializes the WebAuthn instance from the config. +func Init() { + gob.Register(&webauthn.SessionData{}) + + appURL, _ := url.Parse(setting.AppURL) + + WebAuthn = &webauthn.WebAuthn{ + Config: &webauthn.Config{ + RPDisplayName: setting.AppName, + RPID: setting.Domain, + RPOrigin: protocol.FullyQualifiedOrigin(appURL), + AuthenticatorSelection: protocol.AuthenticatorSelection{ + UserVerification: "discouraged", + }, + AttestationPreference: protocol.PreferDirectAttestation, + }, + } +} + +// User represents an implementation of webauthn.User based on User model +type User user_model.User + +//WebAuthnID implements the webauthn.User interface +func (u *User) WebAuthnID() []byte { + id := make([]byte, 8) + binary.PutVarint(id, u.ID) + return id +} + +//WebAuthnName implements the webauthn.User interface +func (u *User) WebAuthnName() string { + if u.LoginName == "" { + return u.Name + } + return u.LoginName +} + +//WebAuthnDisplayName implements the webauthn.User interface +func (u *User) WebAuthnDisplayName() string { + return (*user_model.User)(u).DisplayName() +} + +//WebAuthnIcon implements the webauthn.User interface +func (u *User) WebAuthnIcon() string { + return (*user_model.User)(u).AvatarLink() +} + +//WebAuthnCredentials implementns the webauthn.User interface +func (u *User) WebAuthnCredentials() []webauthn.Credential { + dbCreds, err := auth.GetWebAuthnCredentialsByUID(u.ID) + if err != nil { + return nil + } + + return dbCreds.ToCredentials() +} diff --git a/modules/auth/webauthn/webauthn_test.go b/modules/auth/webauthn/webauthn_test.go new file mode 100644 index 0000000000..71fb9d2757 --- /dev/null +++ b/modules/auth/webauthn/webauthn_test.go @@ -0,0 +1,26 @@ +// Copyright 2021 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 webauthn + +import ( + "testing" + + "code.gitea.io/gitea/modules/setting" + + "github.com/stretchr/testify/assert" +) + +func TestInit(t *testing.T) { + setting.Domain = "domain" + setting.AppName = "AppName" + setting.AppURL = "https://domain/" + rpOrigin := "https://domain" + + Init() + + assert.Equal(t, setting.Domain, WebAuthn.Config.RPID) + assert.Equal(t, setting.AppName, WebAuthn.Config.RPDisplayName) + assert.Equal(t, rpOrigin, WebAuthn.Config.RPOrigin) +} diff --git a/modules/generate/generate.go b/modules/generate/generate.go index ab05a9cb83..ae9aeee18b 100644 --- a/modules/generate/generate.go +++ b/modules/generate/generate.go @@ -13,7 +13,7 @@ import ( "code.gitea.io/gitea/modules/util" - "github.com/golang-jwt/jwt" + "github.com/golang-jwt/jwt/v4" ) // NewInternalToken generate a new value intended to be used by INTERNAL_TOKEN. diff --git a/modules/setting/setting.go b/modules/setting/setting.go index 2ba6bcf9e7..abd6716c74 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -28,7 +28,6 @@ import ( "code.gitea.io/gitea/modules/user" "code.gitea.io/gitea/modules/util" - shellquote "github.com/kballard/go-shellquote" "github.com/unknwon/com" gossh "golang.org/x/crypto/ssh" ini "gopkg.in/ini.v1" @@ -388,8 +387,7 @@ var ( } U2F = struct { - AppID string - TrustedFacets []string + AppID string }{} // Metrics settings @@ -1015,10 +1013,6 @@ func loadFromConf(allowEmpty bool, extraConfig string) { newMarkup() - sec = Cfg.Section("U2F") - U2F.TrustedFacets, _ = shellquote.Split(sec.Key("TRUSTED_FACETS").MustString(strings.TrimSuffix(AppURL, AppSubURL+"/"))) - U2F.AppID = sec.Key("APP_ID").MustString(strings.TrimSuffix(AppURL, "/")) - UI.ReactionsMap = make(map[string]bool) for _, reaction := range UI.Reactions { UI.ReactionsMap[reaction] = true @@ -1027,6 +1021,9 @@ func loadFromConf(allowEmpty bool, extraConfig string) { for _, emoji := range UI.CustomEmojis { UI.CustomEmojisMap[emoji] = ":" + emoji + ":" } + + sec = Cfg.Section("U2F") + U2F.AppID = sec.Key("APP_ID").MustString(strings.TrimSuffix(AppURL, "/")) } func parseAuthorizedPrincipalsAllow(values []string) ([]string, bool) { |