diff --git a/okta/policies.go b/okta/policies.go index e9556c33..39f6422c 100644 --- a/okta/policies.go +++ b/okta/policies.go @@ -36,7 +36,7 @@ func resourcePolicies() *schema.Resource { "description": &schema.Schema{ Type: schema.TypeString, Optional: true, - Description: "Policy Name", + Description: "Policy Description", }, "priority": &schema.Schema{ Type: schema.TypeInt, @@ -69,12 +69,10 @@ func resourcePolicies() *schema.Resource { Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "provider": { - Type: schema.TypeString, - Optional: true, - Default: "OKTA", - // ValidateFunc: validation.StringInSlice([]string{"OKTA", "ACTIVE_DIRECTORY"}, false), - ValidateFunc: validation.StringInSlice([]string{"OKTA"}, false), - Description: "Authentication Provider: OKTA or ACTIVE_DIRECTORY, Active Directory currently unsupported", + Type: schema.TypeString, + Optional: true, + ValidateFunc: validation.StringInSlice([]string{"OKTA", "ACTIVE_DIRECTORY"}, false), + Description: "Authentication Provider: OKTA or ACTIVE_DIRECTORY, Active Directory currently unsupported. Okta default = OKTA", }, "include": { Type: schema.TypeList, @@ -89,13 +87,13 @@ func resourcePolicies() *schema.Resource { }, }, "settings": { - Type: schema.TypeSet, + Type: schema.TypeList, Optional: true, Description: "Policy Level Settings for the Particular Policy Type", Elem: &schema.Resource{ Schema: map[string]*schema.Schema{ "password": { - Type: schema.TypeSet, + Type: schema.TypeList, Optional: true, Description: "User Password Policies", Elem: &schema.Resource{ @@ -103,128 +101,109 @@ func resourcePolicies() *schema.Resource { "minlength": { Type: schema.TypeInt, Optional: true, - Default: 8, - Description: "Minimum password length", + Description: "Minimum password length. Okta default = 8", }, "minlowercase": { Type: schema.TypeInt, Optional: true, - Default: 1, ValidateFunc: validation.IntBetween(0, 1), - Description: "If a password must contain at least one lower case letter: 0 = no, 1 = yes", + Description: "If a password must contain at least one lower case letter: 0 = no, 1 = yes. Okta default = 1", }, "minuppercase": { Type: schema.TypeInt, Optional: true, - Default: 1, ValidateFunc: validation.IntBetween(0, 1), - Description: "If a password must contain at least one upper case letter: 0 = no, 1 = yes", + Description: "If a password must contain at least one upper case letter: 0 = no, 1 = yes. Okta default = 1", }, "minnumber": { Type: schema.TypeInt, Optional: true, - Default: 1, ValidateFunc: validation.IntBetween(0, 1), - Description: "If a password must contain at least one number: 0 = no, 1 = yes", + Description: "If a password must contain at least one number: 0 = no, 1 = yes. Okta default = 1", }, "minsymbol": { Type: schema.TypeInt, Optional: true, - Default: 1, ValidateFunc: validation.IntBetween(0, 1), - Description: "If a password must contain at least one symbol (!@#$%^&*): 0 = no, 1 = yes", + Description: "If a password must contain at least one symbol (!@#$%^&*): 0 = no, 1 = yes. Okta default = 1", }, "excludeusername": { Type: schema.TypeBool, Optional: true, - Default: true, - Description: "If the user name must be excluded from the password", + Description: "If the user name must be excluded from the password. Okta default = true", }, "excludeattributes": { Type: schema.TypeList, Optional: true, - Description: "User profile attributes that must be excluded from the password: firstname or lastname", + Description: "User profile attributes that must be excluded from the password: allowed values = \"firstname\" and/or \"lastname\"", Elem: &schema.Schema{Type: schema.TypeString}, }, "dictionarylookup": { Type: schema.TypeBool, Optional: true, - Default: false, - Description: "Check Passwords Against Common Password Dictionary", + Description: "Check Passwords Against Common Password Dictionary. Okta default = false", }, "maxagedays": { Type: schema.TypeInt, Optional: true, - Default: 0, - Description: "Length in days a password is valid before expiry: 0 = no limit", + Description: "Length in days a password is valid before expiry: 0 = no limit. Okta default = 0", }, "expirewarndays": { Type: schema.TypeInt, Optional: true, - Default: 0, - Description: "Length in days a user will be warned before password expiry: 0 = no warning", + Description: "Length in days a user will be warned before password expiry: 0 = no warning. Okta default = 0", }, "minageminutes": { Type: schema.TypeInt, Optional: true, - Default: 0, - Description: "Minimum time interval in minutes between password changes: 0 = no limit", + Description: "Minimum time interval in minutes between password changes: 0 = no limit. Okta default = 0", }, "historycount": { Type: schema.TypeInt, Optional: true, - Default: 0, - Description: "Number of distinct passwords that can be created before they can be reused: 0 = none", + Description: "Number of distinct passwords that can be created before they can be reused: 0 = none. Okta default = 0", }, "maxlockoutattempts": { Type: schema.TypeInt, Optional: true, - Default: 0, - Description: "Number of unsucessful login attempts allowed before lockout: 0 = no limit", + Description: "Number of unsucessful login attempts allowed before lockout: 0 = no limit. Okta default = 0", }, "autounlockminutes": { Type: schema.TypeInt, Optional: true, - Default: 0, - Description: "Number of minutes before a locked account is unlocked: 0 = no limit", + Description: "Number of minutes before a locked account is unlocked: 0 = no limit. Okta default = 0", }, "showlockoutfailures": { Type: schema.TypeBool, Optional: true, - Default: false, - Description: "If a user should be informed when their account is locked", + Description: "If a user should be informed when their account is locked. Okta default = false", }, "recoveryquestion": { Type: schema.TypeString, Optional: true, - Default: "ACTIVE", ValidateFunc: validation.StringInSlice([]string{"ACTIVE", "INACTIVE"}, false), - Description: "Enable or Disable the recovery question: ACTIVE or INACTIVE", + Description: "Enable or Disable the recovery question: ACTIVE or INACTIVE. Okta default = ACTIVE", }, "questionminlength": { Type: schema.TypeInt, Optional: true, - Default: 4, - Description: "Min length of the password recovery question answer", + Description: "Min length of the password recovery question answer. Okta default = 4", }, "recoveryemailtoken": { Type: schema.TypeInt, Optional: true, - Default: 10080, - Description: "Lifetime in minutes of the recovery email token", + Description: "Lifetime in minutes of the recovery email token. Okta default = 10080", }, "smsrecovery": { Type: schema.TypeString, Optional: true, - Default: "INACTIVE", ValidateFunc: validation.StringInSlice([]string{"ACTIVE", "INACTIVE"}, false), - Description: "If SMS password recovery is enabled or disabled: ACTIVE or INACTIVE", + Description: "If SMS password recovery is enabled or disabled: ACTIVE or INACTIVE. Okta default = INACTIVE", }, "skipunlock": { Type: schema.TypeBool, Optional: true, - Default: false, - Description: "When performing an unlock operation on an Active Directory mastered user who is locked out of Okta, the system should also attempt to unlock the user’s Windows account", + Description: "When performing an unlock operation on an Active Directory mastered user who is locked out of Okta, the system should also attempt to unlock the user’s Windows account. Okta default = false", }, }, }, @@ -248,13 +227,13 @@ func resourcePolicyCreate(d *schema.ResourceData, m interface{}) error { } else { switch d.Get("type").(string) { case "PASSWORD": - policyPassword(thisPolicy, "create", d, m) + err = policyPassword(thisPolicy, "create", d, m) if err != nil { return err } case "OKTA_SIGN_ON": - policySignOn(thisPolicy, "create", d, m) + err = policySignOn(thisPolicy, "create", d, m) if err != nil { return err } @@ -299,13 +278,13 @@ func resourcePolicyUpdate(d *schema.ResourceData, m interface{}) error { if exists == true { switch d.Get("type").(string) { case "PASSWORD": - policyPassword(thisPolicy, "create", d, m) + err = policyPassword(thisPolicy, "update", d, m) if err != nil { return err } case "OKTA_SIGN_ON": - policySignOn(thisPolicy, "create", d, m) + err = policySignOn(thisPolicy, "update", d, m) if err != nil { return err } @@ -401,21 +380,43 @@ func policyPassword(thisPolicy *policyType, action string, d *schema.ResourceDat } else { template.System = false } - template.Conditions.AuthProvider.Provider = "OKTA" // default - template.Settings.Recovery.Factors.OktaEmail.Status = "ACTIVE" // default, read only - template.Settings.Recovery.Factors.RecoveryQuestion.Status = "ACTIVE" // defaulta - - //for _, cond := range d.Get("conditions").([]interface{}) { - // // TODO: authprovider support not included until Active Directory support included - // vals := cond.(map[string]interface{}) - // if attr, ok := vals["groups"]; ok { - // include := make([]string, 0) - // for _, id := range attr { - // include = append(include, id.(string)) - // return fmt.Errorf("%+v", include) - // } - // } - //} + template.Conditions.AuthProvider.Provider = "OKTA" // okta required default + template.Settings.Recovery.Factors.OktaEmail.Status = "ACTIVE" // okta required default + template.Settings.Recovery.Factors.RecoveryQuestion.Status = "ACTIVE" // okta required default + + if len(d.Get("conditions").([]interface{})) > 0 { + if len(d.Get("conditions.0.groups").([]interface{})) > 0 { + groups := d.Get("conditions.0.groups").([]interface{}) + include := make([]string, len(groups)) + for _, vals := range groups { + include = append(include, vals.(string)) + } + //template.Conditions.People.Groups.Include = include + //return fmt.Errorf("%+v", include) + } + if len(d.Get("conditions.0.authprovider").([]interface{})) > 0 { + // TODO: add authprovider Active Directory support + } + } + if len(d.Get("settings.0.password").([]interface{})) > 0 { + template.Settings.Password.Complexity.MinLength = d.Get("settings.0.password.0.minlength").(int) + template.Settings.Password.Complexity.MinLowerCase = d.Get("settings.0.password.0.minlowercase").(int) + template.Settings.Password.Complexity.MinUpperCase = d.Get("settings.0.password.0.minuppercase").(int) + template.Settings.Password.Complexity.MinNumber = d.Get("settings.0.password.0.minnumber").(int) + template.Settings.Password.Complexity.MinSymbol = d.Get("settings.0.password.0.minsymbol").(int) + template.Settings.Password.Complexity.ExcludeUsername = d.Get("settings.0.password.0.excludeusername").(bool) + //template.Settings.Password.Complexity.ExcludeAttributes = d.Get("settings.0.password.0.excludeattributes").list! + template.Settings.Password.Complexity.Dictionary.Common.Exclude = d.Get("settings.0.password.0.dictionarylookup").(bool) + template.Settings.Password.Age.MaxAgeDays = d.Get("settings.0.password.0.maxagedays").(int) + template.Settings.Password.Age.ExpireWarnDays = d.Get("settings.0.password.0.expirewarndays").(int) + template.Settings.Password.Age.MinAgeMinutes = d.Get("settings.0.password.0.minageminutes").(int) + template.Settings.Password.Age.HistoryCount = d.Get("settings.0.password.0.historycount").(int) + template.Settings.Password.Lockout.MaxAttempts = d.Get("settings.0.password.0.maxlockoutattempts").(int) + template.Settings.Password.Lockout.AutoUnlockMinutes = d.Get("settings.0.password.0.autounlockminutes").(int) + template.Settings.Password.Lockout.ShowLockoutFailures = d.Get("settings.0.password.0.showlockoutfailures").(bool) + } + + //return fmt.Errorf("%+v", template) switch action { case "create":