From 7e62b1101116ed7695a3b5c925170b3a3a7d3ecb Mon Sep 17 00:00:00 2001 From: Ben Burwell Date: Wed, 28 Nov 2018 00:08:03 -0500 Subject: initial version --- main.go | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 main.go (limited to 'main.go') diff --git a/main.go b/main.go new file mode 100644 index 0000000..69308b5 --- /dev/null +++ b/main.go @@ -0,0 +1,93 @@ +package main + +import ( + "encoding/json" + "fmt" + "io/ioutil" + "net/http" + "os" + "path" + "strings" + "time" +) + +func main() { + if len(os.Args) != 2 { + fmt.Fprintln(os.Stderr, "no home directory provided") + os.Exit(1) + } + homedir := os.Args[1] + users, err := getUsers(homedir) + if err != nil { + if os.IsNotExist(err) { + os.Exit(0) + } else { + fmt.Fprintf(os.Stderr, "could not read authorized_github_users: %v\n", err) + os.Exit(1) + } + } + keys, err := getUserKeys(users) + if err != nil { + fmt.Fprintf(os.Stderr, "could not get public keys: %v\n", err) + os.Exit(1) + } + for _, key := range keys { + fmt.Println(key) + } + os.Exit(0) +} + +func getUsers(homedir string) ([]string, error) { + filepath := path.Join(homedir, ".ssh", "authorized_github_users") + data, err := ioutil.ReadFile(filepath) + if err != nil { + return nil, err + } + lines := strings.Split(string(data), "\n") + users := map[string]struct{}{} + for _, line := range lines { + trimmed := strings.TrimSpace(line) + if len(trimmed) > 0 && !strings.HasPrefix(trimmed, "#") { + users[trimmed] = struct{}{} + } + } + uniqueUsers := []string{} + for user := range users { + uniqueUsers = append(uniqueUsers, user) + } + return uniqueUsers, nil +} + +// GHKey is a key structure from the GitHub REST API +type GHKey struct { + ID int `json:"id"` + Key string `json:"key"` +} + +func getUserKeys(users []string) ([]string, error) { + client := &http.Client{Timeout: 5 * time.Second} + keys := []string{} + for _, user := range users { + url := fmt.Sprintf("https://api.github.com/users/%s/keys", user) + res, err := client.Get(url) + if err != nil { + return nil, err + } + if res.StatusCode != http.StatusOK { + return nil, fmt.Errorf("error fetching keys: got http %d %s", res.StatusCode, res.Status) + } + data, err := ioutil.ReadAll(res.Body) + defer res.Body.Close() + if err != nil { + return nil, err + } + userKeys := []GHKey{} + if err := json.Unmarshal(data, &userKeys); err != nil { + return nil, err + } + for _, userKey := range userKeys { + keys = append(keys, userKey.Key) + } + } + return keys, nil +} -- cgit v1.2.3