2148baee11f133a1e8f996584ece6cd0d547f37a

Author
Ayman Bagabas <ayman.bagabas@gmail.com>
Committer
Ayman Bagabas <ayman.bagabas@gmail.com>
Date

Message

User may have more than one public key

Diff

  1diff --git a/internal/config/config.go b/internal/config/config.go
  2index 430c1fba814c67780d11bb3a7d3c67633337f3c7..cd71ee9f35a6fb761655ebea18aea1eba1fd8fde 100644
  3--- a/internal/config/config.go
  4+++ b/internal/config/config.go
  5@@ -1,6 +1,8 @@
  6 package config
  7 
  8 import (
  9+	"strings"
 10+
 11 	"gopkg.in/yaml.v2"
 12 
 13 	"fmt"
 14@@ -28,7 +30,7 @@ type Config struct {
 15 type User struct {
 16 	Name        string   `yaml:"name"`
 17 	Admin       bool     `yaml:"admin"`
 18-	PublicKey   string   `yaml:"public-key"`
 19+	PublicKeys  []string `yaml:"public-keys"`
 20 	CollabRepos []string `yaml:"collab-repos"`
 21 }
 22 
 23@@ -64,7 +66,11 @@ func NewConfig(host string, port int, pk string, rs *git.RepoSource) (*Config, e
 24 	}
 25 	yamlConfig := fmt.Sprintf(defaultConfig, displayHost, port, anonAccess)
 26 	if pk != "" {
 27-		yamlUsers = fmt.Sprintf(hasKeyUserConfig, pk)
 28+		pks := ""
 29+		for _, key := range strings.Split(strings.TrimSpace(pk), "\n") {
 30+			pks += fmt.Sprintf("      - %s\n", key)
 31+		}
 32+		yamlUsers = fmt.Sprintf(hasKeyUserConfig, pks)
 33 	} else {
 34 		yamlUsers = defaultUserConfig
 35 	}
 36diff --git a/internal/config/defaults.go b/internal/config/defaults.go
 37index 9267293bed304b6c09d6db6d1b49e09c209d415b..70c28962234ae50e49aa219e2a882311264382e0 100644
 38--- a/internal/config/defaults.go
 39+++ b/internal/config/defaults.go
 40@@ -25,19 +25,19 @@ const hasKeyUserConfig = `
 41 users:
 42   - name: admin
 43     admin: true
 44-    public-key:
 45-      %s`
 46+    public-keys:
 47+%s`
 48 
 49 const defaultUserConfig = `
 50 # users:
 51 #   - name: admin
 52 #     admin: true
 53-#     public-key:
 54-#       KEY TEXT`
 55+#     public-keys:
 56+#       - KEY TEXT`
 57 
 58 const exampleUserConfig = `
 59 #   - name: Example User
 60 #     collab-repos:
 61 #       - REPO
 62-#     public-key:
 63-#       KEY TEXT`
 64+#     public-keys:
 65+#       - KEY TEXT`
 66diff --git a/internal/config/git.go b/internal/config/git.go
 67index 184dde11e1d84f0cf04dd5c3b462546c2195806d..35a9757da4c1f3ad3306f67070455d5dbd7a5ced 100644
 68--- a/internal/config/git.go
 69+++ b/internal/config/git.go
 70@@ -2,6 +2,7 @@ package config
 71 
 72 import (
 73 	"log"
 74+	"strings"
 75 
 76 	gm "github.com/charmbracelet/wish/git"
 77 	"github.com/gliderlabs/ssh"
 78@@ -43,22 +44,24 @@ func (cfg *Config) accessForKey(repo string, pk ssh.PublicKey) gm.AccessLevel {
 79 		private = true
 80 	}
 81 	for _, u := range cfg.Users {
 82-		apk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(u.PublicKey))
 83-		if err != nil {
 84-			log.Printf("error: malformed authorized key: '%s'", u.PublicKey)
 85-			return gm.NoAccess
 86-		}
 87-		if ssh.KeysEqual(pk, apk) {
 88-			if u.Admin {
 89-				return gm.AdminAccess
 90+		for _, k := range u.PublicKeys {
 91+			apk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(strings.TrimSpace(k)))
 92+			if err != nil {
 93+				log.Printf("error: malformed authorized key: '%s'", k)
 94+				return gm.NoAccess
 95 			}
 96-			for _, r := range u.CollabRepos {
 97-				if repo == r {
 98-					return gm.ReadWriteAccess
 99+			if ssh.KeysEqual(pk, apk) {
100+				if u.Admin {
101+					return gm.AdminAccess
102+				}
103+				for _, r := range u.CollabRepos {
104+					if repo == r {
105+						return gm.ReadWriteAccess
106+					}
107+				}
108+				if !private {
109+					return gm.ReadOnlyAccess
110 				}
111-			}
112-			if !private {
113-				return gm.ReadOnlyAccess
114 			}
115 		}
116 	}