Skip to content

Commit 91a5cc8

Browse files
Ensure security defenses settings are set on setRealmData realm (#1257)
This ensures that the securityDefensesSettings propagated to the terraform state. Avoid repeated call to setRealmData(..) from resourceKeycloakRealmCreate. Mark resource_keycloak_realm `security_defenses` property as computed as it is populated with defaults after realm creation. Fixes #1257 Signed-off-by: Thomas Darimont <[email protected]>
1 parent 3400069 commit 91a5cc8

File tree

3 files changed

+31
-10
lines changed

3 files changed

+31
-10
lines changed

keycloak/realm.go

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,9 @@ package keycloak
33
import (
44
"context"
55
"fmt"
6-
"github.com/keycloak/terraform-provider-keycloak/keycloak/types"
76
"strings"
7+
8+
"github.com/keycloak/terraform-provider-keycloak/keycloak/types"
89
)
910

1011
type Key struct {
@@ -86,7 +87,7 @@ type Realm struct {
8687
DefaultDefaultClientScopes []string `json:"defaultDefaultClientScopes,omitempty"`
8788
DefaultOptionalClientScopes []string `json:"defaultOptionalClientScopes,omitempty"`
8889

89-
BrowserSecurityHeaders BrowserSecurityHeaders `json:"browserSecurityHeaders"`
90+
BrowserSecurityHeaders *BrowserSecurityHeaders `json:"browserSecurityHeaders,omitempty"`
9091

9192
BruteForceProtected bool `json:"bruteForceProtected"`
9293
PermanentLockout bool `json:"permanentLockout"`

provider/resource_keycloak_realm.go

Lines changed: 17 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -475,6 +475,7 @@ func resourceKeycloakRealm() *schema.Resource {
475475
"security_defenses": {
476476
Type: schema.TypeList,
477477
Optional: true,
478+
Computed: true,
478479
MaxItems: 1,
479480
Elem: &schema.Resource{
480481
Schema: map[string]*schema.Schema{
@@ -998,7 +999,7 @@ func getRealmFromData(data *schema.ResourceData, keycloakVersion *version.Versio
998999
if len(headersConfig) == 1 {
9991000
headerSettings := headersConfig[0].(map[string]interface{})
10001001

1001-
realm.BrowserSecurityHeaders = keycloak.BrowserSecurityHeaders{
1002+
realm.BrowserSecurityHeaders = &keycloak.BrowserSecurityHeaders{
10021003
ContentSecurityPolicy: headerSettings["content_security_policy"].(string),
10031004
ContentSecurityPolicyReportOnly: headerSettings["content_security_policy_report_only"].(string),
10041005
StrictTransportSecurity: headerSettings["strict_transport_security"].(string),
@@ -1008,8 +1009,6 @@ func getRealmFromData(data *schema.ResourceData, keycloakVersion *version.Versio
10081009
XXSSProtection: headerSettings["x_xss_protection"].(string),
10091010
ReferrerPolicy: headerSettings["referrer_policy"].(string),
10101011
}
1011-
} else {
1012-
setDefaultSecuritySettingHeaders(realm)
10131012
}
10141013

10151014
bruteForceDetectionConfig := securityDefensesSettings["brute_force_detection"].([]interface{})
@@ -1027,7 +1026,6 @@ func getRealmFromData(data *schema.ResourceData, keycloakVersion *version.Versio
10271026
setDefaultSecuritySettingsBruteForceDetection(realm)
10281027
}
10291028
} else {
1030-
setDefaultSecuritySettingHeaders(realm)
10311029
setDefaultSecuritySettingsBruteForceDetection(realm)
10321030
}
10331031

@@ -1178,7 +1176,7 @@ func getRealmFromData(data *schema.ResourceData, keycloakVersion *version.Versio
11781176
}
11791177

11801178
func setDefaultSecuritySettingHeaders(realm *keycloak.Realm) {
1181-
realm.BrowserSecurityHeaders = keycloak.BrowserSecurityHeaders{
1179+
realm.BrowserSecurityHeaders = &keycloak.BrowserSecurityHeaders{
11821180
ContentSecurityPolicy: "frame-src 'self'; frame-ancestors 'self'; object-src 'none';",
11831181
ContentSecurityPolicyReportOnly: "",
11841182
StrictTransportSecurity: "max-age=31536000; includeSubDomains",
@@ -1309,6 +1307,14 @@ func setRealmData(data *schema.ResourceData, realm *keycloak.Realm, keycloakVers
13091307
securityDefensesSettings["brute_force_detection"] = []interface{}{getBruteForceDetectionSettings(realm)}
13101308
data.Set("security_defenses", []interface{}{securityDefensesSettings})
13111309
}
1310+
} else {
1311+
// if we do not have any configuration in the realm config, use the default config generated by Keycloak
1312+
securityDefensesSettings := make(map[string]interface{})
1313+
securityDefensesSettings["headers"] = []interface{}{getHeaderSettings(realm)}
1314+
if realm.BruteForceProtected {
1315+
securityDefensesSettings["brute_force_detection"] = []interface{}{getBruteForceDetectionSettings(realm)}
1316+
}
1317+
data.Set("security_defenses", []interface{}{securityDefensesSettings})
13121318
}
13131319

13141320
data.Set("password_policy", realm.PasswordPolicy)
@@ -1392,6 +1398,11 @@ func getBruteForceDetectionSettings(realm *keycloak.Realm) map[string]interface{
13921398
}
13931399

13941400
func getHeaderSettings(realm *keycloak.Realm) map[string]interface{} {
1401+
1402+
if realm.BrowserSecurityHeaders == nil {
1403+
return nil
1404+
}
1405+
13951406
headersSettings := make(map[string]interface{})
13961407
headersSettings["content_security_policy"] = realm.BrowserSecurityHeaders.ContentSecurityPolicy
13971408
headersSettings["content_security_policy_report_only"] = realm.BrowserSecurityHeaders.ContentSecurityPolicyReportOnly
@@ -1431,7 +1442,7 @@ func resourceKeycloakRealmCreate(ctx context.Context, data *schema.ResourceData,
14311442
return diag.FromErr(err)
14321443
}
14331444

1434-
setRealmData(data, realm, keycloakVersion)
1445+
data.SetId(realm.Realm)
14351446

14361447
return resourceKeycloakRealmRead(ctx, data, meta)
14371448
}

provider/resource_keycloak_realm_test.go

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@ package provider
22

33
import (
44
"fmt"
5+
"regexp"
6+
"testing"
7+
58
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/acctest"
69
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
710
"github.com/hashicorp/terraform-plugin-sdk/v2/terraform"
811
"github.com/keycloak/terraform-provider-keycloak/keycloak"
9-
"regexp"
10-
"testing"
1112
)
1213

1314
func TestAccKeycloakRealm_basic(t *testing.T) {
@@ -629,6 +630,14 @@ func TestAccKeycloakRealm_securityDefenses(t *testing.T) {
629630
testAccCheckKeycloakRealmSecurityDefensesBruteForceDetectionFailureFactor("keycloak_realm.realm", 30),
630631
),
631632
},
633+
{
634+
Config: testKeycloakRealm_basic(realmName, realmDisplayName, realmDisplayNameHtml),
635+
Check: resource.ComposeTestCheckFunc(
636+
testAccCheckKeycloakRealmSecurityDefensesHeaders("keycloak_realm.realm", ""), // empty xFrameOptions
637+
testAccCheckKeycloakRealmSecurityDefensesBruteForceDetection("keycloak_realm.realm", false),
638+
testAccCheckKeycloakRealmSecurityDefensesBruteForceDetectionFailureFactor("keycloak_realm.realm", 30),
639+
),
640+
},
632641
},
633642
})
634643
}

0 commit comments

Comments
 (0)