From cc09a066b66d6140c31255b9194bb3e11799e433 Mon Sep 17 00:00:00 2001
From: Timo Furrer <tuxtimo@gmail.com>
Date: Sun, 13 Mar 2022 14:54:51 +0100
Subject: [PATCH] Implement GET API for single Project and Group Deploy Token

I've recently implemented this API in GitLab and it landed in 14.9 and
already available on gitlab.com
---
 deploy_tokens.go      | 50 +++++++++++++++++++++++++
 deploy_tokens_test.go | 86 +++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 136 insertions(+)

diff --git a/deploy_tokens.go b/deploy_tokens.go
index 1b9943d56..f85102329 100644
--- a/deploy_tokens.go
+++ b/deploy_tokens.go
@@ -95,6 +95,31 @@ func (s *DeployTokensService) ListProjectDeployTokens(pid interface{}, opt *List
 	return ts, resp, err
 }
 
+// GetProjectDeployToken gets a single deploy token.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/deploy_tokens.html#get-a-project-deploy-token
+func (s *DeployTokensService) GetProjectDeployToken(pid interface{}, deployToken int, options ...RequestOptionFunc) (*DeployToken, *Response, error) {
+	project, err := parseID(pid)
+	if err != nil {
+		return nil, nil, err
+	}
+	u := fmt.Sprintf("projects/%s/deploy_tokens/%d", PathEscape(project), deployToken)
+
+	req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	t := new(DeployToken)
+	resp, err := s.client.Do(req, t)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return t, resp, err
+}
+
 // CreateProjectDeployTokenOptions represents the available CreateProjectDeployToken() options.
 //
 // GitLab API docs:
@@ -182,6 +207,31 @@ func (s *DeployTokensService) ListGroupDeployTokens(gid interface{}, opt *ListGr
 	return ts, resp, err
 }
 
+// GetGroupDeployToken gets a single deploy token.
+//
+// GitLab API docs:
+// https://docs.gitlab.com/ee/api/deploy_tokens.html#get-a-group-deploy-token
+func (s *DeployTokensService) GetGroupDeployToken(gid interface{}, deployToken int, options ...RequestOptionFunc) (*DeployToken, *Response, error) {
+	group, err := parseID(gid)
+	if err != nil {
+		return nil, nil, err
+	}
+	u := fmt.Sprintf("groups/%s/deploy_tokens/%d", PathEscape(group), deployToken)
+
+	req, err := s.client.NewRequest(http.MethodGet, u, nil, options)
+	if err != nil {
+		return nil, nil, err
+	}
+
+	t := new(DeployToken)
+	resp, err := s.client.Do(req, t)
+	if err != nil {
+		return nil, resp, err
+	}
+
+	return t, resp, err
+}
+
 // CreateGroupDeployTokenOptions represents the available CreateGroupDeployToken() options.
 //
 // GitLab API docs:
diff --git a/deploy_tokens_test.go b/deploy_tokens_test.go
index 500c475d8..480f6dccc 100644
--- a/deploy_tokens_test.go
+++ b/deploy_tokens_test.go
@@ -118,6 +118,49 @@ func TestListProjectDeployTokens(t *testing.T) {
 	}
 }
 
+func TestGetProjectDeployTokens(t *testing.T) {
+	mux, server, client := setup(t)
+	defer teardown(server)
+
+	mux.HandleFunc("/api/v4/projects/1/deploy_tokens/1", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, http.MethodGet)
+		fmt.Fprint(w, `
+{
+  "id": 1,
+  "name": "MyToken",
+  "username": "gitlab+deploy-token-1",
+  "expires_at": "2020-02-14T00:00:00.000Z",
+  "scopes": [
+    "read_repository",
+    "read_registry"
+  ]
+}
+`)
+	})
+
+	deployToken, _, err := client.DeployTokens.GetProjectDeployToken(1, 1)
+	if err != nil {
+		t.Errorf("DeployTokens.GetProjectDeployToken returned an error: %v", err)
+	}
+
+	wantExpiresAt := time.Date(2020, 02, 14, 0, 0, 0, 0, time.UTC)
+
+	want := &DeployToken{
+		ID:        1,
+		Name:      "MyToken",
+		Username:  "gitlab+deploy-token-1",
+		ExpiresAt: &wantExpiresAt,
+		Scopes: []string{
+			"read_repository",
+			"read_registry",
+		},
+	}
+
+	if !reflect.DeepEqual(want, deployToken) {
+		t.Errorf("DeployTokens.GetProjectDeployToken returned %+v, want %+v", deployToken, want)
+	}
+}
+
 func TestCreateProjectDeployToken(t *testing.T) {
 	mux, server, client := setup(t)
 	defer teardown(server)
@@ -237,6 +280,49 @@ func TestListGroupDeployTokens(t *testing.T) {
 	}
 }
 
+func TestGetGroupDeployTokens(t *testing.T) {
+	mux, server, client := setup(t)
+	defer teardown(server)
+
+	mux.HandleFunc("/api/v4/groups/1/deploy_tokens/1", func(w http.ResponseWriter, r *http.Request) {
+		testMethod(t, r, http.MethodGet)
+		fmt.Fprint(w, `
+{
+  "id": 1,
+  "name": "MyToken",
+  "username": "gitlab+deploy-token-1",
+  "expires_at": "2020-02-14T00:00:00.000Z",
+  "scopes": [
+    "read_repository",
+    "read_registry"
+  ]
+}
+`)
+	})
+
+	deployToken, _, err := client.DeployTokens.GetGroupDeployToken(1, 1)
+	if err != nil {
+		t.Errorf("DeployTokens.GetGroupDeployToken returned an error: %v", err)
+	}
+
+	wantExpiresAt := time.Date(2020, 02, 14, 0, 0, 0, 0, time.UTC)
+
+	want := &DeployToken{
+		ID:        1,
+		Name:      "MyToken",
+		Username:  "gitlab+deploy-token-1",
+		ExpiresAt: &wantExpiresAt,
+		Scopes: []string{
+			"read_repository",
+			"read_registry",
+		},
+	}
+
+	if !reflect.DeepEqual(want, deployToken) {
+		t.Errorf("DeployTokens.GetGroupDeployToken returned %+v, want %+v", deployToken, want)
+	}
+}
+
 func TestCreateGroupDeployToken(t *testing.T) {
 	mux, server, client := setup(t)
 	defer teardown(server)