Skip to content

Commit 045802f

Browse files
committed
Add current_user data source
1 parent 0cfe85d commit 045802f

File tree

6 files changed

+233
-0
lines changed

6 files changed

+233
-0
lines changed

docs/data-sources/current_user.md

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
---
2+
# generated by https://github.com/hashicorp/terraform-plugin-docs
3+
page_title: "gitlab_current_user Data Source - terraform-provider-gitlab"
4+
subcategory: ""
5+
description: |-
6+
The gitlab_current_user data source allows details of the current user (determined by the input provider token) to be retrieved.
7+
Upstream API: GitLab REST API docs https://docs.gitlab.com/ee/api/graphql/reference/index.html#querycurrentuser
8+
---
9+
10+
# gitlab_current_user (Data Source)
11+
12+
The `gitlab_current_user` data source allows details of the current user (determined by the input provider token) to be retrieved.
13+
14+
**Upstream API**: [GitLab REST API docs](https://docs.gitlab.com/ee/api/graphql/reference/index.html#querycurrentuser)
15+
16+
## Example Usage
17+
18+
```terraform
19+
data "gitlab_current_user" "example" {}
20+
```
21+
22+
<!-- schema generated by tfplugindocs -->
23+
## Schema
24+
25+
### Read-Only
26+
27+
- `bot` (Boolean) Indicates if the user is a bot.
28+
- `group_count` (Number) Group count for the user.
29+
- `id` (String) ID of the user. This is in the form of a GraphQL globally unique ID.
30+
- `name` (String) Human-readable name of the user. Returns **** if the user is a project bot and the requester does not have permission to view the project.
31+
- `namespace_id` (String) Personal namespace of the user. This is in the form of a GraphQL globally unique ID.
32+
- `public_email` (String) User’s public email.
33+
- `username` (String) Username of the user. Unique within this instance of GitLab.
34+
35+
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
data "gitlab_current_user" "example" {}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package provider
2+
3+
import (
4+
"context"
5+
"log"
6+
7+
"github.com/hashicorp/terraform-plugin-sdk/v2/diag"
8+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/schema"
9+
"github.com/xanzy/go-gitlab"
10+
)
11+
12+
var _ = registerDataSource("gitlab_current_user", func() *schema.Resource {
13+
return &schema.Resource{
14+
Description: `The ` + "`gitlab_current_user`" + ` data source allows details of the current user (determined by the input provider token) to be retrieved.
15+
16+
**Upstream API**: [GitLab REST API docs](https://docs.gitlab.com/ee/api/graphql/reference/index.html#querycurrentuser)`,
17+
18+
ReadContext: dataSourceGitlabCurrentUserRead,
19+
Schema: map[string]*schema.Schema{
20+
"id": {
21+
Description: "ID of the user. This is in the form of a GraphQL globally unique ID.",
22+
Type: schema.TypeString,
23+
Computed: true,
24+
},
25+
"username": {
26+
Description: "Username of the user. Unique within this instance of GitLab.",
27+
Type: schema.TypeString,
28+
Computed: true,
29+
},
30+
"name": {
31+
Description: "Human-readable name of the user. Returns **** if the user is a project bot and the requester does not have permission to view the project. ",
32+
Type: schema.TypeString,
33+
Computed: true,
34+
},
35+
"bot": {
36+
Description: "Indicates if the user is a bot.",
37+
Type: schema.TypeBool,
38+
Computed: true,
39+
},
40+
"group_count": {
41+
Description: "Group count for the user.",
42+
Type: schema.TypeInt,
43+
Computed: true,
44+
},
45+
"namespace_id": {
46+
Description: "Personal namespace of the user. This is in the form of a GraphQL globally unique ID.",
47+
Type: schema.TypeString,
48+
Computed: true,
49+
},
50+
"public_email": {
51+
Description: "User’s public email.",
52+
Type: schema.TypeString,
53+
Computed: true,
54+
},
55+
},
56+
}
57+
})
58+
59+
func dataSourceGitlabCurrentUserRead(ctx context.Context, d *schema.ResourceData, meta interface{}) diag.Diagnostics {
60+
client := meta.(*gitlab.Client)
61+
62+
query := GraphQLQuery{
63+
`query {currentUser {name, bot, groupCount, id, namespace{id} publicEmail, username}}`,
64+
}
65+
log.Printf("[DEBUG] executing GraphQL Query %s to retrieve current user", query.Query)
66+
67+
var response CurrentUserResponse
68+
_, err := SendGraphQLRequest(context.Background(), client, query, &response)
69+
if err != nil {
70+
return diag.FromErr(err)
71+
}
72+
73+
d.SetId(response.Data.CurrentUser.ID)
74+
d.Set("username", response.Data.CurrentUser.Username)
75+
d.Set("name", response.Data.CurrentUser.Name)
76+
d.Set("bot", response.Data.CurrentUser.Bot)
77+
d.Set("group_count", response.Data.CurrentUser.GroupCount)
78+
d.Set("namespace_id", response.Data.CurrentUser.Namespace.ID)
79+
d.Set("public_email", response.Data.CurrentUser.PublicEmail)
80+
81+
return nil
82+
}
83+
84+
// Struct representing current user based on the input API token
85+
type CurrentUserResponse struct {
86+
Data struct {
87+
CurrentUser GraphQLUser `json:"currentUser"`
88+
} `json:"data"`
89+
}
90+
91+
type GraphQLUser struct {
92+
Name string `json:"name"`
93+
Bot bool `json:"bot"`
94+
GroupCount int `json:"groupCount"`
95+
ID string `json:"id"` // This is purposefully a string, as in some APIs it comes back as a globally unique ID
96+
Namespace struct {
97+
ID string `json:"id"`
98+
} `json:"namespace"`
99+
PublicEmail string `json:"publicEmail"`
100+
Username string `json:"username"`
101+
}
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
//go:build acceptance
2+
// +build acceptance
3+
4+
package provider
5+
6+
import (
7+
"testing"
8+
9+
"github.com/hashicorp/terraform-plugin-sdk/v2/helper/resource"
10+
"github.com/xanzy/go-gitlab"
11+
)
12+
13+
func TestAccDataSourceGitlabCurrentUser_basic(t *testing.T) {
14+
//The root user has no public email by default, set the public email so it shows up properly.
15+
_, _, _ = testGitlabClient.Users.ModifyUser(1, &gitlab.ModifyUserOptions{
16+
Email: gitlab.String("[email protected]"),
17+
// The public email MUST match an email on record for the user, or it gets a bad request.
18+
PublicEmail: gitlab.String("[email protected]"),
19+
})
20+
21+
resource.Test(t, resource.TestCase{
22+
ProviderFactories: providerFactories,
23+
Steps: []resource.TestStep{
24+
{
25+
Config: `data "gitlab_current_user" "this" {}`,
26+
Check: resource.ComposeTestCheckFunc(
27+
resource.TestCheckResourceAttrSet("data.gitlab_current_user.this", "id"),
28+
resource.TestCheckResourceAttrSet("data.gitlab_current_user.this", "name"),
29+
resource.TestCheckResourceAttrSet("data.gitlab_current_user.this", "username"),
30+
resource.TestCheckResourceAttrSet("data.gitlab_current_user.this", "bot"),
31+
resource.TestCheckResourceAttrSet("data.gitlab_current_user.this", "group_count"),
32+
resource.TestCheckResourceAttrSet("data.gitlab_current_user.this", "namespace_id"),
33+
resource.TestCheckResourceAttrSet("data.gitlab_current_user.this", "public_email"),
34+
),
35+
},
36+
},
37+
})
38+
}

internal/provider/graphql_helper.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package provider
2+
3+
import (
4+
"context"
5+
6+
"github.com/xanzy/go-gitlab"
7+
)
8+
9+
// Helper method for modifying client requests appropriately for sending a GraphQL call instead of a REST call.
10+
func SendGraphQLRequest(ctx context.Context, client *gitlab.Client, graphQLCall GraphQLQuery, objectToParseForResponse interface{}) (interface{}, error) {
11+
12+
request, err := client.NewRequest("POST", "", graphQLCall, nil)
13+
//Overwrite the path of the existing request, as otherwise the client appends /api/v4 instead.
14+
request.URL.Path = "/api/graphql"
15+
if err != nil {
16+
return nil, err
17+
}
18+
19+
_, err = client.Do(request, objectToParseForResponse)
20+
if err != nil {
21+
return nil, err
22+
}
23+
24+
return objectToParseForResponse, nil
25+
}
26+
27+
// Represents a GraphQL call to the API. All graphQL calls are a string passed to the "query" parameter, so they should be included here.
28+
type GraphQLQuery struct {
29+
Query string `json:"query"`
30+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
//go:build acceptance
2+
// +build acceptance
3+
4+
package provider
5+
6+
import (
7+
"context"
8+
"log"
9+
"testing"
10+
)
11+
12+
func TestAcc_GraphQL_basic(t *testing.T) {
13+
14+
query := GraphQLQuery{
15+
`query {currentUser {name, bot, gitpodEnabled, groupCount, id, namespace{id} publicEmail, username}}`,
16+
}
17+
18+
var response CurrentUserResponse
19+
_, err := SendGraphQLRequest(context.Background(), testGitlabClient, query, &response)
20+
if err != nil {
21+
log.Println(err)
22+
t.Fail()
23+
}
24+
25+
if response.Data.CurrentUser.Name != "Administrator" {
26+
t.Fail()
27+
}
28+
}

0 commit comments

Comments
 (0)