1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
|
package main
import (
"flag"
"fmt"
"log/slog"
"net/http"
"os"
"time"
"git.ofmax.li/go-git-server/internal/admin"
"git.ofmax.li/go-git-server/internal/authz"
"git.ofmax.li/go-git-server/internal/git"
"git.ofmax.li/go-git-server/internal/modules"
)
var (
reposDir string
mgmtRepo bool
backendCommand string
loggingLevel string
addr string
serverHost string
modelPath string
policyPath string
serverConfigPath string
tokenFilePath string
newToken bool
goGitServerVersion string
showVersion bool
)
var (
logLevels = map[string]slog.Level{
"DEBUG": slog.LevelDebug,
"INFO": slog.LevelInfo,
"ERROR": slog.LevelError,
}
)
func main() {
flag.Parse()
level, ok := logLevels[loggingLevel]
slog.Info("log level", "found", loggingLevel)
if !ok {
slog.Error("log levels are DEBUG, INFO, ERROR", "found", loggingLevel)
os.Exit(1)
}
slog.SetLogLoggerLevel(level)
slog.Info("go-git-server", "version", goGitServerVersion)
if showVersion {
os.Exit(0)
}
if newToken {
token, hash, err := authz.GenerateNewToken()
if err != nil {
slog.Error("error generating token", slog.Any("error", err))
os.Exit(1)
}
fmt.Printf("token: %s\nhash: %s\n", token, hash)
return
}
adminSvc, err := admin.NewService(modelPath, policyPath, serverConfigPath, reposDir, mgmtRepo)
if err != nil {
slog.Error("exiting due to error", "msg", err)
os.Exit(1)
}
if err := adminSvc.InitServer(); err != nil {
slog.Error("error initializing server", "msg", err)
}
// Load authentication tokens and identity mappings
tokens := authz.NewSafeTokenMap()
identities := authz.NewIdentityMap()
// Load tokens from CSV file
tokenMap, identityMap, err := authz.LoadTokensFromFile(tokenFilePath)
if err != nil {
slog.Error("error loading tokens", slog.Any("error", err))
os.Exit(1)
}
// Update the token map with loaded values
for id, hash := range tokenMap {
tokens.Set(id, hash)
}
// Copy identity mappings
for id, name := range identityMap.IDToName {
identities.Register(id, name)
}
// Create git and module handlers
gitHandler := git.GitHttpBackendHandler(reposDir, backendCommand)
moduleHandler := modules.NewModuleHandler(reposDir, serverHost, adminSvc.Conf)
router := http.NewServeMux()
// TODO we don't want to use a global
// de-reference args
router.Handle("/mgmt/", admin.Hooks(adminSvc, gitHandler))
// Apply authentication to git operations
authenticatedGitHandler := authz.Authentication(tokens, identities, authz.Authorization(adminSvc, gitHandler))
// Apply module middleware (handles module requests directly, passes git requests to auth)
moduleMiddleware := modules.ModuleMiddleware(moduleHandler, authenticatedGitHandler)
router.Handle("/", moduleMiddleware)
server := &http.Server{
Addr: addr,
ReadHeaderTimeout: 5 * time.Second,
Handler: router,
}
slog.Error("error while running exiting", slog.Any("error", server.ListenAndServe()))
os.Exit(1)
}
func init() {
logLevel, ok := os.LookupEnv("GO_GIT_SERVER_LOG_LEVEL")
if !ok {
logLevel = "INFO"
}
flag.StringVar(&backendCommand, "c", "git http-backend", "CGI binary to execute")
flag.StringVar(&loggingLevel, "e", logLevel, "set log level")
flag.StringVar(&addr, "l", ":8080", "Address/port to listen on")
flag.StringVar(&serverHost, "h", "localhost:8080", "Public hostname for Go module discovery")
flag.StringVar(&modelPath, "m", "./auth_model.ini", "casbin authentication model")
flag.StringVar(&policyPath, "p", "./policy.csv", "casbin auth policy")
flag.StringVar(&tokenFilePath, "t", "./tokens.csv", "casbin auth policy")
flag.StringVar(&serverConfigPath, "s", "./gitserver.yaml", "serverconfig path, this should be relative to the git root or absolute if not using mgmt repo")
flag.StringVar(&reposDir, "r", "./repos", "Directory containing git repositories")
flag.BoolVar(&mgmtRepo, "a", false, "mgmt repo used for configuration")
flag.BoolVar(&newToken, "g", false, "make a new token")
flag.BoolVar(&showVersion, "v", false, "show version of go-git-server")
}
|