Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Add support for User SSH signing keys
- Loading branch information
1 parent
0c3cd12
commit 0dcd9f3
Showing
4 changed files
with
313 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,108 @@ | ||
// Copyright 2022 The go-github AUTHORS. All rights reserved. | ||
// | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package github | ||
|
||
import ( | ||
"context" | ||
"fmt" | ||
) | ||
|
||
// SSHSigningKey represents a public SSH key used to sign git commits. | ||
type SSHSigningKey struct { | ||
ID *int64 `json:"id,omitempty"` | ||
Key *string `json:"key,omitempty"` | ||
Title *string `json:"title,omitempty"` | ||
CreatedAt *Timestamp `json:"created_at,omitempty"` | ||
} | ||
|
||
func (k SSHSigningKey) String() string { | ||
return Stringify(k) | ||
} | ||
|
||
// ListSSHSigningKeys lists the SSH signing keys for a user. Passing an empty | ||
// username string will fetch SSH signing keys for the authenticated user. | ||
// | ||
// GitHub API docs: https://docs.github.com/en/rest/users/ssh-signing-keys#list-ssh-signing-keys-for-the-authenticated-user | ||
// GitHub API docs: https://docs.github.com/en/rest/users/ssh-signing-keys#list-ssh-signing-keys-for-a-user | ||
func (s *UsersService) ListSSHSigningKeys(ctx context.Context, user string, opts *ListOptions) ([]*SSHSigningKey, *Response, error) { | ||
var u string | ||
if user != "" { | ||
u = fmt.Sprintf("users/%v/ssh_signing_keys", user) | ||
} else { | ||
u = "user/ssh_signing_keys" | ||
} | ||
u, err := addOptions(u, opts) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
req, err := s.client.NewRequest("GET", u, nil) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
var keys []*SSHSigningKey | ||
resp, err := s.client.Do(ctx, req, &keys) | ||
if err != nil { | ||
return nil, resp, err | ||
} | ||
|
||
return keys, resp, nil | ||
} | ||
|
||
// GetSSHSigningKey fetches a single SSH signing key for the authenticated user. | ||
// | ||
// GitHub API docs: https://docs.github.com/en/rest/users/ssh-signing-keys#get-an-ssh-signing-key-for-the-authenticated-user | ||
func (s *UsersService) GetSSHSigningKey(ctx context.Context, id int64) (*SSHSigningKey, *Response, error) { | ||
u := fmt.Sprintf("user/ssh_signing_keys/%v", id) | ||
|
||
req, err := s.client.NewRequest("GET", u, nil) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
key := new(SSHSigningKey) | ||
resp, err := s.client.Do(ctx, req, key) | ||
if err != nil { | ||
return nil, resp, err | ||
} | ||
|
||
return key, resp, nil | ||
} | ||
|
||
// CreateSSHSigningKey adds a SSH signing key for the authenticated user. | ||
// | ||
// GitHub API docs: https://docs.github.com/en/rest/users/ssh-signing-keys#create-a-ssh-signing-key-for-the-authenticated-user | ||
func (s *UsersService) CreateSSHSigningKey(ctx context.Context, key *Key) (*SSHSigningKey, *Response, error) { | ||
u := "user/ssh_signing_keys" | ||
|
||
req, err := s.client.NewRequest("POST", u, key) | ||
if err != nil { | ||
return nil, nil, err | ||
} | ||
|
||
k := new(SSHSigningKey) | ||
resp, err := s.client.Do(ctx, req, k) | ||
if err != nil { | ||
return nil, resp, err | ||
} | ||
|
||
return k, resp, nil | ||
} | ||
|
||
// DeleteKey deletes a SSH signing key for the authenticated user. | ||
// | ||
// GitHub API docs: https://docs.github.com/en/rest/users/ssh-signing-keys#delete-an-ssh-signing-key-for-the-authenticated-user | ||
func (s *UsersService) DeleteSSHSigningKey(ctx context.Context, id int64) (*Response, error) { | ||
u := fmt.Sprintf("user/ssh_signing_keys/%v", id) | ||
|
||
req, err := s.client.NewRequest("DELETE", u, nil) | ||
if err != nil { | ||
return nil, err | ||
} | ||
|
||
return s.client.Do(ctx, req, nil) | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,202 @@ | ||
// Copyright 2022 The go-github AUTHORS. All rights reserved. | ||
// | ||
// Use of this source code is governed by a BSD-style | ||
// license that can be found in the LICENSE file. | ||
|
||
package github | ||
|
||
import ( | ||
"context" | ||
"encoding/json" | ||
"fmt" | ||
"net/http" | ||
"testing" | ||
|
||
"github.com/google/go-cmp/cmp" | ||
) | ||
|
||
func TestUsersService_ListSSHSigningKeys_authenticatedUser(t *testing.T) { | ||
client, mux, _, teardown := setup() | ||
defer teardown() | ||
|
||
mux.HandleFunc("/user/ssh_signing_keys", func(w http.ResponseWriter, r *http.Request) { | ||
testMethod(t, r, "GET") | ||
testFormValues(t, r, values{"page": "2"}) | ||
fmt.Fprint(w, `[{"id":1}]`) | ||
}) | ||
|
||
opt := &ListOptions{Page: 2} | ||
ctx := context.Background() | ||
keys, _, err := client.Users.ListSSHSigningKeys(ctx, "", opt) | ||
if err != nil { | ||
t.Errorf("Users.ListSSHSigningKeys returned error: %v", err) | ||
} | ||
|
||
want := []*SSHSigningKey{{ID: Int64(1)}} | ||
if !cmp.Equal(keys, want) { | ||
t.Errorf("Users.ListSSHSigningKeys returned %+v, want %+v", keys, want) | ||
} | ||
|
||
const methodName = "ListSSHSigningKeys" | ||
testBadOptions(t, methodName, func() (err error) { | ||
_, _, err = client.Users.ListSSHSigningKeys(ctx, "\n", opt) | ||
return err | ||
}) | ||
|
||
testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { | ||
got, resp, err := client.Users.ListSSHSigningKeys(ctx, "", opt) | ||
if got != nil { | ||
t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) | ||
} | ||
return resp, err | ||
}) | ||
} | ||
|
||
func TestUsersService_ListSSHSigningKeys_specifiedUser(t *testing.T) { | ||
client, mux, _, teardown := setup() | ||
defer teardown() | ||
|
||
mux.HandleFunc("/users/u/ssh_signing_keys", func(w http.ResponseWriter, r *http.Request) { | ||
testMethod(t, r, "GET") | ||
fmt.Fprint(w, `[{"id":1}]`) | ||
}) | ||
|
||
ctx := context.Background() | ||
keys, _, err := client.Users.ListSSHSigningKeys(ctx, "u", nil) | ||
if err != nil { | ||
t.Errorf("Users.ListSSHSigningKeys returned error: %v", err) | ||
} | ||
|
||
want := []*SSHSigningKey{{ID: Int64(1)}} | ||
if !cmp.Equal(keys, want) { | ||
t.Errorf("Users.ListSSHSigningKeys returned %+v, want %+v", keys, want) | ||
} | ||
} | ||
|
||
func TestUsersService_ListSSHSigningKeys_invalidUser(t *testing.T) { | ||
client, _, _, teardown := setup() | ||
defer teardown() | ||
|
||
ctx := context.Background() | ||
_, _, err := client.Users.ListSSHSigningKeys(ctx, "%", nil) | ||
testURLParseError(t, err) | ||
} | ||
|
||
func TestUsersService_GetSSHSigningKey(t *testing.T) { | ||
client, mux, _, teardown := setup() | ||
defer teardown() | ||
|
||
mux.HandleFunc("/user/ssh_signing_keys/1", func(w http.ResponseWriter, r *http.Request) { | ||
testMethod(t, r, "GET") | ||
fmt.Fprint(w, `{"id":1}`) | ||
}) | ||
|
||
ctx := context.Background() | ||
key, _, err := client.Users.GetSSHSigningKey(ctx, 1) | ||
if err != nil { | ||
t.Errorf("Users.GetSSHSigningKey returned error: %v", err) | ||
} | ||
|
||
want := &SSHSigningKey{ID: Int64(1)} | ||
if !cmp.Equal(key, want) { | ||
t.Errorf("Users.GetSSHSigningKey returned %+v, want %+v", key, want) | ||
} | ||
|
||
const methodName = "GetSSHSigningKey" | ||
testBadOptions(t, methodName, func() (err error) { | ||
_, _, err = client.Users.GetSSHSigningKey(ctx, -1) | ||
return err | ||
}) | ||
|
||
testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { | ||
got, resp, err := client.Users.GetSSHSigningKey(ctx, 1) | ||
if got != nil { | ||
t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) | ||
} | ||
return resp, err | ||
}) | ||
} | ||
|
||
func TestUsersService_CreateSSHSigningKey(t *testing.T) { | ||
client, mux, _, teardown := setup() | ||
defer teardown() | ||
|
||
input := &Key{Key: String("k"), Title: String("t")} | ||
|
||
mux.HandleFunc("/user/ssh_signing_keys", func(w http.ResponseWriter, r *http.Request) { | ||
v := new(Key) | ||
json.NewDecoder(r.Body).Decode(v) | ||
|
||
testMethod(t, r, "POST") | ||
if !cmp.Equal(v, input) { | ||
t.Errorf("Request body = %+v, want %+v", v, input) | ||
} | ||
|
||
fmt.Fprint(w, `{"id":1}`) | ||
}) | ||
|
||
ctx := context.Background() | ||
key, _, err := client.Users.CreateSSHSigningKey(ctx, input) | ||
if err != nil { | ||
t.Errorf("Users.CreateSSHSigningKey returned error: %v", err) | ||
} | ||
|
||
want := &SSHSigningKey{ID: Int64(1)} | ||
if !cmp.Equal(key, want) { | ||
t.Errorf("Users.CreateSSHSigningKey returned %+v, want %+v", key, want) | ||
} | ||
|
||
const methodName = "CreateKey" | ||
testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { | ||
got, resp, err := client.Users.CreateKey(ctx, input) | ||
if got != nil { | ||
t.Errorf("testNewRequestAndDoFailure %v = %#v, want nil", methodName, got) | ||
} | ||
return resp, err | ||
}) | ||
} | ||
|
||
func TestUsersService_DeleteSSHSigningKey(t *testing.T) { | ||
client, mux, _, teardown := setup() | ||
defer teardown() | ||
|
||
mux.HandleFunc("/user/ssh_signing_keys/1", func(w http.ResponseWriter, r *http.Request) { | ||
testMethod(t, r, "DELETE") | ||
}) | ||
|
||
ctx := context.Background() | ||
_, err := client.Users.DeleteSSHSigningKey(ctx, 1) | ||
if err != nil { | ||
t.Errorf("Users.DeleteSSHSigningKey returned error: %v", err) | ||
} | ||
|
||
const methodName = "DeleteSSHSigningKey" | ||
testBadOptions(t, methodName, func() (err error) { | ||
_, err = client.Users.DeleteSSHSigningKey(ctx, -1) | ||
return err | ||
}) | ||
|
||
testNewRequestAndDoFailure(t, methodName, client, func() (*Response, error) { | ||
return client.Users.DeleteSSHSigningKey(ctx, 1) | ||
}) | ||
} | ||
|
||
func TestSSHSigningKey_Marshal(t *testing.T) { | ||
testJSONMarshal(t, &SSHSigningKey{}, "{}") | ||
|
||
u := &Key{ | ||
ID: Int64(1), | ||
Key: String("abc"), | ||
Title: String("title"), | ||
CreatedAt: &Timestamp{referenceTime}, | ||
} | ||
|
||
want := `{ | ||
"id": 1, | ||
"key": "abc", | ||
"title": "title", | ||
"created_at": ` + referenceTimeStr + ` | ||
}` | ||
|
||
testJSONMarshal(t, u, want) | ||
} |