@@ -1,13 +1,14 @@
package config
import (
+ "log"
+
gm "github.com/charmbracelet/wish/git"
"github.com/gliderlabs/ssh"
)
func (cfg *Config) AuthRepo(repo string, pk ssh.PublicKey) gm.AccessLevel {
- // TODO: check yaml for access rules
- return gm.ReadWriteAccess
+ return cfg.accessForKey(repo, pk)
}
func (cfg *Config) PasswordHandler(ctx ssh.Context, password string) bool {
@@ -15,6 +16,39 @@ func (cfg *Config) PasswordHandler(ctx ssh.Context, password string) bool {
}
func (cfg *Config) PublicKeyHandler(ctx ssh.Context, pk ssh.PublicKey) bool {
- // TODO: check yaml for access rules
+ if cfg.accessForKey("", pk) == gm.NoAccess {
+ return false
+ }
return true
}
+
+func (cfg *Config) accessForKey(repo string, pk ssh.PublicKey) gm.AccessLevel {
+ 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 _, r := range u.CollabRepos {
+ if repo == r {
+ return gm.ReadWriteAccess
+ }
+ }
+ return gm.ReadOnlyAccess
+ }
+ }
+ switch cfg.AnonAccess {
+ case "no-access":
+ return gm.NoAccess
+ case "read-only":
+ return gm.ReadOnlyAccess
+ case "read-write":
+ return gm.ReadWriteAccess
+ default:
+ return gm.NoAccess
+ }
+}
@@ -29,7 +29,7 @@ type Config struct {
type User struct {
Name string `yaml:"name"`
Admin bool `yaml:"admin"`
- PublicKey string `yaml:"pk"`
+ PublicKey string `yaml:"public-key"`
CollabRepos []string `yaml:"collab_repos"`
}
@@ -72,13 +72,13 @@ func NewConfig(host string, port int, pk string, rs *git.RepoSource) (*Config, e
}
func (cfg *Config) Pushed(repo string, pk ssh.PublicKey) {
- err := cfg.Reload()
+ err := cfg.reload()
if err != nil {
log.Printf("error reloading after push: %s", err)
}
}
-func (cfg *Config) Reload() error {
+func (cfg *Config) reload() error {
err := cfg.Source.LoadRepos()
if err != nil {
return err
@@ -157,12 +157,11 @@ func (cfg *Config) createDefaultConfigRepo(yaml string) error {
if err != nil {
return err
}
- err = rs.LoadRepos()
if err != nil {
return err
}
} else if err != nil {
return err
}
- return nil
+ return cfg.reload()
}
@@ -2,8 +2,7 @@ package config
const defaultReadme = "# Soft Serve\n\n Welcome! You can configure your Soft Serve server by cloning this repo and pushing changes.\n\n## Repos\n\n{{ range .Repos }}* {{ .Name }}{{ if .Note }} - {{ .Note }} {{ end }}\n - `git clone ssh://{{$.Host}}:{{$.Port}}/{{.Repo}}`\n{{ end }}"
-const defaultConfig = `
-name: Soft Serve
+const defaultConfig = `name: Soft Serve
host: %s
port: %d
@@ -16,27 +15,27 @@ allow-no-keys: false
# Customize repo display in menu
repos:
- name: Home
- repo: config
- note: "Configuration and content repo for this server"`
+ repo: config
+ note: "Configuration and content repo for this server"`
const hasKeyUserConfig = `
# Users can read all repos, and push to collab-repos, admin can push to all repos
users:
- name: admin
- admin: true
- public-key: |
- %s`
+ admin: true
+ public-key:
+ %s`
const defaultUserConfig = `
# users:
# - name: admin
-# admin: true
-# public-key: |
-# KEY TEXT`
+# admin: true
+# public-key: |
+# KEY TEXT`
const exampleUserConfig = `
-# - name: little-buddy
-# collab-repos:
-# - soft-serve
-# public-key: |
-# KEY TEXT`
+# - name: little-buddy
+# collab-repos:
+# - soft-serve
+# public-key: |
+# KEY TEXT`