Skip to content

Commit 12d53d3

Browse files
committed
add toggle for syncing sso roles with idp
1 parent 35ce16e commit 12d53d3

File tree

4 files changed

+74
-10
lines changed

4 files changed

+74
-10
lines changed

app/controllers/auth/sso_controller.rb

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,8 @@ def callback
110110
email: profile.email,
111111
)
112112

113-
# keep the user's role up-to-date with the IdP
114-
if profile.role in slug: String => name
113+
# keep the user's role up-to-date with the IdP (some IdPs e.g. Google OIDC have issues with groups)
114+
if account.sso_sync_roles? && profile.role in slug: String => name
115115
role = name.underscore.to_sym # pin expects a symbol
116116

117117
unless user.role in Role(^role)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
class AddSsoSyncRolesToAccounts < ActiveRecord::Migration[8.0]
2+
verbose!
3+
4+
def change
5+
add_column :accounts, :sso_sync_roles, :boolean, null: false, default: false
6+
end
7+
end

db/schema.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,11 +10,11 @@
1010
#
1111
# It's strongly recommended that you check this file into your version control system.
1212

13-
ActiveRecord::Schema[7.2].define(version: 2025_09_24_165540) do
13+
ActiveRecord::Schema[8.0].define(version: 2025_10_10_143945) do
1414
# These are extensions that must be enabled in order to support this database
1515
enable_extension "btree_gin"
16+
enable_extension "pg_catalog.plpgsql"
1617
enable_extension "pg_stat_statements"
17-
enable_extension "plpgsql"
1818
enable_extension "uuid-ossp"
1919

2020
create_table "account_settings", id: :uuid, default: -> { "uuid_generate_v4()" }, force: :cascade do |t|
@@ -60,6 +60,7 @@
6060
t.string "slack_channel_id"
6161
t.text "ecdsa_private_key"
6262
t.text "ecdsa_public_key"
63+
t.boolean "sso_sync_roles", default: false, null: false
6364
t.index ["cname"], name: "index_accounts_on_cname", unique: true
6465
t.index ["created_at"], name: "index_accounts_on_created_at", order: :desc
6566
t.index ["domain"], name: "index_accounts_on_domain", unique: true

features/auth/sso.feature

Lines changed: 62 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -2,11 +2,11 @@
22
Feature: SSO
33
Background:
44
Given the following "accounts" exist:
5-
| name | slug | sso_organization_id | sso_organization_domains | sso_session_duration | sso_jit_provisioning | sso_external_authn | secret_key |
6-
| Keygen | keygen-sh | | | | | | 04cd269a781e207653eb2ff3e9ab0be5 |
7-
| Example | example-com | | | | | | a1f091cf41085e9436708a79090e37a6 |
8-
| Evil Corp | ecorp-example | test_org_59f4ac10f7b6acbf3304f3fc2211 | ecorp.example | 43200 | false | true | a9be6bf4b17f353d002758ad33a0e0a4 |
9-
| Lumon Industries | lumon-example | test_org_669aa06c521982d5c12b3eb74bf0 | lumon.example | | true | false | 98a2f3ad35a80561ce2b2c2d93d7e7e4 |
5+
| name | slug | sso_organization_id | sso_organization_domains | sso_session_duration | sso_jit_provisioning | sso_external_authn | sso_sync_roles | secret_key |
6+
| Keygen | keygen-sh | | | | | | | 04cd269a781e207653eb2ff3e9ab0be5 |
7+
| Example | example-com | | | | | | | a1f091cf41085e9436708a79090e37a6 |
8+
| Evil Corp | ecorp-example | test_org_59f4ac10f7b6acbf3304f3fc2211 | ecorp.example | 43200 | false | true | true | a9be6bf4b17f353d002758ad33a0e0a4 |
9+
| Lumon Industries | lumon-example | test_org_669aa06c521982d5c12b3eb74bf0 | lumon.example | | true | false | false | 98a2f3ad35a80561ce2b2c2d93d7e7e4 |
1010

1111
Scenario: We receive a successful callback for an existing admin
1212
Given the first "admin" of account "ecorp-example" has the following attributes:
@@ -365,7 +365,7 @@ Feature: SSO
365365
"""
366366
And time is unfrozen
367367

368-
Scenario: We receive a successful callback for an existing user (changed role)
368+
Scenario: We receive a successful callback for an existing user (changed role, role sync enabled)
369369
Given the account "ecorp-example" has 1 "user" with the following:
370370
"""
371371
{ "email": "[email protected]" }
@@ -422,6 +422,62 @@ Feature: SSO
422422
"""
423423
And time is unfrozen
424424

425+
Scenario: We receive a successful callback for an existing user (changed role, role sync disabled)
426+
Given the account "lumon-example" has 1 "user" with the following:
427+
"""
428+
{ "email": "[email protected]" }
429+
"""
430+
And the SSO callback code "test_123" returns the following profile:
431+
"""
432+
{
433+
"id": "test_prof_b2c45c1af54f9cad85edf6104091",
434+
"organization_id": "test_org_669aa06c521982d5c12b3eb74bf0",
435+
"connection_id": "test_conn_6ca55425d9b4842cdd3ba3f1ea9c",
436+
"idp_id": "test_idp_34d99d8985608b3d0297183a1265",
437+
"email": "[email protected]",
438+
"first_name": "Mark",
439+
"last_name": "Scout",
440+
"role": {
441+
"slug": "admin"
442+
}
443+
}
444+
"""
445+
And I use user agent "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0) Gecko/20100101 Firefox/136.0"
446+
And time is frozen at "2552-02-28T00:00:00.000Z"
447+
When I send a GET request to "//auth.keygen.sh/sso?code=test_123&state=TOqaPpXRH1plNlmQrU76PG35WvLupDqoJPpQX52M8LcYIUh1fIpvlj5kiM1wiyVpRWEAYA.LE-szECwEiE2sSqH.f9GClmuiFnrT7Xe81U_Rxw"
448+
Then the response status should be "303"
449+
And the response headers should contain "Location" with "https://portal.keygen.sh/lumon-example"
450+
And the response headers should contain "Set-Cookie" with an encrypted cookie:
451+
"""
452+
session_id=$sessions[0]; domain=keygen.sh; path=/; expires=Mon, 28 Feb 2552 08:00:00 GMT; secure; httponly; samesite=None; partitioned;
453+
"""
454+
And the account "lumon-example" should have 1 "admin"
455+
And the account "lumon-example" should have 1 "user"
456+
And the last "user" of account "lumon-example" should have the following attributes:
457+
"""
458+
{
459+
"sso_profile_id": "test_prof_b2c45c1af54f9cad85edf6104091",
460+
"sso_connection_id": "test_conn_6ca55425d9b4842cdd3ba3f1ea9c",
461+
"sso_idp_id": "test_idp_34d99d8985608b3d0297183a1265",
462+
"email": "[email protected]",
463+
"first_name": "Mark",
464+
"last_name": "Scout"
465+
}
466+
"""
467+
And the account "lumon-example" should have 1 "session"
468+
And the last "session" of account "lumon-example" should have the following attributes:
469+
"""
470+
{
471+
"bearer_type": "User",
472+
"bearer_id": "$users[1]",
473+
"token_id": null,
474+
"user_agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:136.0) Gecko/20100101 Firefox/136.0",
475+
"ip": "127.0.0.1",
476+
"last_used_at": null
477+
}
478+
"""
479+
And time is unfrozen
480+
425481
Scenario: We receive a successful callback for an existing user (invalid role)
426482
Given the account "ecorp-example" has 1 "user" with the following:
427483
"""

0 commit comments

Comments
 (0)