mirror of
https://github.com/coder/coder.git
synced 2026-09-24 15:04:27 +08:00
chore: add --force-reset-all flag to oidc link repair cli (#26534)
Useful when the issuer is unchanged, but oidc subject claims have changed.
This commit is contained in:
@@ -70,6 +70,12 @@ func ResetMismatchedOIDCLinks(ctx context.Context, db database.Store, expectedIs
|
||||
return count, nil
|
||||
}
|
||||
|
||||
// UnmatchableIssuer is a synthetic issuer value that no real OIDC linked_id
|
||||
// will ever start with. Passing it to AnalyzeOIDCLinks or
|
||||
// ResetMismatchedOIDCLinks causes every link to be treated as "mismatched",
|
||||
// which effectively resets all of them.
|
||||
const UnmatchableIssuer = "00000000-0000-0000-0000-000000000000"
|
||||
|
||||
// ResolveIssuer uses OIDC discovery to fetch the canonical issuer string
|
||||
// from the provider's .well-known/openid-configuration endpoint.
|
||||
// This does not require OIDC client credentials.
|
||||
|
||||
@@ -247,6 +247,88 @@ func TestResetMismatchedOIDCLinks(t *testing.T) {
|
||||
})
|
||||
}
|
||||
|
||||
func TestResetMismatchedOIDCLinksWithUnmatchableIssuer(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
t.Run("ResetsAll", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := testutil.Context(t, testutil.WaitShort)
|
||||
|
||||
db, _ := dbtestutil.NewDB(t)
|
||||
|
||||
// Correctly linked user.
|
||||
correctUser := dbgen.User(t, db, database.User{LoginType: database.LoginTypeOIDC})
|
||||
dbgen.UserLink(t, db, database.UserLink{
|
||||
UserID: correctUser.ID,
|
||||
LoginType: database.LoginTypeOIDC,
|
||||
LinkedID: "https://accounts.google.com||sub-correct",
|
||||
})
|
||||
|
||||
// Mismatched user.
|
||||
mismatchedUser := dbgen.User(t, db, database.User{LoginType: database.LoginTypeOIDC})
|
||||
dbgen.UserLink(t, db, database.UserLink{
|
||||
UserID: mismatchedUser.ID,
|
||||
LoginType: database.LoginTypeOIDC,
|
||||
LinkedID: "https://old-issuer.example.com||sub-mismatched",
|
||||
})
|
||||
|
||||
// Unlinked user (empty linked_id).
|
||||
unlinkedUser := dbgen.User(t, db, database.User{LoginType: database.LoginTypeOIDC})
|
||||
dbgen.UserLink(t, db, database.UserLink{
|
||||
UserID: unlinkedUser.ID,
|
||||
LoginType: database.LoginTypeOIDC,
|
||||
LinkedID: "",
|
||||
})
|
||||
|
||||
count, err := authlink.ResetMismatchedOIDCLinks(ctx, db, authlink.UnmatchableIssuer)
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, 2, count, "should reset correct + mismatched, not unlinked")
|
||||
|
||||
// Verify the correct link was reset.
|
||||
link, err := db.GetUserLinkByUserIDLoginType(ctx, database.GetUserLinkByUserIDLoginTypeParams{
|
||||
UserID: correctUser.ID,
|
||||
LoginType: database.LoginTypeOIDC,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "", link.LinkedID)
|
||||
|
||||
// Verify the mismatched link was reset.
|
||||
link, err = db.GetUserLinkByUserIDLoginType(ctx, database.GetUserLinkByUserIDLoginTypeParams{
|
||||
UserID: mismatchedUser.ID,
|
||||
LoginType: database.LoginTypeOIDC,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "", link.LinkedID)
|
||||
|
||||
// Verify the unlinked user is still unlinked.
|
||||
link, err = db.GetUserLinkByUserIDLoginType(ctx, database.GetUserLinkByUserIDLoginTypeParams{
|
||||
UserID: unlinkedUser.ID,
|
||||
LoginType: database.LoginTypeOIDC,
|
||||
})
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, "", link.LinkedID)
|
||||
})
|
||||
|
||||
t.Run("NothingToReset", func(t *testing.T) {
|
||||
t.Parallel()
|
||||
ctx := testutil.Context(t, testutil.WaitShort)
|
||||
|
||||
db, _ := dbtestutil.NewDB(t)
|
||||
|
||||
// Only an unlinked user.
|
||||
user := dbgen.User(t, db, database.User{LoginType: database.LoginTypeOIDC})
|
||||
dbgen.UserLink(t, db, database.UserLink{
|
||||
UserID: user.ID,
|
||||
LoginType: database.LoginTypeOIDC,
|
||||
LinkedID: "",
|
||||
})
|
||||
|
||||
count, err := authlink.ResetMismatchedOIDCLinks(ctx, db, authlink.UnmatchableIssuer)
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, 0, count)
|
||||
})
|
||||
}
|
||||
|
||||
func TestResolveIssuer(t *testing.T) {
|
||||
t.Parallel()
|
||||
|
||||
|
||||
Reference in New Issue
Block a user