aboutsummaryrefslogtreecommitdiff
path: root/main.go
diff options
context:
space:
mode:
authorBen Burwell <ben@benburwell.com>2018-11-28 00:08:03 -0500
committerBen Burwell <ben@benburwell.com>2018-11-28 00:08:03 -0500
commit7e62b1101116ed7695a3b5c925170b3a3a7d3ecb (patch)
treef76043bccb3e281c68b319fa6d3d3372a07ced54 /main.go
initial version
Diffstat (limited to 'main.go')
-rw-r--r--main.go93
1 files changed, 93 insertions, 0 deletions
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
+}