1// Copyright 2021 The Gitea Authors. All rights reserved.
2// Use of this source code is governed by a MIT-style
3// license that can be found in the LICENSE file.
4
5package webauthn
6
7import (
8	"encoding/binary"
9	"encoding/gob"
10	"net/url"
11
12	"code.gitea.io/gitea/models/auth"
13	user_model "code.gitea.io/gitea/models/user"
14	"code.gitea.io/gitea/modules/setting"
15
16	"github.com/duo-labs/webauthn/protocol"
17	"github.com/duo-labs/webauthn/webauthn"
18)
19
20//WebAuthn represents the global WebAuthn instance
21var WebAuthn *webauthn.WebAuthn
22
23//Init initializes the WebAuthn instance from the config.
24func Init() {
25	gob.Register(&webauthn.SessionData{})
26
27	appURL, _ := url.Parse(setting.AppURL)
28
29	WebAuthn = &webauthn.WebAuthn{
30		Config: &webauthn.Config{
31			RPDisplayName: setting.AppName,
32			RPID:          setting.Domain,
33			RPOrigin:      protocol.FullyQualifiedOrigin(appURL),
34			AuthenticatorSelection: protocol.AuthenticatorSelection{
35				UserVerification: "discouraged",
36			},
37			AttestationPreference: protocol.PreferDirectAttestation,
38		},
39	}
40}
41
42// User represents an implementation of webauthn.User based on User model
43type User user_model.User
44
45//WebAuthnID implements the webauthn.User interface
46func (u *User) WebAuthnID() []byte {
47	id := make([]byte, 8)
48	binary.PutVarint(id, u.ID)
49	return id
50}
51
52//WebAuthnName implements the webauthn.User interface
53func (u *User) WebAuthnName() string {
54	if u.LoginName == "" {
55		return u.Name
56	}
57	return u.LoginName
58}
59
60//WebAuthnDisplayName implements the webauthn.User interface
61func (u *User) WebAuthnDisplayName() string {
62	return (*user_model.User)(u).DisplayName()
63}
64
65//WebAuthnIcon implements the webauthn.User interface
66func (u *User) WebAuthnIcon() string {
67	return (*user_model.User)(u).AvatarLink()
68}
69
70//WebAuthnCredentials implementns the webauthn.User interface
71func (u *User) WebAuthnCredentials() []webauthn.Credential {
72	dbCreds, err := auth.GetWebAuthnCredentialsByUID(u.ID)
73	if err != nil {
74		return nil
75	}
76
77	return dbCreds.ToCredentials()
78}
79