User may have more than one public key

Ayman Bagabas created

Change summary

internal/config/config.go   | 10 ++++++++--
internal/config/defaults.go | 12 ++++++------
internal/config/git.go      | 31 +++++++++++++++++--------------
3 files changed, 31 insertions(+), 22 deletions(-)

Detailed changes

internal/config/config.go 🔗

@@ -1,6 +1,8 @@
 package config
 
 import (
+	"strings"
+
 	"gopkg.in/yaml.v2"
 
 	"fmt"
@@ -28,7 +30,7 @@ type Config struct {
 type User struct {
 	Name        string   `yaml:"name"`
 	Admin       bool     `yaml:"admin"`
-	PublicKey   string   `yaml:"public-key"`
+	PublicKeys  []string `yaml:"public-keys"`
 	CollabRepos []string `yaml:"collab-repos"`
 }
 
@@ -64,7 +66,11 @@ func NewConfig(host string, port int, pk string, rs *git.RepoSource) (*Config, e
 	}
 	yamlConfig := fmt.Sprintf(defaultConfig, displayHost, port, anonAccess)
 	if pk != "" {
-		yamlUsers = fmt.Sprintf(hasKeyUserConfig, pk)
+		pks := ""
+		for _, key := range strings.Split(strings.TrimSpace(pk), "\n") {
+			pks += fmt.Sprintf("      - %s\n", key)
+		}
+		yamlUsers = fmt.Sprintf(hasKeyUserConfig, pks)
 	} else {
 		yamlUsers = defaultUserConfig
 	}

internal/config/defaults.go 🔗

@@ -25,19 +25,19 @@ const hasKeyUserConfig = `
 users:
   - name: admin
     admin: true
-    public-key:
-      %s`
+    public-keys:
+%s`
 
 const defaultUserConfig = `
 # users:
 #   - name: admin
 #     admin: true
-#     public-key:
-#       KEY TEXT`
+#     public-keys:
+#       - KEY TEXT`
 
 const exampleUserConfig = `
 #   - name: Example User
 #     collab-repos:
 #       - REPO
-#     public-key:
-#       KEY TEXT`
+#     public-keys:
+#       - KEY TEXT`

internal/config/git.go 🔗

@@ -2,6 +2,7 @@ package config
 
 import (
 	"log"
+	"strings"
 
 	gm "github.com/charmbracelet/wish/git"
 	"github.com/gliderlabs/ssh"
@@ -43,22 +44,24 @@ func (cfg *Config) accessForKey(repo string, pk ssh.PublicKey) gm.AccessLevel {
 		private = true
 	}
 	for _, u := range cfg.Users {
-		apk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(u.PublicKey))
-		if err != nil {
-			log.Printf("error: malformed authorized key: '%s'", u.PublicKey)
-			return gm.NoAccess
-		}
-		if ssh.KeysEqual(pk, apk) {
-			if u.Admin {
-				return gm.AdminAccess
+		for _, k := range u.PublicKeys {
+			apk, _, _, _, err := ssh.ParseAuthorizedKey([]byte(strings.TrimSpace(k)))
+			if err != nil {
+				log.Printf("error: malformed authorized key: '%s'", k)
+				return gm.NoAccess
 			}
-			for _, r := range u.CollabRepos {
-				if repo == r {
-					return gm.ReadWriteAccess
+			if ssh.KeysEqual(pk, apk) {
+				if u.Admin {
+					return gm.AdminAccess
+				}
+				for _, r := range u.CollabRepos {
+					if repo == r {
+						return gm.ReadWriteAccess
+					}
+				}
+				if !private {
+					return gm.ReadOnlyAccess
 				}
-			}
-			if !private {
-				return gm.ReadOnlyAccess
 			}
 		}
 	}