Skip to content

Commit c544684

Browse files
user_data_source: implemented
1 parent fe687a3 commit c544684

File tree

4 files changed

+250
-0
lines changed

4 files changed

+250
-0
lines changed

docs/data-sources/user.md

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "passbolt_user Data Source - passbolt"
4+
subcategory: ""
5+
description: |-
6+
A Passbolt User DataSource.
7+
---
8+
9+
# passbolt_user (Data Source)
10+
11+
A Passbolt User DataSource.
12+
13+
## Example Usage
14+
15+
```terraform
16+
data "passbolt_user" "example" {
17+
username = "dummy@exmpl.com"
18+
}
19+
20+
output "user_out" {
21+
value = data.passbolt_user.example
22+
}
23+
```
24+
25+
<!-- schema generated by tfplugindocs -->
26+
## Schema
27+
28+
### Optional
29+
30+
- `username` (String) The user name. This needs to be a valid email. User will be replaced upon username change.
31+
32+
### Read-Only
33+
34+
- `users` (Attributes List) (see [below for nested schema](#nestedatt--users))
35+
36+
<a id="nestedatt--users"></a>
37+
### Nested Schema for `users`
38+
39+
Required:
40+
41+
- `active` (Boolean)
42+
- `created` (String)
43+
- `deleted` (Boolean)
44+
- `description` (String)
45+
- `id` (String)
46+
- `last_logged_in` (String)
47+
- `modified` (String)
48+
- `role_id` (String)
49+
- `username` (String)
50+
51+
Read-Only:
52+
53+
- `profile` (Attributes) (see [below for nested schema](#nestedatt--users--profile))
54+
55+
<a id="nestedatt--users--profile"></a>
56+
### Nested Schema for `users.profile`
57+
58+
Required:
59+
60+
- `first_name` (String)
61+
- `last_name` (String)
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
data "passbolt_user" "example" {
2+
username = "dummy@exmpl.com"
3+
}
4+
5+
output "user_out" {
6+
value = data.passbolt_user.example
7+
}

internal/provider/provider.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -176,6 +176,7 @@ func (p *passboltProvider) DataSources(_ context.Context) []func() datasource.Da
176176
NewPasswordDataSource,
177177
NewShareDataSource,
178178
NewRolesDataSource,
179+
NewUserDataSource,
179180
}
180181
}
181182

Lines changed: 181 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,181 @@
1+
package provider
2+
3+
import (
4+
"context"
5+
"fmt"
6+
7+
"github.com/hashicorp/terraform-plugin-framework/datasource"
8+
"github.com/hashicorp/terraform-plugin-framework/datasource/schema"
9+
"github.com/hashicorp/terraform-plugin-framework/types"
10+
"github.com/passbolt/go-passbolt/api"
11+
)
12+
13+
// Ensure the implementation satisfies the expected interfaces.
14+
var (
15+
_ datasource.DataSource = &userDataSource{}
16+
_ datasource.DataSourceWithConfigure = &userDataSource{}
17+
)
18+
19+
// NewUserDataSource is a helper function to simplify the provider implementation.
20+
func NewUserDataSource() datasource.DataSource {
21+
return &userDataSource{}
22+
}
23+
24+
// userDataSource is the datasource implementation.
25+
type userDataSource struct {
26+
client *PassboltClient
27+
}
28+
29+
type usersDataSourceModel struct {
30+
UserName types.String `tfsdk:"username"`
31+
Users []usersReadModel `tfsdk:"users"`
32+
}
33+
34+
// created, modified
35+
type usersReadModel struct {
36+
ID types.String `tfsdk:"id"`
37+
UserName types.String `tfsdk:"username"`
38+
Profile profileModel `tfsdk:"profile"`
39+
Created types.String `tfsdk:"created"`
40+
Modified types.String `tfsdk:"modified"`
41+
Active types.Bool `tfsdk:"active"`
42+
Deleted types.Bool `tfsdk:"deleted"`
43+
RoleID types.String `tfsdk:"role_id"`
44+
Description types.String `tfsdk:"description"`
45+
LastLoggedIn types.String `tfsdk:"last_logged_in"`
46+
}
47+
48+
type profileModel struct {
49+
FirstName types.String `tfsdk:"first_name"`
50+
LastName types.String `tfsdk:"last_name"`
51+
}
52+
53+
// Configure adds the provider configured client to the datasource.
54+
func (r *userDataSource) Configure(_ context.Context, req datasource.ConfigureRequest, resp *datasource.ConfigureResponse) {
55+
if req.ProviderData == nil {
56+
return
57+
}
58+
59+
client, ok := req.ProviderData.(*PassboltClient)
60+
if !ok {
61+
resp.Diagnostics.AddError(
62+
"Unexpected Data Source Configure Type",
63+
fmt.Sprintf("Expected *passboltClient, got: %T. Please report this issue to the provider developers.", req.ProviderData),
64+
)
65+
66+
return
67+
}
68+
69+
r.client = client
70+
}
71+
72+
// Metadata returns the datasource type name.
73+
func (r *userDataSource) Metadata(_ context.Context, req datasource.MetadataRequest, resp *datasource.MetadataResponse) {
74+
resp.TypeName = req.ProviderTypeName + "_user"
75+
}
76+
77+
// Schema defines the schema for the datasource.
78+
func (r *userDataSource) Schema(_ context.Context, _ datasource.SchemaRequest, resp *datasource.SchemaResponse) {
79+
resp.Schema = schema.Schema{
80+
Description: "A Passbolt User DataSource.",
81+
Attributes: map[string]schema.Attribute{
82+
"username": schema.StringAttribute{
83+
Description: "The user name. This needs to be a valid email. User will be replaced upon username change.",
84+
Optional: true,
85+
},
86+
"users": schema.ListNestedAttribute{
87+
Computed: true,
88+
NestedObject: schema.NestedAttributeObject{
89+
Attributes: map[string]schema.Attribute{
90+
"id": schema.StringAttribute{
91+
Required: true,
92+
},
93+
"username": schema.StringAttribute{
94+
Required: true,
95+
},
96+
"created": schema.StringAttribute{
97+
Required: true,
98+
},
99+
"modified": schema.StringAttribute{
100+
Required: true,
101+
},
102+
"active": schema.BoolAttribute{
103+
Required: true,
104+
},
105+
"deleted": schema.BoolAttribute{
106+
Required: true,
107+
},
108+
"role_id": schema.StringAttribute{
109+
Required: true,
110+
},
111+
"description": schema.StringAttribute{
112+
Required: true,
113+
},
114+
"last_logged_in": schema.StringAttribute{
115+
Required: true,
116+
},
117+
"profile": schema.SingleNestedAttribute{
118+
Computed: true,
119+
Attributes: map[string]schema.Attribute{
120+
"first_name": schema.StringAttribute{
121+
Required: true,
122+
},
123+
"last_name": schema.StringAttribute{
124+
Required: true,
125+
},
126+
},
127+
},
128+
},
129+
},
130+
},
131+
},
132+
}
133+
}
134+
135+
// Read refreshes the Terraform state with the latest data.
136+
func (r *userDataSource) Read(ctx context.Context, req datasource.ReadRequest, resp *datasource.ReadResponse) {
137+
// Retrieve values from state
138+
var reqModel, state usersDataSourceModel
139+
diags := req.Config.Get(ctx, &reqModel)
140+
resp.Diagnostics.Append(diags...)
141+
if resp.Diagnostics.HasError() {
142+
return
143+
}
144+
145+
users, err := r.client.Client.GetUsers(r.client.Context, &api.GetUsersOptions{
146+
FilterSearch: reqModel.UserName.ValueString(),
147+
})
148+
if err != nil {
149+
resp.Diagnostics.AddError(
150+
fmt.Sprintf("Cannot get user: %s", reqModel.UserName.ValueString()),
151+
err.Error(),
152+
)
153+
return
154+
}
155+
156+
for _, user := range users {
157+
userState := usersReadModel{
158+
ID: types.StringValue(user.ID),
159+
UserName: types.StringValue(user.Username),
160+
Profile: profileModel{
161+
FirstName: types.StringValue(user.Profile.FirstName),
162+
LastName: types.StringValue(user.Profile.LastName),
163+
},
164+
Created: types.StringValue(user.Created.String()),
165+
Modified: types.StringValue(user.Modified.String()),
166+
Active: types.BoolValue(user.Active),
167+
Deleted: types.BoolValue(user.Deleted),
168+
RoleID: types.StringValue(user.RoleID),
169+
Description: types.StringValue(user.Description),
170+
LastLoggedIn: types.StringValue(user.LastLoggedIn),
171+
}
172+
state.Users = append(state.Users, userState)
173+
}
174+
175+
// Set state to fully populated data
176+
diags = resp.State.Set(ctx, &state)
177+
resp.Diagnostics.Append(diags...)
178+
if resp.Diagnostics.HasError() {
179+
return
180+
}
181+
}

0 commit comments

Comments
 (0)