diff --git a/go.mod b/go.mod index a1745c60..c87a6979 100644 --- a/go.mod +++ b/go.mod @@ -71,3 +71,5 @@ require ( google.golang.org/genproto/googleapis/rpc v0.0.0-20240125205218-1f4bbc51befe // indirect gopkg.in/square/go-jose.v2 v2.6.0 // indirect ) + +replace github.com/zitadel/terraform-provider-zitadel => github.com/mojaloop/terraform-provider-zitadel v1.3.2 \ No newline at end of file diff --git a/zitadel/provider.go b/zitadel/provider.go index 95157e1b..39035332 100644 --- a/zitadel/provider.go +++ b/zitadel/provider.go @@ -248,6 +248,8 @@ func Provider() *schema.Provider { "zitadel_org_idp_saml": org_idp_saml.GetDatasource(), "zitadel_org_idp_oauth": org_idp_oauth.GetDatasource(), "zitadel_default_oidc_settings": default_oidc_settings.GetDatasource(), + "zitadel_user_grant": user_grant.GetDatasource(), + "zitadel_user_grants": user_grant.ListDatasources(), }, Schema: map[string]*schema.Schema{ helper.DomainVar: { diff --git a/zitadel/user_grant/const.go b/zitadel/user_grant/const.go index 53b377e1..1d78fc37 100644 --- a/zitadel/user_grant/const.go +++ b/zitadel/user_grant/const.go @@ -6,4 +6,12 @@ const ( projectGrantIDVar = "project_grant_id" UserIDVar = "user_id" RoleKeysVar = "role_keys" + OrgNameVar = "org_name" + userNameVar = "user_name" + roleStatusVar = "role_status" + projectNameVar = "project_name" + roleNamesVar = "role_names" + userGrantDataVar = "user_grant_data" + emailVar = "email" + nameVar = "name" ) diff --git a/zitadel/user_grant/datasource.go b/zitadel/user_grant/datasource.go new file mode 100644 index 00000000..be374fb6 --- /dev/null +++ b/zitadel/user_grant/datasource.go @@ -0,0 +1,129 @@ +package user_grant + +import ( + "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" +) + +func GetDatasource() *schema.Resource { + return &schema.Resource{ + Description: "represents role grants", + Schema: map[string]*schema.Schema{ + grantIDVar: { + Type: schema.TypeString, + Required: true, + Description: "ID of the usergrant", + }, + UserIDVar: { + Type: schema.TypeString, + Required: true, + Description: "ID of the user", + }, + RoleKeysVar: { + Type: schema.TypeList, + Computed: true, + Description: "A set of all roles for a user.", + Elem: &schema.Schema{Type: schema.TypeString}, + }, + projectNameVar: { + Type: schema.TypeString, + Optional: true, + Description: "Name of the project.", + Computed: true, + }, + roleStatusVar: { + Type: schema.TypeString, + Optional: true, + Description: "Status of role", + Computed: true, + }, + userNameVar: { + Type: schema.TypeString, + Optional: true, + Description: "username", + Computed: true, + }, + emailVar: { + Type: schema.TypeString, + Optional: true, + Description: "email of user", + Computed: true, + }, + nameVar: { + Type: schema.TypeString, + Optional: true, + Description: "display name of user", + Computed: true, + }, + }, + ReadContext: readDS, + } +} + +func ListDatasources() *schema.Resource { + return &schema.Resource{ + Description: "represents role grants", + Schema: map[string]*schema.Schema{ + projectNameVar: { + Type: schema.TypeString, + Required: true, + Description: "Name of the project.", + }, + userGrantDataVar: { + Type: schema.TypeList, + Computed: true, + Description: "A list of all usergrants.", + Elem: &schema.Resource{ + Schema: map[string]*schema.Schema{ + grantIDVar: { + Type: schema.TypeString, + Computed: true, + Description: "grantID", + }, + UserIDVar: { + Type: schema.TypeString, + Computed: true, + Description: "userid", + }, + RoleKeysVar: { + Type: schema.TypeList, + Computed: true, + Description: "A set of all roles for a user.", + Elem: &schema.Schema{Type: schema.TypeString}, + }, + projectNameVar: { + Type: schema.TypeString, + Optional: true, + Description: "Name of the project.", + Computed: true, + }, + roleStatusVar: { + Type: schema.TypeString, + Optional: true, + Description: "Status of role", + Computed: true, + }, + userNameVar: { + Type: schema.TypeString, + Optional: true, + Description: "username", + Computed: true, + }, + emailVar: { + Type: schema.TypeString, + Optional: true, + Description: "email of user", + Computed: true, + }, + nameVar: { + Type: schema.TypeString, + Optional: true, + Description: "display name of user", + Computed: true, + }, + }, + }, + }, + }, + ReadContext: list, + } +} diff --git a/zitadel/user_grant/funcs.go b/zitadel/user_grant/funcs.go index 50a9e8d7..ae2b49f9 100644 --- a/zitadel/user_grant/funcs.go +++ b/zitadel/user_grant/funcs.go @@ -6,9 +6,9 @@ import ( "github.com/hashicorp/terraform-plugin-log/tflog" "github.com/hashicorp/terraform-plugin-sdk/v2/diag" "github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema" - "github.com/zitadel/zitadel-go/v2/pkg/client/zitadel/management" - "github.com/zitadel/terraform-provider-zitadel/zitadel/helper" + "github.com/zitadel/zitadel-go/v2/pkg/client/zitadel/management" + "github.com/zitadel/zitadel-go/v2/pkg/client/zitadel/user" ) func delete(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { @@ -125,3 +125,95 @@ func read(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagn d.SetId(grant.GetId()) return nil } + +func readDS(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + tflog.Info(ctx, "started read") + clientinfo, ok := m.(*helper.ClientInfo) + if !ok { + return diag.Errorf("failed to get client") + } + client, err := helper.GetManagementClient(clientinfo) + if err != nil { + return diag.FromErr(err) + } + resp, err := client.GetUserGrantByID(helper.CtxWithOrgID(ctx, d), &management.GetUserGrantByIDRequest{ + GrantId: helper.GetID(d, grantIDVar), + UserId: d.Get(UserIDVar).(string), + }) + if err != nil && helper.IgnoreIfNotFoundError(err) == nil { + d.SetId("") + return nil + } + if err != nil { + return diag.Errorf("failed to get user grant") + } + grant := resp.GetUserGrant() + set := map[string]interface{}{ + UserIDVar: grant.GetUserId(), + RoleKeysVar: grant.GetRoleKeys(), + userNameVar: grant.GetUserName(), + roleStatusVar: grant.GetState().String(), + projectNameVar: grant.GetProjectName(), + emailVar: grant.Email, + nameVar: grant.DisplayName, + } + if grant.GetProjectId() != "" { + set[projectIDVar] = grant.GetProjectId() + } + if grant.GetProjectGrantId() != "" { + set[projectGrantIDVar] = grant.GetProjectGrantId() + } + for k, v := range set { + if err := d.Set(k, v); err != nil { + return diag.Errorf("failed to set %s of usergrant: %v", k, err) + } + } + d.SetId(grant.GetId()) + return nil +} + +func list(ctx context.Context, d *schema.ResourceData, m interface{}) diag.Diagnostics { + tflog.Info(ctx, "started list") + projectName := d.Get(projectNameVar).(string) + clientinfo, ok := m.(*helper.ClientInfo) + if !ok { + return diag.Errorf("failed to get client") + } + client, err := helper.GetManagementClient(clientinfo) + if err != nil { + return diag.FromErr(err) + } + req := &management.ListUserGrantRequest{} + + req.Queries = append(req.Queries, &user.UserGrantQuery{ + Query: &user.UserGrantQuery_ProjectNameQuery{ + ProjectNameQuery: &user.UserGrantProjectNameQuery{ + ProjectName: projectName, + Method: 3, + }, + }, + }) + + resp, err := client.ListUserGrants(ctx, req) + + if err != nil { + return diag.Errorf("error while getting roles by projName %s: %v", projectName, err) + } + results := []map[string]interface{}{} + for _, roleGrant := range resp.Result { + results = append(results, map[string]interface{}{ + UserIDVar: roleGrant.UserId, + grantIDVar: roleGrant.Id, + RoleKeysVar: roleGrant.GetRoleKeys(), + userNameVar: roleGrant.GetUserName(), + roleStatusVar: roleGrant.GetState().String(), + projectNameVar: roleGrant.GetProjectName(), + emailVar: roleGrant.Email, + nameVar: roleGrant.DisplayName, + }) + } + // If the ID is blank, the datasource is deleted and not usable. + d.SetId("-") + return diag.FromErr(d.Set(userGrantDataVar, results)) + +}