Skip to content

Commit

Permalink
Merge pull request #1104 from okta/themes_feature
Browse files Browse the repository at this point in the history
Data Sources "okta_themes", "okta_theme", Resource "okta_theme"
  • Loading branch information
monde authored May 13, 2022
2 parents 6825741 + 2ea0bc9 commit efab351
Show file tree
Hide file tree
Showing 43 changed files with 1,191 additions and 133 deletions.
4 changes: 2 additions & 2 deletions examples/okta_email_customization/datasource.tf
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ data "okta_email_customizations" "forgot_password" {
}

data "okta_email_customization" "forgot_password_en" {
customization_id = tolist(data.okta_email_customizations.forgot_password.email_customizations)[0].id
brand_id = tolist(data.okta_brands.test.brands)[0].id
template_name = "ForgotPassword"
}
customization_id = tolist(data.okta_email_customizations.forgot_password.email_customizations)[0].id
}
12 changes: 12 additions & 0 deletions examples/okta_theme/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# okta_theme

This resource represents a theme of a brand for an Okta organization. More
information can be found in the
[Theme](https://developer.okta.com/docs/reference/api/brands/#theme-response-object)
API documentation.

- Example [datastore.tf](./datasource.tf)
- Example [basic.tf](./basic.tf)
- Example [updated.tf](./updated.tf)
- Example [import.tf](./import.tf)
- Example [delete-images.tf](./delete-images.tf)
21 changes: 21 additions & 0 deletions examples/okta_theme/basic.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
# This example is part of the test harness. The okta_theme resource state has
# already been imported via import.tf

data "okta_brands" "test" {
}

resource "okta_theme" "example" {
brand_id = tolist(data.okta_brands.test.brands)[0].id

logo = "../examples/okta_theme/okta_logo.png"
favicon = "../examples/okta_theme/okta_favicon.png"
background_image = "../examples/okta_theme/okta_background_image.png"
primary_color_hex = "#1662dd"
primary_color_contrast_hex = "#ffffff"
secondary_color_hex = "#ebebed"
secondary_color_contrast_hex = "#000000"
sign_in_page_touch_point_variant = "OKTA_DEFAULT"
end_user_dashboard_touch_point_variant = "OKTA_DEFAULT"
error_page_touch_point_variant = "OKTA_DEFAULT"
email_template_touch_point_variant = "OKTA_DEFAULT"
}
11 changes: 11 additions & 0 deletions examples/okta_theme/datasource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
data "okta_brands" "test" {
}

data "okta_themes" "test" {
brand_id = tolist(data.okta_brands.test.brands)[0].id
}

data "okta_theme" "test" {
brand_id = tolist(data.okta_brands.test.brands)[0].id
theme_id = tolist(data.okta_themes.test.themes)[0].id
}
22 changes: 22 additions & 0 deletions examples/okta_theme/delete-images.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
# This example is part of the test harness. The okta_theme resource state has
# already been imported via import.tf

data "okta_brands" "test" {
}

resource "okta_theme" "example" {
brand_id = tolist(data.okta_brands.test.brands)[0].id

logo = ""
favicon = ""
background_image = ""

primary_color_hex = "#1662ff"
primary_color_contrast_hex = "#ffffff"
secondary_color_hex = "#fbfbfd"
secondary_color_contrast_hex = "#000000"
sign_in_page_touch_point_variant = "OKTA_DEFAULT"
end_user_dashboard_touch_point_variant = "OKTA_DEFAULT"
error_page_touch_point_variant = "OKTA_DEFAULT"
email_template_touch_point_variant = "OKTA_DEFAULT"
}
11 changes: 11 additions & 0 deletions examples/okta_theme/import.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
data "okta_brands" "test" {
}

data "okta_themes" "test" {
brand_id = tolist(data.okta_brands.test.brands)[0].id
}

resource "okta_theme" "example" {
brand_id = tolist(data.okta_brands.test.brands)[0].id
theme_id = tolist(data.okta_themes.test.themes)[0].id
}
Binary file added examples/okta_theme/okta_background_image.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/okta_theme/okta_favicon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added examples/okta_theme/okta_logo.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
18 changes: 18 additions & 0 deletions examples/okta_theme/updated.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
# This example is part of the test harness. The okta_theme resource state has
# already been imported via import.tf

data "okta_brands" "test" {
}

resource "okta_theme" "example" {
brand_id = tolist(data.okta_brands.test.brands)[0].id

primary_color_hex = "#1662ff"
primary_color_contrast_hex = "#ffffff"
secondary_color_hex = "#fbfbfd"
secondary_color_contrast_hex = "#000000"
sign_in_page_touch_point_variant = "OKTA_DEFAULT"
end_user_dashboard_touch_point_variant = "OKTA_DEFAULT"
error_page_touch_point_variant = "OKTA_DEFAULT"
email_template_touch_point_variant = "OKTA_DEFAULT"
}
8 changes: 8 additions & 0 deletions examples/okta_themes/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
# okta_themes

This resource represents a themes of a brand for an Okta organization. More
information can be found in the
[Theme](https://developer.okta.com/docs/reference/api/brands/#get-themes)
API documentation.

- Example [datastore.tf](./datasource.tf)
6 changes: 6 additions & 0 deletions examples/okta_themes/datasource.tf
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
data "okta_brands" "test" {
}

data "okta_themes" "test" {
brand_id = tolist(data.okta_brands.test.brands)[0].id
}
28 changes: 1 addition & 27 deletions okta/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,10 @@ package okta

import (
"context"
"crypto/sha256"
"encoding/hex"
"encoding/json"
"errors"
"fmt"
"io"
"log"
"net/http"
"os"
"strings"
"sync"
"time"
Expand Down Expand Up @@ -92,7 +87,7 @@ var (
DiffSuppressFunc: func(k, old, new string, d *schema.ResourceData) bool {
return new == ""
},
StateFunc: logoStateFunc,
StateFunc: localFileStateFunc,
},
"logo_url": {
Type: schema.TypeString,
Expand Down Expand Up @@ -724,24 +719,3 @@ func setAppUsersIDsAndGroupsIDs(ctx context.Context, d *schema.ResourceData, cli
}
return nil
}

func computeFileHash(filename string) string {
file, err := os.Open(filename)
if err != nil {
return ""
}
h := sha256.New()
if _, err := io.Copy(h, file); err != nil {
log.Fatal(err)
}
_ = file.Close()
return hex.EncodeToString(h.Sum(nil))
}

func logoStateFunc(val interface{}) string {
logoPath := val.(string)
if logoPath == "" {
return ""
}
return computeFileHash(logoPath)
}
2 changes: 1 addition & 1 deletion okta/app_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ func TestLogoStateFunc(t *testing.T) {
},
}
for _, c := range cases {
result := logoStateFunc(c.input)
result := localFileStateFunc(c.input)
if result != c.expected {
t.Errorf("Error matching logo, expected %q, got %q, for file %q", c.expected, result, c.input)
}
Expand Down
45 changes: 13 additions & 32 deletions okta/brand.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ var brandResourceSchema = map[string]*schema.Schema{
Type: schema.TypeString,
Optional: true,
Description: "Custom privacy policy URL",
DiffSuppressFunc: suppressDuringCreate,
DiffSuppressFunc: suppressDuringCreateFunc("brand_id"),
},
"links": {
Type: schema.TypeString,
Expand All @@ -40,23 +40,15 @@ var brandResourceSchema = map[string]*schema.Schema{
Optional: true,
Default: false,
Description: `Removes "Powered by Okta" from the Okta-hosted sign-in page and "© 2021 Okta, Inc." from the Okta End-User Dashboard`,
DiffSuppressFunc: suppressDuringCreate,
DiffSuppressFunc: suppressDuringCreateFunc("brand_id"),
},
}

func suppressDuringCreate(k, old, new string, d *schema.ResourceData) bool {
// If brand_id has changed assume this is create and treat the properties as readers not caring about what would otherwise apear to be drift.
if d.HasChange("brand_id") {
return true
}
return old == new
}

var brandDataSourceSchema = map[string]*schema.Schema{
"brand_id": {
"id": {
Type: schema.TypeString,
Required: true,
Description: "Brand ID",
Computed: true,
Description: "The ID of the Brand",
},
"custom_privacy_policy_url": {
Type: schema.TypeString,
Expand All @@ -76,31 +68,20 @@ var brandDataSourceSchema = map[string]*schema.Schema{
}

var brandsDataSourceSchema = map[string]*schema.Schema{
"id": {
Type: schema.TypeString,
Computed: true,
Description: "Brand ID",
},
"custom_privacy_policy_url": {
Type: schema.TypeString,
"brands": {
Type: schema.TypeSet,
Computed: true,
Description: "Custom privacy policy URL",
},
"links": {
Type: schema.TypeString,
Computed: true,
Description: "Link relations for this object - JSON HAL - Discoverable resources related to the brand",
},
"remove_powered_by_okta": {
Type: schema.TypeBool,
Computed: true,
Description: `Removes "Powered by Okta" from the Okta-hosted sign-in page and "© 2021 Okta, Inc." from the Okta End-User Dashboard`,
Description: "List of `okta_brand` belonging to the organization",
Elem: &schema.Resource{
Schema: brandDataSourceSchema,
},
},
}

func flattenBrand(brand *okta.Brand) map[string]interface{} {
attrs := map[string]interface{}{}
// NOTE: explicitly set defaults on brand

attrs["id"] = brand.Id
attrs["custom_privacy_policy_url"] = ""
if brand.CustomPrivacyPolicyUrl != "" {
attrs["custom_privacy_policy_url"] = brand.CustomPrivacyPolicyUrl
Expand Down
11 changes: 10 additions & 1 deletion okta/data_source_okta_brand.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,16 @@ import (
func dataSourceBrand() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceBrandRead,
Schema: brandDataSourceSchema,
Schema: buildSchema(
map[string]*schema.Schema{
"brand_id": {
Type: schema.TypeString,
Required: true,
Description: "Brand ID",
},
},
brandDataSourceSchema,
),
}
}

Expand Down
2 changes: 1 addition & 1 deletion okta/data_source_okta_brand_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ func TestAccDataSourceOktaBrand_read(t *testing.T) {
Config: config,
Destroy: false,
Check: resource.ComposeTestCheckFunc(
resource.TestCheckResourceAttrSet("data.okta_brand.example", "brand_id"),
resource.TestCheckResourceAttrSet("data.okta_brand.example", "id"),
resource.TestCheckResourceAttrSet("data.okta_brand.example", "links"),
),
},
Expand Down
13 changes: 2 additions & 11 deletions okta/data_source_okta_brands.go
Original file line number Diff line number Diff line change
Expand Up @@ -10,16 +10,7 @@ import (
func dataSourceBrands() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceBrandsRead,
Schema: map[string]*schema.Schema{
"brands": {
Type: schema.TypeSet,
Computed: true,
Description: "List of `okta_brand` belonging to the organization",
Elem: &schema.Resource{
Schema: brandsDataSourceSchema,
},
},
},
Schema: brandsDataSourceSchema,
}
}

Expand All @@ -37,7 +28,7 @@ func dataSourceBrandsRead(ctx context.Context, d *schema.ResourceData, m interfa
arr[i] = rawMap
}
brandDataSource := &schema.Resource{
Schema: brandResourceSchema,
Schema: brandDataSourceSchema,
}
_ = d.Set("brands", schema.NewSet(schema.HashResource(brandDataSource), arr))

Expand Down
23 changes: 21 additions & 2 deletions okta/data_source_okta_email_customization.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,26 @@ import (
func dataSourceEmailCustomization() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceEmailCustomizationRead,
Schema: emailCustomizationDataSourceSchema,
Schema: buildSchema(
map[string]*schema.Schema{
"brand_id": {
Type: schema.TypeString,
Required: true,
Description: "Brand ID",
},
"template_name": {
Type: schema.TypeString,
Required: true,
Description: "Template Name",
},
"customization_id": {
Type: schema.TypeString,
Required: true,
Description: "The ID of the customization",
},
},
emailCustomizationDataSourceSchema,
),
}
}

Expand All @@ -37,7 +56,7 @@ func dataSourceEmailCustomizationRead(ctx context.Context, d *schema.ResourceDat
}

d.SetId(fmt.Sprintf("email_customization-%s-%s-%s", customization.Id, templateName.(string), brandID.(string)))
rawMap := flattenEmailCustomization(brandID.(string), templateName.(string), true, customization)
rawMap := flattenEmailCustomization(customization)
err = setNonPrimitives(d, rawMap)
if err != nil {
return diag.Errorf("failed to set email customization properties: %v", err)
Expand Down
2 changes: 1 addition & 1 deletion okta/data_source_okta_email_customization_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ func TestAccDataSourceOktaEmailCustomization_read(t *testing.T) {
resource.TestCheckResourceAttrSet("data.okta_email_customization.forgot_password_en", "language"),
resource.TestCheckResourceAttr("data.okta_email_customization.forgot_password_en", "language", "en"),
resource.TestCheckResourceAttrSet("data.okta_email_customization.forgot_password_en", "is_default"),
resource.TestCheckResourceAttr("data.okta_email_customization.forgot_password_en", "is_default", "false"),
resource.TestCheckResourceAttr("data.okta_email_customization.forgot_password_en", "is_default", "true"),
resource.TestCheckResourceAttrSet("data.okta_email_customization.forgot_password_en", "subject"),
resource.TestCheckResourceAttr("data.okta_email_customization.forgot_password_en", "subject", "Stuff"),
resource.TestCheckResourceAttrSet("data.okta_email_customization.forgot_password_en", "body"),
Expand Down
18 changes: 16 additions & 2 deletions okta/data_source_okta_email_customizations.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,21 @@ import (
func dataSourceEmailCustomizations() *schema.Resource {
return &schema.Resource{
ReadContext: dataSourceEmailCustomizationsRead,
Schema: emailCustomizationsDataSourceSchema,
Schema: buildSchema(
map[string]*schema.Schema{
"brand_id": {
Type: schema.TypeString,
Required: true,
Description: "Brand ID",
},
"template_name": {
Type: schema.TypeString,
Required: true,
Description: "Template Name",
},
},
emailCustomizationsDataSourceSchema,
),
}
}

Expand All @@ -35,7 +49,7 @@ func dataSourceEmailCustomizationsRead(ctx context.Context, d *schema.ResourceDa
d.SetId(fmt.Sprintf("email_customizations-%s-%s", templateName, brandID.(string)))
arr := make([]interface{}, len(customizations))
for i, customization := range customizations {
rawMap := flattenEmailCustomization(brandID.(string), templateName.(string), true, customization)
rawMap := flattenEmailCustomization(customization)
arr[i] = rawMap
}

Expand Down
Loading

0 comments on commit efab351

Please sign in to comment.