@@ -4,6 +4,8 @@ defmodule Rbac.Okta.Integration do
4
4
"""
5
5
6
6
require Ecto.Query
7
+ require Logger
8
+
7
9
alias Ecto.Query
8
10
alias Rbac.Repo
9
11
alias Rbac.Okta.Saml.Certificate
@@ -21,23 +23,82 @@ defmodule Rbac.Okta.Integration do
21
23
jit_provisioning_enabled ,
22
24
idempotency_token \\ Ecto.UUID . generate ( )
23
25
) do
24
- with { :ok , fingerprint } <- Certificate . fingerprint ( certificate ) ,
25
- { :ok , integration } <-
26
- Rbac.Repo.OktaIntegration . insert_or_update (
27
- org_id: org_id ,
28
- creator_id: creator_id ,
29
- sso_url: sso_url ,
30
- saml_issuer: saml_issuer ,
31
- saml_certificate_fingerprint: Base . encode64 ( fingerprint ) ,
32
- jit_provisioning_enabled: jit_provisioning_enabled ,
33
- idempotency_token: idempotency_token
34
- ) do
35
- { :ok , integration }
26
+ Ecto.Multi . new ( )
27
+ |> Ecto.Multi . run ( :fingerprint , fn _repo , _changes ->
28
+ Certificate . fingerprint ( certificate )
29
+ end )
30
+ |> Ecto.Multi . run ( :integration , fn _repo , % { fingerprint: fingerprint } ->
31
+ Rbac.Repo.OktaIntegration . insert_or_update (
32
+ org_id: org_id ,
33
+ creator_id: creator_id ,
34
+ sso_url: sso_url ,
35
+ saml_issuer: saml_issuer ,
36
+ saml_certificate_fingerprint: Base . encode64 ( fingerprint ) ,
37
+ jit_provisioning_enabled: jit_provisioning_enabled ,
38
+ idempotency_token: idempotency_token
39
+ )
40
+ end )
41
+ |> Ecto.Multi . run ( :allowed_id_providers , fn _repo , _changes ->
42
+ add_okta_to_allowed_id_providers ( org_id )
43
+ end )
44
+ |> Rbac.Repo . transaction ( )
45
+ |> case do
46
+ { :ok , % { integration: integration } } ->
47
+ { :ok , integration }
48
+
49
+ { :error , :fingerprint , reason , _changes } ->
50
+ Logger . error ( "Failed to decode certificate for org #{ org_id } : #{ inspect ( reason ) } ." )
51
+ { :error , :cert_decode_error }
52
+
53
+ { :error , :integration , reason , _changes } ->
54
+ Logger . error (
55
+ "Failed to create/update Okta integration for org #{ org_id } : #{ inspect ( reason ) } "
56
+ )
57
+
58
+ { :error , { :integration_failed , reason } }
59
+
60
+ { :error , :allowed_id_providers , reason , _changes } ->
61
+ Logger . error (
62
+ "Failed to add Okta to allowed ID providers for org #{ org_id } : #{ inspect ( reason ) } "
63
+ )
64
+
65
+ { :error , { :allowed_id_providers_failed , reason } }
66
+
67
+ { :error , operation , reason , _changes } ->
68
+ Logger . error (
69
+ "Unknown operation #{ inspect ( operation ) } failed for org #{ org_id } : #{ inspect ( reason ) } "
70
+ )
71
+
72
+ { :error , reason }
73
+ end
74
+ end
75
+
76
+ defp update_id_providers ( org_id , operation , action ) do
77
+ with { :ok , org } <- Rbac.Api.Organization . find_by_id ( org_id ) ,
78
+ updated_providers <- operation . ( org . allowed_id_providers || [ ] ) ,
79
+ updated_org <- Map . put ( org , :allowed_id_providers , updated_providers ) ,
80
+ { :ok , updated } <- Rbac.Api.Organization . update ( updated_org ) do
81
+ { :ok , updated }
36
82
else
37
- e -> e
83
+ { :error , :not_found } ->
84
+ Logger . error ( "Failed to #{ action } okta provider: Org #{ org_id } not found" )
85
+ { :error , :organization_not_found }
86
+
87
+ { :error , reason } ->
88
+ Logger . error ( "Failed to #{ action } okta provider for org #{ org_id } : #{ inspect ( reason ) } " )
89
+
90
+ { :error , :update_failed }
38
91
end
39
92
end
40
93
94
+ defp add_okta_to_allowed_id_providers ( org_id ) do
95
+ update_id_providers ( org_id , & Enum . uniq ( & 1 ++ [ "okta" ] ) , "add" )
96
+ end
97
+
98
+ defp remove_okta_from_allowed_id_providers ( org_id ) do
99
+ update_id_providers ( org_id , & Enum . reject ( & 1 , fn provider -> provider == "okta" end ) , "remove" )
100
+ end
101
+
41
102
def generate_scim_token ( integration ) do
42
103
token = Rbac.Okta.Scim.Token . generate ( )
43
104
token_hash = Rbac.Okta.Scim.Token . hash ( token )
@@ -96,10 +157,13 @@ defmodule Rbac.Okta.Integration do
96
157
Rbac.RoleManagement . retract_roles ( rbi , :okta )
97
158
{ :ok , :retracted_roles }
98
159
end )
99
- |> Ecto.Multi . run ( :delete_okta_users , fn _repo , _cahnges ->
160
+ |> Ecto.Multi . run ( :delete_okta_users , fn _repo , _changes ->
100
161
OktaUser . delete_all ( id )
101
162
{ :ok , :okta_users_deleted }
102
163
end )
164
+ |> Ecto.Multi . run ( :remove_okta_from_allowed_id_providers , fn _repo , _changes ->
165
+ remove_okta_from_allowed_id_providers ( integration . org_id )
166
+ end )
103
167
|> Ecto.Multi . delete ( :delete_okta_integration , integration )
104
168
|> Rbac.Repo . transaction ( timeout: 60_000 )
105
169
0 commit comments