@@ -2,35 +2,122 @@ package idaas
22
33import (
44 "context"
5+ "fmt"
6+ "time"
57
68 "github.com/hashicorp/terraform-plugin-sdk/v2/diag"
79 "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
8- "github.com/okta/terraform-provider-okta/okta/utils"
910 "github.com/okta/terraform-provider-okta/sdk"
1011 "github.com/okta/terraform-provider-okta/sdk/query"
1112)
1213
14+ // dataSourceAppUserAssignments returns a Terraform data source for retrieving
15+ // detailed information about users assigned to an Okta application.
16+ // This data source exposes the full API response including user status, scope,
17+ // profile data, credentials, and timestamps.
1318func dataSourceAppUserAssignments () * schema.Resource {
1419 return & schema.Resource {
1520 ReadContext : dataSourceAppUserAssignmentsRead ,
1621 Schema : map [string ]* schema.Schema {
1722 "id" : {
1823 Type : schema .TypeString ,
1924 Required : true ,
20- Description : "ID of the Okta App being queried for groups " ,
25+ Description : "ID of the Okta App being queried for users " ,
2126 ForceNew : true ,
2227 },
2328 "users" : {
2429 Type : schema .TypeSet ,
2530 Computed : true ,
26- Elem : & schema.Schema {Type : schema .TypeString },
27- Description : "List of user IDs assigned to the app" ,
31+ Description : "List of users assigned to the app with detailed information" ,
32+ Elem : & schema.Resource {
33+ Schema : map [string ]* schema.Schema {
34+ "id" : {
35+ Type : schema .TypeString ,
36+ Computed : true ,
37+ Description : "Unique identifier for the Okta User" ,
38+ },
39+ "external_id" : {
40+ Type : schema .TypeString ,
41+ Computed : true ,
42+ Description : "The ID of the user in the target app that's linked to the Okta Application User object" ,
43+ },
44+ "status" : {
45+ Type : schema .TypeString ,
46+ Computed : true ,
47+ Description : "Status of an Application User (ACTIVE, INACTIVE, PROVISIONED, etc.)" ,
48+ },
49+ "scope" : {
50+ Type : schema .TypeString ,
51+ Computed : true ,
52+ Description : "Indicates if the assignment is direct (USER) or by group membership (GROUP)" ,
53+ },
54+ "sync_state" : {
55+ Type : schema .TypeString ,
56+ Computed : true ,
57+ Description : "The synchronization state for the Application User (DISABLED, ENABLED, ERROR, etc.)" ,
58+ },
59+ "created" : {
60+ Type : schema .TypeString ,
61+ Computed : true ,
62+ Description : "Timestamp when the Application User was created" ,
63+ },
64+ "last_updated" : {
65+ Type : schema .TypeString ,
66+ Computed : true ,
67+ Description : "Timestamp when the Application User was last updated" ,
68+ },
69+ "last_sync" : {
70+ Type : schema .TypeString ,
71+ Computed : true ,
72+ Description : "Timestamp of the last synchronization operation" ,
73+ },
74+ "password_changed" : {
75+ Type : schema .TypeString ,
76+ Computed : true ,
77+ Description : "Timestamp when the Application User password was last changed" ,
78+ },
79+ "status_changed" : {
80+ Type : schema .TypeString ,
81+ Computed : true ,
82+ Description : "Timestamp when the Application User status was last changed" ,
83+ },
84+ "profile" : {
85+ Type : schema .TypeMap ,
86+ Computed : true ,
87+ Description : "Profile properties for the user in this application" ,
88+ Elem : & schema.Schema {Type : schema .TypeString },
89+ },
90+ "credentials" : {
91+ Type : schema .TypeList ,
92+ Computed : true ,
93+ Description : "Credentials for the Application User" ,
94+ Elem : & schema.Resource {
95+ Schema : map [string ]* schema.Schema {
96+ "user_name" : {
97+ Type : schema .TypeString ,
98+ Computed : true ,
99+ Description : "Username for the Application User" ,
100+ },
101+ "password" : {
102+ Type : schema .TypeString ,
103+ Computed : true ,
104+ Description : "Password for the Application User" ,
105+ Sensitive : true ,
106+ },
107+ },
108+ },
109+ },
110+ },
111+ },
28112 },
29113 },
30- Description : "Get a set of users assigned to an Okta application." ,
114+ Description : "Get a set of users assigned to an Okta application with detailed information ." ,
31115 }
32116}
33117
118+ // dataSourceAppUserAssignmentsRead retrieves all users assigned to an Okta application
119+ // and returns detailed information about each user including their status, scope,
120+ // profile data, credentials, and various timestamps.
34121func dataSourceAppUserAssignmentsRead (ctx context.Context , d * schema.ResourceData , meta interface {}) diag.Diagnostics {
35122 client := getOktaClientFromMetadata (meta )
36123 id := d .Get ("id" ).(string )
@@ -49,11 +136,86 @@ func dataSourceAppUserAssignmentsRead(ctx context.Context, d *schema.ResourceDat
49136 userAssignments = append (userAssignments , moreAssignments ... )
50137 }
51138
52- var users []string
139+ var users []map [ string ] interface {}
53140 for _ , assignment := range userAssignments {
54- users = append (users , assignment .Id )
141+ user := processAppUserAssignment (assignment )
142+ users = append (users , user )
55143 }
56- _ = d .Set ("users" , utils .ConvertStringSliceToSet (users ))
144+
145+ _ = d .Set ("users" , users )
57146 d .SetId (id )
58147 return nil
59148}
149+
150+ // processAppUserAssignment converts an AppUser to a Terraform-compatible map
151+ func processAppUserAssignment (assignment * sdk.AppUser ) map [string ]interface {} {
152+ user := map [string ]interface {}{
153+ "id" : assignment .Id ,
154+ }
155+
156+ if assignment .ExternalId != "" {
157+ user ["external_id" ] = assignment .ExternalId
158+ }
159+ if assignment .Status != "" {
160+ user ["status" ] = assignment .Status
161+ }
162+ if assignment .Scope != "" {
163+ user ["scope" ] = assignment .Scope
164+ }
165+ if assignment .SyncState != "" {
166+ user ["sync_state" ] = assignment .SyncState
167+ }
168+ if assignment .Created != nil {
169+ user ["created" ] = assignment .Created .Format (time .RFC3339 )
170+ }
171+ if assignment .LastUpdated != nil {
172+ user ["last_updated" ] = assignment .LastUpdated .Format (time .RFC3339 )
173+ }
174+ if assignment .LastSync != nil {
175+ user ["last_sync" ] = assignment .LastSync .Format (time .RFC3339 )
176+ }
177+ if assignment .PasswordChanged != nil {
178+ user ["password_changed" ] = assignment .PasswordChanged .Format (time .RFC3339 )
179+ }
180+ if assignment .StatusChanged != nil {
181+ user ["status_changed" ] = assignment .StatusChanged .Format (time .RFC3339 )
182+ }
183+
184+ // Handle profile data
185+ if assignment .Profile != nil {
186+ if profileMap , ok := assignment .Profile .(map [string ]interface {}); ok {
187+ // Convert profile values to strings for Terraform compatibility
188+ stringProfile := make (map [string ]string )
189+ for k , v := range profileMap {
190+ if v == nil {
191+ continue // Skip null values
192+ }
193+ if str , ok := v .(string ); ok {
194+ stringProfile [k ] = str
195+ } else {
196+ // Convert other types to string representation
197+ stringProfile [k ] = fmt .Sprintf ("%v" , v )
198+ }
199+ }
200+ if len (stringProfile ) > 0 {
201+ user ["profile" ] = stringProfile
202+ }
203+ }
204+ }
205+
206+ // Handle credentials
207+ if assignment .Credentials != nil {
208+ credentials := map [string ]interface {}{}
209+ if assignment .Credentials .UserName != "" {
210+ credentials ["user_name" ] = assignment .Credentials .UserName
211+ }
212+ if assignment .Credentials .Password != nil && assignment .Credentials .Password .Value != "" {
213+ credentials ["password" ] = assignment .Credentials .Password .Value
214+ }
215+ if len (credentials ) > 0 {
216+ user ["credentials" ] = []map [string ]interface {}{credentials }
217+ }
218+ }
219+
220+ return user
221+ }
0 commit comments