File: http.go

package info (click to toggle)
gh 2.46.0-4
  • links: PTS, VCS
  • area: main
  • in suites: sid
  • size: 15,548 kB
  • sloc: sh: 227; makefile: 117
file content (127 lines) | stat: -rw-r--r-- 2,605 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
package add

import (
	"bytes"
	"encoding/json"
	"errors"
	"io"
	"net/http"
	"strings"

	"github.com/cli/cli/v2/api"
	"github.com/cli/cli/v2/internal/ghinstance"
	"github.com/cli/cli/v2/pkg/cmd/ssh-key/shared"
)

// Uploads the provided SSH key. Returns true if the key was uploaded, false if it was not.
func SSHKeyUpload(httpClient *http.Client, hostname string, keyFile io.Reader, title string) (bool, error) {
	url := ghinstance.RESTPrefix(hostname) + "user/keys"

	keyBytes, err := io.ReadAll(keyFile)
	if err != nil {
		return false, err
	}

	fullUserKey := string(keyBytes)
	splitKey := strings.Fields(fullUserKey)
	if len(splitKey) < 2 {
		return false, errors.New("provided key is not in a valid format")
	}

	keyToCompare := splitKey[0] + " " + splitKey[1]

	keys, err := shared.UserKeys(httpClient, hostname, "")
	if err != nil {
		return false, err
	}

	for _, k := range keys {
		if k.Key == keyToCompare {
			return false, nil
		}
	}

	payload := map[string]string{
		"title": title,
		"key":   fullUserKey,
	}

	err = keyUpload(httpClient, url, payload)

	if err != nil {
		return false, err
	}

	return true, nil
}

// Uploads the provided SSH Signing key. Returns true if the key was uploaded, false if it was not.
func SSHSigningKeyUpload(httpClient *http.Client, hostname string, keyFile io.Reader, title string) (bool, error) {
	url := ghinstance.RESTPrefix(hostname) + "user/ssh_signing_keys"

	keyBytes, err := io.ReadAll(keyFile)
	if err != nil {
		return false, err
	}

	fullUserKey := string(keyBytes)
	splitKey := strings.Fields(fullUserKey)
	if len(splitKey) < 2 {
		return false, errors.New("provided key is not in a valid format")
	}

	keyToCompare := splitKey[0] + " " + splitKey[1]

	keys, err := shared.UserSigningKeys(httpClient, hostname, "")
	if err != nil {
		return false, err
	}

	for _, k := range keys {
		if k.Key == keyToCompare {
			return false, nil
		}
	}

	payload := map[string]string{
		"title": title,
		"key":   fullUserKey,
	}

	err = keyUpload(httpClient, url, payload)

	if err != nil {
		return false, err
	}

	return true, nil
}

func keyUpload(httpClient *http.Client, url string, payload map[string]string) error {
	payloadBytes, err := json.Marshal(payload)
	if err != nil {
		return err
	}

	req, err := http.NewRequest("POST", url, bytes.NewBuffer(payloadBytes))
	if err != nil {
		return err
	}

	resp, err := httpClient.Do(req)
	if err != nil {
		return err
	}
	defer resp.Body.Close()

	if resp.StatusCode > 299 {
		return api.HandleHTTPError(resp)
	}

	_, err = io.Copy(io.Discard, resp.Body)
	if err != nil {
		return err
	}

	return nil
}