aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMax Resnick <max@ofmax.li>2024-02-12 21:16:48 -0800
committerMax Resnick <max@ofmax.li>2024-02-17 22:28:39 -0800
commit3db63367ef110e7f4a245cde61471e232e86339c (patch)
tree7be4be99ab5953f8d7beb1c613b0d0bc64db6c65
parent45a9f3814c14b41b93e47ae4cbc3f50c34d94991 (diff)
downloadgo-git-server-3db63367ef110e7f4a245cde61471e232e86339c.tar.gz
fix: fix up tests and linting
Diffstat (limited to '')
-rw-r--r--README.md11
-rw-r--r--cmd/main.go35
-rw-r--r--go.mod3
-rw-r--r--go.sum6
-rw-r--r--internal/admin/middleware.go4
-rw-r--r--internal/admin/model.go34
-rw-r--r--internal/admin/model_test.go38
-rw-r--r--internal/admin/service.go2
-rw-r--r--internal/admin/service_test.go16
-rw-r--r--internal/authz/middleware.go15
-rw-r--r--internal/authz/middleware_test.go13
-rw-r--r--internal/authz/model.go6
-rw-r--r--internal/git/handler.go2
13 files changed, 103 insertions, 82 deletions
diff --git a/README.md b/README.md
index 75e2f0c..d69dca3 100644
--- a/README.md
+++ b/README.md
@@ -19,17 +19,6 @@ The current focus is for a single user and CI user(s) and intends to become self
Tools like gitea are great, but they require things like a DBMS. This increases hosting comlexity and maintenance especially for small teams or single user bases.
-# TODO
-
-* Admin repo
-* read ini file
-* create repo
-* update gitweb config per repo
-* migration from gitolite
-
-## Admin
-
-
### Admin events
triggered by handler?
diff --git a/cmd/main.go b/cmd/main.go
index bf3697d..a0f007b 100644
--- a/cmd/main.go
+++ b/cmd/main.go
@@ -5,6 +5,7 @@ import (
"fmt"
"log"
"net/http"
+ "time"
"git.ofmax.li/go-git-server/internal/admin"
"git.ofmax.li/go-git-server/internal/authz"
@@ -12,20 +13,21 @@ import (
)
var (
- reposDir = flag.String("r", "./repos", "Directory containing git repositories")
- mgmtRepo = flag.Bool("a", true, "mgmt repo used for configuration")
- backendCommand = flag.String("c", "git http-backend", "CGI binary to execute")
- addr = flag.String("l", ":8080", "Address/port to listen on")
- modelPath = flag.String("m", "./auth_model.ini", "Authentication model")
- policyPath = flag.String("p", "./policy.csv", "auth policy")
- serverConfigPath = flag.String("s", "/gitserver.yaml", "serverconfig path")
- newToken = flag.Bool("t", false, "make a new token")
- updatePolicies = flag.Bool("u", false, "update policies")
+ reposDir = *flag.String("r", "./repos", "Directory containing git repositories")
+ mgmtRepo = *flag.Bool("a", true, "mgmt repo used for configuration")
+ backendCommand = *flag.String("c", "git http-backend", "CGI binary to execute")
+ addr = *flag.String("l", ":8080", "Address/port to listen on")
+ modelPath = *flag.String("m", "./auth_model.ini", "Authentication model")
+ policyPath = *flag.String("p", "./policy.csv", "auth policy")
+ serverConfigPath = *flag.String("s", "/gitserver.yaml", "serverconfig path")
+ newToken = *flag.Bool("t", false, "make a new token")
+ // TODO what was my intent here?
+ // updatePolicies = flag.Bool("u", false, "update policies")
)
func main() {
flag.Parse()
- if *newToken {
+ if newToken {
token, hash, err := authz.GenerateNewToken()
if err != nil {
log.Fatal(err)
@@ -33,7 +35,7 @@ func main() {
fmt.Printf("token: %s\nhash: %s\n", token, hash)
return
}
- adminSvc := admin.NewService(*modelPath, *policyPath, *serverConfigPath, *reposDir, *mgmtRepo)
+ adminSvc := admin.NewService(modelPath, policyPath, serverConfigPath, reposDir, mgmtRepo)
adminSvc.InitServer()
tokens := authz.NewTokenMap()
err := tokens.LoadTokensFromFile("./tokens.csv")
@@ -43,8 +45,13 @@ func main() {
router := http.NewServeMux()
// TODO we don't want to use a global
// de-reference args
- router.Handle("/mgmt/", admin.AdminHooks(adminSvc, git.GitHttpBackendHandler(*reposDir, *backendCommand)))
- router.Handle("/", git.GitHttpBackendHandler(*reposDir, *backendCommand))
+ router.Handle("/mgmt/", admin.Hooks(adminSvc, git.GitHttpBackendHandler(reposDir, backendCommand)))
+ router.Handle("/", git.GitHttpBackendHandler(reposDir, backendCommand))
mux := authz.Authentication(tokens, authz.Authorization(adminSvc, router))
- log.Fatal(http.ListenAndServe(":8080", mux))
+ server := &http.Server{
+ Addr: addr,
+ ReadHeaderTimeout: 5 * time.Second,
+ Handler: mux,
+ }
+ log.Fatal(server.ListenAndServe())
}
diff --git a/go.mod b/go.mod
index 550cf94..e5a0748 100644
--- a/go.mod
+++ b/go.mod
@@ -4,12 +4,10 @@ go 1.19
require (
github.com/casbin/casbin/v2 v2.56.0
- github.com/go-git/go-billy v4.2.0+incompatible
github.com/go-git/go-billy/v5 v5.4.1
github.com/go-git/go-git/v5 v5.6.1
golang.org/x/crypto v0.6.0
gopkg.in/ini.v1 v1.67.0
- gopkg.in/yaml.v2 v2.4.0
sigs.k8s.io/yaml v1.3.0
)
@@ -31,4 +29,5 @@ require (
golang.org/x/net v0.7.0 // indirect
golang.org/x/sys v0.5.0 // indirect
gopkg.in/warnings.v0 v0.1.2 // indirect
+ gopkg.in/yaml.v2 v2.4.0 // indirect
)
diff --git a/go.sum b/go.sum
index 63a5c10..3350ec9 100644
--- a/go.sum
+++ b/go.sum
@@ -15,7 +15,6 @@ github.com/casbin/casbin/v2 v2.56.0 h1:4qM+hDfj+i9M6lBbguafWKE/8tJA+9vRY5+l0ZB5W
github.com/casbin/casbin/v2 v2.56.0/go.mod h1:vByNa/Fchek0KZUgG5wEsl7iFsiviAYKRtgrQfcJqHg=
github.com/cloudflare/circl v1.1.0 h1:bZgT/A+cikZnKIwn7xL2OBj012Bmvho/o6RpRvv3GKY=
github.com/cloudflare/circl v1.1.0/go.mod h1:prBCrKB9DV4poKZY1l9zBXg2QJY7mvgRvtMxxK7fi4I=
-github.com/creack/pty v1.1.7/go.mod h1:lj5s0c3V2DBrqTV7llrYr5NG6My20zk30Fl46Y7DoTY=
github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E=
github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
@@ -26,8 +25,6 @@ github.com/gliderlabs/ssh v0.3.5 h1:OcaySEmAQJgyYcArR+gGGTHCyE7nvhEMTlYY+Dp8CpY=
github.com/gliderlabs/ssh v0.3.5/go.mod h1:8XB4KraRrX39qHhT6yxPsHedjA08I/uBVwj4xC+/+z4=
github.com/go-git/gcfg v1.5.0 h1:Q5ViNfGF8zFgyJWPqYwA7qGFoMTEiBmdlkcfRmpIMa4=
github.com/go-git/gcfg v1.5.0/go.mod h1:5m20vg6GwYabIxaOonVkTdrILxQMpEShl1xiMF4ua+E=
-github.com/go-git/go-billy v4.2.0+incompatible h1:Z6QtVXd5tjxUtcODLugkJg4WaZnGg13CD8qB9pr+7q0=
-github.com/go-git/go-billy v4.2.0+incompatible/go.mod h1:hedUGslB3n31bx5SW9KMjV/t0CUKnrapjVG9fT7xKX4=
github.com/go-git/go-billy/v5 v5.3.1/go.mod h1:pmpqyWchKfYfrkb/UVH4otLvyi/5gJlGI4Hb3ZqZ3W0=
github.com/go-git/go-billy/v5 v5.4.1 h1:Uwp5tDRkPr+l/TnbHOQzp+tmJfLceOlbVucgpTz8ix4=
github.com/go-git/go-billy/v5 v5.4.1/go.mod h1:vjbugF6Fz7JIflbVpl1hJsGjSHNltrSw45YK/ukIvQg=
@@ -50,7 +47,6 @@ github.com/kr/pretty v0.1.0/go.mod h1:dAy3ld7l9f0ibDNOQOHHMYYIIbhfbHSm3C4ZsoJORN
github.com/kr/pretty v0.2.1 h1:Fmg33tUaq4/8ym9TJN1x7sLJnHVwhP33CNkpYV/7rwI=
github.com/kr/pretty v0.2.1/go.mod h1:ipq/a2n7PKx3OHsz4KJII5eveXtPO4qwEXGdVfWzfnI=
github.com/kr/pty v1.1.1/go.mod h1:pFQYn66WHrOpPYNljwOMqo10TkYh1fy3cYio2l3bCsQ=
-github.com/kr/pty v1.1.8/go.mod h1:O1sed60cT9XZ5uDucP5qwvh+TE3NnUj51EiZO/lmSfw=
github.com/kr/text v0.1.0/go.mod h1:4Jbv+DJW3UT/LiOwJeYQe1efqtUx/iVham/4vfdArNI=
github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY=
github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE=
@@ -101,7 +97,6 @@ golang.org/x/net v0.7.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
-golang.org/x/sys v0.0.0-20190726091711-fc99dfbffb4e/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
@@ -139,7 +134,6 @@ golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc
golang.org/x/tools v0.2.0/go.mod h1:y4OqIKeOV/fWJetJ8bXPU1sEVniLMIyDAZWeHdV+NTA=
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/check.v1 v1.0.0-20180628173108-788fd7840127/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
gopkg.in/check.v1 v1.0.0-20201130134442-10cb98267c6c h1:Hei/4ADfdWqJk1ZMxUNpqntNwaWcugrBjAiHlqqRiVk=
diff --git a/internal/admin/middleware.go b/internal/admin/middleware.go
index 56d4797..60274ad 100644
--- a/internal/admin/middleware.go
+++ b/internal/admin/middleware.go
@@ -5,8 +5,8 @@ import (
"net/http"
)
-// Admin middleware to handle requests to the admin repo.
-func AdminHooks(adminSvc *Servicer, next http.Handler) http.Handler {
+// Hooks middleware to handle requests to the admin repo.
+func Hooks(adminSvc *Servicer, next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
log.Printf("stuffs about to reload %s", "now")
next.ServeHTTP(rw, req)
diff --git a/internal/admin/model.go b/internal/admin/model.go
index 5a7f984..2841e0a 100644
--- a/internal/admin/model.go
+++ b/internal/admin/model.go
@@ -15,9 +15,7 @@ import (
"github.com/go-git/go-git/v5"
"github.com/go-git/go-git/v5/storage/filesystem"
"github.com/go-git/go-git/v5/storage/memory"
-
"gopkg.in/ini.v1"
-
"sigs.k8s.io/yaml"
)
@@ -30,7 +28,7 @@ const (
Admin = 2
// GitExportMagic magic file name for daemon export
GitExportMagic = "git-daemon-export-ok"
- // GitWebExportMagic
+ // GitWebExportMagic magic filename for web repos
GitWebExportMagic = "git-web-export-ok"
)
@@ -71,11 +69,11 @@ type ServerRepos struct {
BasePath string `json:"basepath"`
}
-func loadFromGit(gitUrl, filePath string) ([]byte, error) {
+func loadFromGit(gitURL, filePath string) ([]byte, error) {
fs := memfs.New()
storer := memory.NewStorage()
_, err := git.Clone(storer, fs, &git.CloneOptions{
- URL: gitUrl,
+ URL: gitURL,
})
if err != nil {
// log.error
@@ -97,6 +95,7 @@ func loadLocalFile(path string) ([]byte, error) {
log.Printf("config file not opened %s", path)
return []byte{}, err
}
+ defer file.Close()
configBytes, err := io.ReadAll(file)
if err != nil {
log.Print("config file not read")
@@ -105,9 +104,12 @@ func loadLocalFile(path string) ([]byte, error) {
return configBytes, nil
}
+// loadServerConfig configPath should be the absolutepath to the configmap if it's not in a repo
func loadServerConfig(mgmtRepo bool, baseDir, configPath string) (*ServerRepos, error) {
- configBytes := []byte{}
- var err error
+ var (
+ configBytes []byte
+ err error
+ )
if mgmtRepo {
repoURI := filepath.Join("file:///", baseDir, "mgmt.git")
configBytes, err = loadFromGit(repoURI, configPath)
@@ -117,17 +119,17 @@ func loadServerConfig(mgmtRepo bool, baseDir, configPath string) (*ServerRepos,
return &ServerRepos{}, err
}
} else {
- configBytes, err = loadLocalFile(filepath.Join(baseDir, configPath))
+ configBytes, err = loadLocalFile(configPath)
if err != nil {
// log.error
- log.Print("Failed to load config file from git")
+ log.Print("Failed to load config file from file system")
return &ServerRepos{}, err
}
}
config := &ServerRepos{}
err = yaml.Unmarshal(configBytes, &config)
if err != nil {
- return &ServerRepos{}, errors.New("Could not parse gitserver config")
+ return &ServerRepos{}, errors.New("could not parse gitserver config")
}
return config, nil
}
@@ -189,8 +191,8 @@ func (r *GitRepo) ReconcileRepo(basePath string) {
_, err := os.Stat(repoBase)
if errors.Is(err, fs.ErrNotExist) {
// if no exist -> init bare
- fs := osfs.New(repoBase)
- strg := filesystem.NewStorage(fs, nil)
+ repoFs := osfs.New(repoBase)
+ strg := filesystem.NewStorage(repoFs, nil)
_, _ = git.Init(strg, nil)
}
// set export file for git-http-backend
@@ -231,7 +233,9 @@ func (r *GitWeb) ReconcileGitConf(repoBase string) {
if (GitWeb{} == *r) {
if cfg.HasSection("gitweb") {
cfg.DeleteSection("gitweb")
- cfg.SaveTo(confPath)
+ if err := cfg.SaveTo(confPath); err != nil {
+ log.Fatalf("Coudln't save gitconfig %s", err)
+ }
}
return
}
@@ -240,5 +244,7 @@ func (r *GitWeb) ReconcileGitConf(repoBase string) {
section.Key("owner").SetValue(r.Owner)
section.Key("url").SetValue(r.URL)
section.Key("category").SetValue(r.Category)
- cfg.SaveTo(confPath)
+ if err := cfg.SaveTo(confPath); err != nil {
+ log.Fatalf("Coudln't save gitconfig %s", err)
+ }
}
diff --git a/internal/admin/model_test.go b/internal/admin/model_test.go
index 7f816f5..70ec738 100644
--- a/internal/admin/model_test.go
+++ b/internal/admin/model_test.go
@@ -6,7 +6,6 @@ import (
"fmt"
"io"
"io/fs"
- "io/ioutil"
"os"
"path/filepath"
"strings"
@@ -18,6 +17,7 @@ import (
"gopkg.in/ini.v1"
)
+//nolint:cyclop
func TestCasbinPolicies(t *testing.T) {
roleName := "myrole"
repoName := "myrepo"
@@ -86,7 +86,7 @@ func TestLoadServerConfig(t *testing.T) {
localDir := t.TempDir()
// TODO Refactor next touch
localFile := filepath.Join(localDir, "stuff.yaml")
- srcFile, err := os.Open("../../gitserver.yaml")
+ srcFile, err := os.Open(filepath.Clean("../../gitserver.yaml"))
if err != nil {
t.Fatalf("Error opening base config %s", err)
}
@@ -105,7 +105,7 @@ func TestLoadServerConfig(t *testing.T) {
}
// end copy file
- loadedFile, err := loadServerConfig(false, localDir, "stuff.yaml")
+ loadedFile, err := loadServerConfig(false, localDir, filepath.Join(localDir, "stuff.yaml"))
if err != nil {
t.Fatal(err)
}
@@ -114,7 +114,7 @@ func TestLoadServerConfig(t *testing.T) {
}
})
- t.Run("testing server config from git", func(t *testing.T) {
+ t.Run("testing server config from git", func(_ *testing.T) {
})
}
@@ -122,7 +122,10 @@ func TestLoadServerConfig(t *testing.T) {
func TestLocalFile(t *testing.T) {
localDir := t.TempDir()
localFile := filepath.Join(localDir, "stuff.yaml")
- os.WriteFile(localFile, []byte("stuff"), 0750)
+ //nolint:gosec
+ if err := os.WriteFile(localFile, []byte("stuff"), 0500); err != nil {
+ t.Fatal(err)
+ }
loadedFile, err := loadLocalFile(localFile)
if err != nil {
t.Fatal(err)
@@ -137,6 +140,7 @@ func TestLocalFile(t *testing.T) {
}
}
+//nolint:cyclop
func TestMgmtGitConfig(t *testing.T) {
// setup tempdir
gitDir := t.TempDir()
@@ -173,7 +177,9 @@ func TestMgmtGitConfig(t *testing.T) {
if err != nil {
t.Fatal(err)
}
- wt.Add(fileToCommit)
+ if _, err := wt.Add(fileToCommit); err != nil {
+ t.Fatal(err)
+ }
_, err = wt.Commit(fileToCommit, &git.CommitOptions{})
if err != nil {
t.Fatalf("Error creating commit %s", err)
@@ -203,13 +209,16 @@ func TestMgmtGitConfig(t *testing.T) {
// TODO run via serverLoadConfig
}
+//nolint:cyclop
func TestConfigReconcile(t *testing.T) {
tempDir := t.TempDir()
defer os.RemoveAll(tempDir)
// make "fake" repo
testRepo := filepath.Join(tempDir, "testrepo.git")
testConf := filepath.Join(testRepo, "config")
- os.Mkdir(testRepo, 0750)
+ if err := os.Mkdir(testRepo, 0750); err != nil {
+ t.Fatal(err)
+ }
f, err := os.Create(filepath.Join(testRepo, "config"))
if err != nil {
t.Fatalf("couldn't create testdir, %s", err)
@@ -247,6 +256,9 @@ func TestConfigReconcile(t *testing.T) {
emptyGitWeb := &GitWeb{}
emptyGitWeb.ReconcileGitConf(testRepo)
emptyCfg, err := ini.Load(testConf)
+ if err != nil {
+ t.Fatalf("error couldn't load %s", testConf)
+ }
if emptyCfg.HasSection("gitweb") {
t.Fatalf("reconciler conf didn't remove section `gitweb`")
}
@@ -283,15 +295,18 @@ func TestRepoReconcile(t *testing.T) {
t.Fatal("expected repo to be created, but does not exist")
}
defaultFile := []byte(`
-[core]
-bare = true
+[core]
+bare = true
`)
// write the base config to repo
tempConfigFile := filepath.Join(repoPath, "config")
- ioutil.WriteFile(tempConfigFile, defaultFile, 0644)
+ //nolint:gosec
+ if err := os.WriteFile(tempConfigFile, defaultFile, 0500); err != nil {
+ t.Fatal(err)
+ }
// re-reconcile
repo.ReconcileRepo(tempDir)
- content, err := ioutil.ReadFile(tempConfigFile)
+ content, err := os.ReadFile(tempConfigFile)
if err != nil {
t.Fatal(err)
}
@@ -303,5 +318,4 @@ bare = true
if _, err := os.Stat(gitExportMagicPath); errors.Is(err, fs.ErrNotExist) {
t.Fatal("expected git export magic to be created, but does not exist")
}
-
}
diff --git a/internal/admin/service.go b/internal/admin/service.go
index 84547fa..1b5662d 100644
--- a/internal/admin/service.go
+++ b/internal/admin/service.go
@@ -41,7 +41,7 @@ func (s *Servicer) InitServer() {
continue
}
if added {
- numAdded += 1
+ numAdded++
}
}
log.Printf("policies added %d", numAdded)
diff --git a/internal/admin/service_test.go b/internal/admin/service_test.go
index fdd3aa6..e13d28c 100644
--- a/internal/admin/service_test.go
+++ b/internal/admin/service_test.go
@@ -10,7 +10,7 @@ import (
)
var (
- updatedServerConfig []byte = []byte(`
+ updatedServerConfig = []byte(`
---
name: "go-git-server"
version: "v1alpha1"
@@ -42,7 +42,6 @@ repos:
)
func copyFile(t *testing.T, srcFilePath, destPath string) {
-
srcFile, err := os.Open(srcFilePath)
if err != nil {
t.Fatalf("Error opening base config %s", err)
@@ -87,10 +86,11 @@ func TestInitServer(t *testing.T) {
t.Run("test reload config success", func(t *testing.T) {
svc := NewService(destModelFile,
destPolicyFile,
- "gitserver.yaml",
+ filepath.Join(tempRepoDir, "gitserver.yaml"),
tempRepoDir,
false)
- err := os.WriteFile(destConfigFile, updatedServerConfig, 0755)
+ //nolint:gosec
+ err := os.WriteFile(destConfigFile, updatedServerConfig, 0500)
if err != nil {
t.Fatal(err)
}
@@ -104,16 +104,17 @@ func TestInitServer(t *testing.T) {
if !strings.Contains(string(data), "thisismynewrepo") {
t.Fatal("expected to find test new repo but didn't")
}
-
})
t.Run("test reload config err", func(t *testing.T) {
svc := NewService(destModelFile,
destPolicyFile,
- "gitserver.yaml",
+ // TODO set abs path
+ filepath.Join(tempRepoDir, "gitserver.yaml"),
tempRepoDir,
false)
notAGoodConfig := []byte("this is not valid yaml")
- err := os.WriteFile(destConfigFile, notAGoodConfig, 0755)
+ //nolint:gosec
+ err := os.WriteFile(destConfigFile, notAGoodConfig, 0500)
if err != nil {
t.Fatal(err)
}
@@ -127,6 +128,5 @@ func TestInitServer(t *testing.T) {
if !strings.Contains(string(data), "mgmt") {
log.Fatal("expected to mgmt repo but didn't in policy")
}
-
})
}
diff --git a/internal/authz/middleware.go b/internal/authz/middleware.go
index a35b6b4..6763323 100644
--- a/internal/authz/middleware.go
+++ b/internal/authz/middleware.go
@@ -1,3 +1,4 @@
+// authentication and authorization module
package authz
import (
@@ -11,6 +12,13 @@ import (
"golang.org/x/crypto/bcrypt"
)
+// AuthzContextKey key used to store urn of user in context
+type AuthzContextKey string
+
+var (
+ AuthzUrnKey AuthzContextKey = "goGitAuthzUrn"
+)
+
func Authentication(authMap TokenMap, next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
u, p, ok := req.BasicAuth()
@@ -34,7 +42,7 @@ func Authentication(authMap TokenMap, next http.Handler) http.Handler {
http.Error(rw, "Bad Request", http.StatusForbidden)
return
}
- ctx := context.WithValue(req.Context(), "urn", urn)
+ ctx := context.WithValue(req.Context(), AuthzUrnKey, urn)
next.ServeHTTP(rw, req.WithContext(ctx))
})
}
@@ -43,7 +51,10 @@ func Authentication(authMap TokenMap, next http.Handler) http.Handler {
func Authorization(adminSvc *admin.Servicer, next http.Handler) http.Handler {
return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
ctx := req.Context()
- urn := ctx.Value("urn").(string)
+ urn, ok := ctx.Value(AuthzUrnKey).(string)
+ if !ok || urn == "" {
+ http.Error(rw, "Bad Request", http.StatusBadRequest)
+ }
repo := req.URL.Path
action := req.Method
ok, err := adminSvc.Enforce(urn, repo, action)
diff --git a/internal/authz/middleware_test.go b/internal/authz/middleware_test.go
index cc3f6d1..9ed9081 100644
--- a/internal/authz/middleware_test.go
+++ b/internal/authz/middleware_test.go
@@ -40,11 +40,10 @@ func TestAuthentication(t *testing.T) {
description: "Good Login",
handler: func(rw http.ResponseWriter, req *http.Request) {
ctx := req.Context()
- uid := ctx.Value("urn")
+ uid := ctx.Value(AuthzUrnKey)
if uid != fmt.Sprintf("uid:%s", okUserName) {
t.Fatal("Context UID not set")
}
-
},
},
{
@@ -72,6 +71,7 @@ func TestAuthentication(t *testing.T) {
recorder := httptest.NewRecorder()
authHandler.ServeHTTP(recorder, req)
result := recorder.Result()
+ defer result.Body.Close()
if result.StatusCode != tc.statusCode {
t.Fatalf("Test Case %s failed Expected: %d Found: %d",
tc.description, tc.statusCode, result.StatusCode)
@@ -94,13 +94,13 @@ func TestAuthorization(t *testing.T) {
url: fmt.Sprintf("%s/%s", baseURL, "repo/url"),
user: "uid:jack",
expectedStatus: 200,
- description: "an autorized action should yield a 200",
+ description: "an authorized action should yield a 200",
},
{
url: fmt.Sprintf("%s/%s", baseURL, "repo/url/bar"),
user: "uid:chumba",
expectedStatus: 403,
- description: "an unautorized action should yield a 403",
+ description: "an unauthorized action should yield a 403",
},
}
svcr := admin.NewService(
@@ -115,12 +115,13 @@ func TestAuthorization(t *testing.T) {
recorder := httptest.NewRecorder()
req := httptest.NewRequest(http.MethodGet, tc.url, nil)
ctx := req.Context()
- ctx = context.WithValue(ctx, "urn", tc.user)
+ ctx = context.WithValue(ctx, AuthzUrnKey, tc.user)
req = req.WithContext(ctx)
authHandler.ServeHTTP(recorder, req)
result := recorder.Result()
+ defer result.Body.Close()
if result.StatusCode != tc.expectedStatus {
- t.Fatalf("Test Case failed Expected: %d Found: %d", tc.expectedStatus, result.StatusCode)
+ t.Fatalf("Test Case %s failed Expected: %d Found: %d", tc.description, tc.expectedStatus, result.StatusCode)
}
}
}
diff --git a/internal/authz/model.go b/internal/authz/model.go
index cf9c952..efa78f7 100644
--- a/internal/authz/model.go
+++ b/internal/authz/model.go
@@ -19,7 +19,7 @@ func NewTokenMap() TokenMap {
// TokenMap a map of username,hash
type TokenMap map[string]string
-// LoadTokens load tokens from a csv into a map
+// LoadTokensFromFile load tokens from a csv into a map
func (tm TokenMap) LoadTokensFromFile(path string) error {
// TODO this should be configurable
contents, err := os.Open(path)
@@ -45,8 +45,8 @@ func (tm TokenMap) LoadTokensFromFile(path string) error {
func GenerateNewToken() (string, string, error) {
tokenBytes := make([]byte, 28)
for i := range tokenBytes {
- max := big.NewInt(int64(255))
- randInt, err := rand.Int(rand.Reader, max)
+ maxInt := big.NewInt(int64(255))
+ randInt, err := rand.Int(rand.Reader, maxInt)
if err != nil {
return "", "", err
}
diff --git a/internal/git/handler.go b/internal/git/handler.go
index e90ab5f..6dc4584 100644
--- a/internal/git/handler.go
+++ b/internal/git/handler.go
@@ -3,7 +3,7 @@ package git
import (
"fmt"
"net/http"
- "net/http/cgi"
+ "net/http/cgi" //nolint:gosec
)
// GitHttpBackendHandler a handler for git cgi