Skip to content

Commit

Permalink
only set username and email if valid
Browse files Browse the repository at this point in the history
Signed-off-by: Kristoffer Dalby <[email protected]>
  • Loading branch information
kradalby committed Nov 22, 2024
1 parent c905f04 commit c59144a
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 8 deletions.
2 changes: 1 addition & 1 deletion hscontrol/policy/acls.go
Original file line number Diff line number Diff line change
Expand Up @@ -990,7 +990,7 @@ func filterNodesByUser(nodes types.Nodes, users []types.User, userToken string)

var potentialUsers []types.User
for _, user := range users {
if user.ProviderIdentifier == userToken {
if user.ProviderIdentifier.Valid && user.ProviderIdentifier.String == userToken {
// If a user is matching with a known unique field,
// disgard all other users and only keep the current
// user.
Expand Down
3 changes: 2 additions & 1 deletion hscontrol/policy/acls_test.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
package policy

import (
"database/sql"
"errors"
"math/rand/v2"
"net/netip"
Expand Down Expand Up @@ -892,7 +893,7 @@ func Test_filterNodesByUser(t *testing.T) {
Model: gorm.Model{ID: 3},
Name: "mikael",
Email: "[email protected]",
ProviderIdentifier: "http://oidc.org/1234",
ProviderIdentifier: sql.NullString{String: "http://oidc.org/1234", Valid: true},
},
{Model: gorm.Model{ID: 4}, Name: "mikael2", Email: "[email protected]"},
{Model: gorm.Model{ID: 5}, Name: "mikael", Email: "[email protected]"},
Expand Down
24 changes: 18 additions & 6 deletions hscontrol/types/users.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package types

import (
"cmp"
"database/sql"
"net/mail"
"strconv"

v1 "github.com/juanfont/headscale/gen/go/headscale/v1"
Expand Down Expand Up @@ -34,7 +36,7 @@ type User struct {
// Unique identifier of the user from OIDC,
// comes from `sub` claim in the OIDC token
// and is used to lookup the user.
ProviderIdentifier string `gorm:"index"`
ProviderIdentifier sql.NullString `gorm:"index"`

// Provider is the origin of the user account,
// same as RegistrationMethod, without authkey.
Expand All @@ -51,7 +53,7 @@ type User struct {
// should be used throughout headscale, in information returned to the
// user and the Policy engine.
func (u *User) Username() string {
return cmp.Or(u.Email, u.Name, u.ProviderIdentifier, strconv.FormatUint(uint64(u.ID), 10))
return cmp.Or(u.Email, u.Name, u.ProviderIdentifier.String, strconv.FormatUint(uint64(u.ID), 10))
}

// DisplayNameOrUsername returns the DisplayName if it exists, otherwise
Expand Down Expand Up @@ -107,7 +109,7 @@ func (u *User) Proto() *v1.User {
CreatedAt: timestamppb.New(u.CreatedAt),
DisplayName: u.DisplayName,
Email: u.Email,
ProviderId: u.ProviderIdentifier,
ProviderId: u.ProviderIdentifier.String,
Provider: u.Provider,
ProfilePicUrl: u.ProfilePicURL,
}
Expand All @@ -129,10 +131,20 @@ type OIDCClaims struct {
// FromClaim overrides a User from OIDC claims.
// All fields will be updated, except for the ID.
func (u *User) FromClaim(claims *OIDCClaims) {
u.ProviderIdentifier = claims.Sub
err := util.CheckForFQDNRules(claims.Username)
if err == nil {
u.Name = claims.Username
}

if claims.EmailVerified {
_, err = mail.ParseAddress(claims.Email)
if err == nil {
u.Email = claims.Email
}
}

u.ProviderIdentifier.String = claims.Sub
u.DisplayName = claims.Name
u.Email = claims.Email
u.Name = claims.Username
u.ProfilePicURL = claims.ProfilePictureURL
u.Provider = util.RegisterMethodOIDC
}

0 comments on commit c59144a

Please sign in to comment.