Skip to content

Commit 0cda82d

Browse files
laureat-natzkaLaureat Grepi
and
Laureat Grepi
authored
Feature/keycloak_required_action config values (#996)
* Enable configs in required actions Signed-off-by: Laureat Grepi <[email protected]> * registry json file Signed-off-by: Laureat Grepi <[email protected]> * newline Signed-off-by: Laureat Grepi <[email protected]> * Enable configuring required action from terraform Signed-off-by: Laureat Grepi <[email protected]> * Allow required action config values to be passed from terraform Signed-off-by: Laureat Grepi <[email protected]> * update examples Signed-off-by: Laureat Grepi <[email protected]> * Add multivalued config in user profile Signed-off-by: Laureat Grepi <[email protected]> * fmt Signed-off-by: Laureat Grepi <[email protected]> * remove default value Signed-off-by: Laureat Grepi <[email protected]> * format Signed-off-by: Laureat Grepi <[email protected]> * remove multivalued Signed-off-by: Laureat Grepi <[email protected]> * format Signed-off-by: Laureat Grepi <[email protected]> --------- Signed-off-by: Laureat Grepi <[email protected]> Co-authored-by: Laureat Grepi <[email protected]>
1 parent 9411368 commit 0cda82d

File tree

5 files changed

+88
-21
lines changed

5 files changed

+88
-21
lines changed

docs/resources/required_action.md

+6-2
Original file line numberDiff line numberDiff line change
@@ -19,9 +19,12 @@ resource "keycloak_realm" "realm" {
1919
2020
resource "keycloak_required_action" "required_action" {
2121
realm_id = keycloak_realm.realm.realm
22-
alias = "webauthn-register"
22+
alias = "UPDATE_PASSWORD"
2323
enabled = true
24-
name = "Webauthn Register"
24+
name = "Update Password"
25+
config = {
26+
max_auth_age = "600"
27+
}
2528
}
2629
```
2730

@@ -33,6 +36,7 @@ resource "keycloak_required_action" "required_action" {
3336
- `enabled` - (Optional) When `false`, the required action is not enabled for new users. Defaults to `false`.
3437
- `default_action` - (Optional) When `true`, the required action is set as the default action for new users. Defaults to `false`.
3538
- `priority`- (Optional) The priority of the required action.
39+
- `config`- (Optional) The configuration. Keys are specific to each configurable required action and not checked when applying.
3640

3741
## Import
3842

example/main.tf

+18-6
Original file line numberDiff line numberDiff line change
@@ -109,6 +109,18 @@ resource "keycloak_required_action" "custom-terms-and-conditions" {
109109
name = "Custom Terms and Conditions"
110110
}
111111

112+
resource "keycloak_required_action" "update-password" {
113+
realm_id = keycloak_realm.test.realm
114+
alias = "UPDATE_PASSWORD"
115+
default_action = true
116+
enabled = true
117+
name = "Update Password"
118+
119+
config {
120+
max_auth_age = "600"
121+
}
122+
}
123+
112124
resource "keycloak_required_action" "custom-configured_totp" {
113125
realm_id = keycloak_realm.test.realm
114126
alias = "CONFIGURE_TOTP"
@@ -1020,47 +1032,47 @@ resource "keycloak_authentication_execution" "browser-copy-cookie" {
10201032
parent_flow_alias = keycloak_authentication_flow.browser-copy-flow.alias
10211033
authenticator = "auth-cookie"
10221034
requirement = "ALTERNATIVE"
1023-
priority = 20
1035+
priority = 20
10241036
}
10251037

10261038
resource "keycloak_authentication_execution" "browser-copy-kerberos" {
10271039
realm_id = keycloak_realm.test.id
10281040
parent_flow_alias = keycloak_authentication_flow.browser-copy-flow.alias
10291041
authenticator = "auth-spnego"
10301042
requirement = "DISABLED"
1031-
priority = 10
1043+
priority = 10
10321044
}
10331045

10341046
resource "keycloak_authentication_execution" "browser-copy-idp-redirect" {
10351047
realm_id = keycloak_realm.test.id
10361048
parent_flow_alias = keycloak_authentication_flow.browser-copy-flow.alias
10371049
authenticator = "identity-provider-redirector"
10381050
requirement = "ALTERNATIVE"
1039-
priority = 30
1051+
priority = 30
10401052
}
10411053

10421054
resource "keycloak_authentication_subflow" "browser-copy-flow-forms" {
10431055
realm_id = keycloak_realm.test.id
10441056
parent_flow_alias = keycloak_authentication_flow.browser-copy-flow.alias
10451057
alias = "browser-copy-flow-forms"
10461058
requirement = "ALTERNATIVE"
1047-
priority = 40
1059+
priority = 40
10481060
}
10491061

10501062
resource "keycloak_authentication_execution" "browser-copy-auth-username-password-form" {
10511063
realm_id = keycloak_realm.test.id
10521064
parent_flow_alias = keycloak_authentication_subflow.browser-copy-flow-forms.alias
10531065
authenticator = "auth-username-password-form"
10541066
requirement = "REQUIRED"
1055-
priority = 50
1067+
priority = 50
10561068
}
10571069

10581070
resource "keycloak_authentication_execution" "browser-copy-otp" {
10591071
realm_id = keycloak_realm.test.id
10601072
parent_flow_alias = keycloak_authentication_subflow.browser-copy-flow-forms.alias
10611073
authenticator = "auth-otp-form"
10621074
requirement = "REQUIRED"
1063-
priority = 60
1075+
priority = 60
10641076
}
10651077

10661078
resource "keycloak_authentication_execution_config" "config" {

keycloak/required_action.go

+11-12
Original file line numberDiff line numberDiff line change
@@ -6,31 +6,30 @@ import (
66
)
77

88
type RequiredAction struct {
9-
Id string `json:"-"`
10-
RealmId string `json:"-"`
11-
Alias string `json:"alias"`
12-
Name string `json:"name"`
13-
ProviderId string `json:"providerId"`
14-
Enabled bool `json:"enabled"`
15-
DefaultAction bool `json:"defaultAction"`
16-
Priority int `json:"priority"`
17-
Config map[string][]string `json:"config"`
9+
Id string `json:"-"`
10+
RealmId string `json:"-"`
11+
Alias string `json:"alias"`
12+
Name string `json:"name"`
13+
ProviderId string `json:"providerId"`
14+
Enabled bool `json:"enabled"`
15+
DefaultAction bool `json:"defaultAction"`
16+
Priority int `json:"priority"`
17+
Config map[string]string `json:"config"`
1818
}
1919

2020
func (requiredActions *RequiredAction) getConfig(val string) string {
2121
if len(requiredActions.Config[val]) == 0 {
2222
return ""
2323
}
24-
return requiredActions.Config[val][0]
24+
return requiredActions.Config[val]
2525
}
2626

2727
func (requiredActions *RequiredAction) getConfigOk(val string) (string, bool) {
2828
if v, ok := requiredActions.Config[val]; ok {
29-
return v[0], true
29+
return v, true
3030
}
3131
return "", false
3232
}
33-
3433
func (keycloakClient *KeycloakClient) GetRequiredActions(ctx context.Context, realmId string) ([]*RequiredAction, error) {
3534
var requiredActions []*RequiredAction
3635

provider/resource_keycloak_required_action.go

+12-1
Original file line numberDiff line numberDiff line change
@@ -47,11 +47,21 @@ func resourceKeycloakRequiredAction() *schema.Resource {
4747
Optional: true,
4848
Computed: true,
4949
},
50+
"config": {
51+
Type: schema.TypeMap,
52+
Elem: &schema.Schema{Type: schema.TypeString},
53+
Optional: true,
54+
},
5055
},
5156
}
5257
}
5358

5459
func getRequiredActionFromData(data *schema.ResourceData) (*keycloak.RequiredAction, error) {
60+
config := make(map[string]string)
61+
for key, value := range data.Get("config").(map[string]interface{}) {
62+
config[key] = value.(string)
63+
}
64+
5565
action := &keycloak.RequiredAction{
5666
Id: fmt.Sprintf("%s/%s", data.Get("realm_id").(string), data.Get("alias").(string)),
5767
RealmId: data.Get("realm_id").(string),
@@ -60,7 +70,7 @@ func getRequiredActionFromData(data *schema.ResourceData) (*keycloak.RequiredAct
6070
Enabled: data.Get("enabled").(bool),
6171
DefaultAction: data.Get("default_action").(bool),
6272
Priority: data.Get("priority").(int),
63-
Config: make(map[string][]string),
73+
Config: config,
6474
}
6575

6676
return action, nil
@@ -74,6 +84,7 @@ func setRequiredActionData(data *schema.ResourceData, action *keycloak.RequiredA
7484
data.Set("enabled", action.Enabled)
7585
data.Set("default_action", action.DefaultAction)
7686
data.Set("priority", action.Priority)
87+
data.Set("config", action.Config)
7788
}
7889

7990
func resourceKeycloakRequiredActionsCreate(ctx context.Context, data *schema.ResourceData, meta interface{}) diag.Diagnostics {

provider/resource_keycloak_required_action_test.go

+41
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,28 @@ func TestAccKeycloakRequiredAction_basic(t *testing.T) {
2626
})
2727
}
2828

29+
func TestAccKeycloakRequiredAction_withConfig(t *testing.T) {
30+
realmName := acctest.RandomWithPrefix("tf-acc")
31+
requiredActionAlias := "UPDATE_PASSWORD"
32+
maxAuthAgeConfig := "3600"
33+
34+
resource.Test(t, resource.TestCase{
35+
ProviderFactories: testAccProviderFactories,
36+
PreCheck: func() { testAccPreCheck(t) },
37+
Steps: []resource.TestStep{
38+
{
39+
Config: testKeycloakRequiredAction_withConfig(realmName, requiredActionAlias, 37, maxAuthAgeConfig),
40+
Check: resource.ComposeTestCheckFunc(
41+
testAccCheckKeycloakRequiresActionExists(realmName, requiredActionAlias),
42+
resource.TestCheckResourceAttr("keycloak_required_action.required_action", "realm_id", realmName),
43+
resource.TestCheckResourceAttr("keycloak_required_action.required_action", "config.%", "1"),
44+
resource.TestCheckResourceAttr("keycloak_required_action.required_action", "config.max_auth_age", maxAuthAgeConfig),
45+
),
46+
},
47+
},
48+
})
49+
}
50+
2951
func TestAccKeycloakRequiredAction_unregisteredAction(t *testing.T) {
3052
realmName := acctest.RandomWithPrefix("tf-acc")
3153
requiredActionAlias := "webauthn-register"
@@ -128,6 +150,25 @@ resource "keycloak_required_action" "required_action" {
128150
`, realm, requiredActionAlias, priority)
129151
}
130152

153+
func testKeycloakRequiredAction_withConfig(realm, requiredActionAlias string, priority int, maxAuthAgeConfig string) string {
154+
return fmt.Sprintf(`
155+
resource "keycloak_realm" "realm" {
156+
realm = "%s"
157+
}
158+
resource "keycloak_required_action" "required_action" {
159+
realm_id = "${keycloak_realm.realm.realm}"
160+
alias = "%s"
161+
default_action = true
162+
enabled = true
163+
name = "My required Action"
164+
priority = %d
165+
config = {
166+
max_auth_age = "%s"
167+
}
168+
}
169+
`, realm, requiredActionAlias, priority, maxAuthAgeConfig)
170+
}
171+
131172
func testKeycloakRequiredAction_import(realm, requiredActionAlias string) string {
132173
return fmt.Sprintf(`
133174
resource "keycloak_realm" "realm" {

0 commit comments

Comments
 (0)