💾 Archived View for gemini.rmf-dev.com › repo › Vaati › Gemigit › files › 71e66c8c97c3c9a4ecc1723592… captured on 2023-12-28 at 15:35:04. Gemini links have been rewritten to link to archived content
-=-=-=-=-=-=-
0 package main
1
2 import (
3 "fmt"
4 "log"
5 "os"
6
7 "golang.org/x/term"
8
9 "gemigit/access"
10 "gemigit/auth"
11 "gemigit/config"
12 "gemigit/db"
13 "gemigit/httpgit"
14 "gemigit/sshgit"
15 "gemigit/repo"
16 "gemigit/gmi"
17
18 "github.com/pitr/gig"
19 )
20
21 func main() {
22
23 if err := config.LoadConfig(); err != nil {
24 log.Fatalln(err.Error())
25 }
26
27 if len(os.Args) > 1 {
28 switch (os.Args[1]) {
29 case "chpasswd":
30 if (config.Cfg.Ldap.Enabled) {
31 fmt.Println("Not valid when LDAP is enabled")
32 return
33 }
34 if len(os.Args) < 3 {
35 fmt.Println(os.Args[0] +
36 " chpasswd <username>")
37 return
38 }
39 fmt.Print("New Password : ")
40 password, err := term.ReadPassword(0)
41 fmt.Print("\n")
42 if err != nil {
43 log.Fatalln(err.Error())
44 }
45 err = db.Init(config.Cfg.Database.Type,
46 config.Cfg.Database.Url, false)
47 if err != nil {
48 log.Fatalln(err.Error())
49 }
50 defer db.Close()
51 if err := db.ChangePassword(os.Args[2],
52 string(password));
53 err != nil {
54 fmt.Println(err.Error())
55 return
56 }
57 fmt.Println(os.Args[2] + "'s password changed")
58 return
59 case "register":
60 if (config.Cfg.Ldap.Enabled) {
61 fmt.Println("Not valid when LDAP is enabled")
62 return
63 }
64 if len(os.Args) < 3 {
65 fmt.Println(os.Args[0] +
66 " register <username>")
67 return
68 }
69 fmt.Print("Password : ")
70 password, err := term.ReadPassword(0)
71 fmt.Print("\n")
72 if err != nil {
73 log.Fatalln(err.Error())
74 }
75 err = db.Init(config.Cfg.Database.Type,
76 config.Cfg.Database.Url, false)
77 if err != nil {
78 log.Fatalln(err.Error())
79 }
80 defer db.Close()
81 if err := db.Register(os.Args[2], string(password));
82 err != nil {
83 fmt.Println(err.Error())
84 return
85 }
86 fmt.Println("User " + os.Args[2] + " created")
87 return
88 case "rmuser":
89 if len(os.Args) < 3 {
90 fmt.Println(os.Args[0] + " rmuser <username>")
91 return
92 }
93 err := db.Init(config.Cfg.Database.Type,
94 config.Cfg.Database.Url, false)
95 if err != nil {
96 log.Fatalln(err.Error())
97 }
98 defer db.Close()
99 err = db.DeleteUser(os.Args[2])
100 if err != nil {
101 log.Fatalln(err)
102 }
103 fmt.Println("User " + os.Args[2] +
104 " deleted successfully")
105 return
106 case "init":
107 err := db.Init(config.Cfg.Database.Type,
108 config.Cfg.Database.Url, true)
109 if err != nil {
110 log.Fatalln(err.Error())
111 }
112 db.Close()
113 return
114 case "update":
115 err := db.Init(config.Cfg.Database.Type,
116 config.Cfg.Database.Url, false)
117 if err != nil {
118 log.Fatalln(err.Error())
119 }
120 db.UpdateTable()
121 db.Close()
122 return
123 }
124 fmt.Println("usage: " + os.Args[0] + " [command]")
125 fmt.Println("commands :")
126 fmt.Println("\tchpasswd <username> - Change user password")
127 fmt.Println("\tregister <username> - Create user")
128 fmt.Println("\trmuser <username> - Remove user")
129 fmt.Println("\tupdate - Update database " +
130 "(Warning, it is recommended to do a backup of " +
131 "the database before using this command)")
132 fmt.Println("\tinit - Initialize database")
133 return
134 }
135
136 log.SetFlags(log.LstdFlags | log.Lshortfile)
137
138 if err := access.Init(); err != nil {
139 log.Fatalln(err.Error())
140 }
141
142 if err := gmi.LoadTemplate(config.Cfg.Gemini.Templates); err != nil {
143 log.Fatalln(err.Error())
144 }
145
146 err := db.Init(config.Cfg.Database.Type,
147 config.Cfg.Database.Url, false)
148 if err != nil {
149 log.Fatalln(err.Error())
150 }
151 defer db.Close()
152 if err := repo.Init("repos"); err != nil {
153 log.Fatalln(err.Error())
154 }
155
156 if !config.Cfg.Git.Remote.Enabled {
157 if config.Cfg.Git.Http.Enabled {
158 go httpgit.Listen(config.Cfg.Git.Path,
159 config.Cfg.Git.Http.Address,
160 config.Cfg.Git.Http.Port)
161 }
162 if config.Cfg.Git.SSH.Enabled {
163 go sshgit.Listen(config.Cfg.Git.Path,
164 config.Cfg.Git.SSH.Address,
165 config.Cfg.Git.SSH.Port)
166 }
167 }
168 go auth.Decrease()
169
170 gig.DefaultLoggerConfig.Format = "${time_rfc3339} - ${remote_ip} | " +
171 "Path=${path}, Status=${status}, " +
172 "Latency=${latency}\n"
173 g := gig.Default()
174 g.Use(gig.Recover())
175 g.File("/robots.txt", config.Cfg.Gemini.Templates + "/robots.txt")
176 if config.Cfg.Gemini.StaticDirectory != "" {
177 g.Static("/static", config.Cfg.Gemini.StaticDirectory)
178 }
179
180 passAuth := gig.PassAuth(
181 func(sig string, c gig.Context) (string, error) {
182 _, b := db.GetUser(sig)
183 if !b {
184 return "/login", nil
185 }
186 return "", nil
187 })
188
189 secure := g.Group("/account", passAuth)
190
191 secure.Handle("", gmi.ShowAccount)
192 // groups management
193 secure.Handle("/groups", gmi.ShowGroups)
194 secure.Handle("/groups/:group", gmi.ShowMembers)
195 secure.Handle("/groups/:group/desc", gmi.SetGroupDesc)
196 secure.Handle("/groups/:group/add", gmi.AddToGroup)
197 secure.Handle("/groups/:group/leave", gmi.LeaveGroup)
198 secure.Handle("/groups/:group/delete", gmi.DeleteGroup)
199 secure.Handle("/groups/:group/kick/:user", gmi.RmFromGroup)
200
201 // repository settings
202 secure.Handle("/repo/:repo/*", gmi.RepoFile)
203 secure.Handle("/repo/:repo/togglepublic", gmi.TogglePublic)
204 secure.Handle("/repo/:repo/chname", gmi.ChangeRepoName)
205 secure.Handle("/repo/:repo/chdesc", gmi.ChangeRepoDesc)
206 secure.Handle("/repo/:repo/delrepo", gmi.DeleteRepo)
207
208 // access management
209 secure.Handle("/repo/:repo/access", gmi.ShowAccess)
210 secure.Handle("/repo/:repo/access/add", gmi.AddUserAccess)
211 secure.Handle("/repo/:repo/access/addg", gmi.AddGroupAccess)
212 secure.Handle("/repo/:repo/access/:user/first",
213 gmi.UserAccessFirstOption)
214 secure.Handle("/repo/:repo/access/:user/second",
215 gmi.UserAccessSecondOption)
216 secure.Handle("/repo/:repo/access/:group/g/first",
217 gmi.GroupAccessFirstOption)
218 secure.Handle("/repo/:repo/access/:group/g/second",
219 gmi.GroupAccessSecondOption)
220 secure.Handle("/repo/:repo/access/:user/kick",
221 gmi.RemoveUserAccess)
222 secure.Handle("/repo/:repo/access/:group/g/kick",
223 gmi.RemoveGroupAccess)
224
225 // repository view
226 secure.Handle("/repo/:repo", gmi.RepoLog)
227 secure.Handle("/repo/:repo/license", gmi.RepoLicense)
228 secure.Handle("/repo/:repo/readme", gmi.RepoReadme)
229 secure.Handle("/repo/:repo/refs", gmi.RepoRefs)
230 secure.Handle("/repo/:repo/files", gmi.RepoFiles)
231 secure.Handle("/repo/:repo/files/:blob", gmi.RepoFileContent)
232
233 // user page
234 secure.Handle("/chdesc", gmi.ChangeDesc)
235 secure.Handle("/addrepo", gmi.AddRepo)
236 secure.Handle("/addgroup", gmi.AddGroup)
237 // otp
238 secure.Handle("/otp", gmi.ShowOTP)
239 secure.Handle("/otp/qr", gmi.CreateTOTP)
240 secure.Handle("/otp/confirm", gmi.ConfirmTOTP)
241 secure.Handle("/otp/rm", gmi.RemoveTOTP)
242 // token
243 secure.Handle("/token", gmi.ListTokens)
244 secure.Handle("/token/new", gmi.CreateWriteToken)
245 secure.Handle("/token/new_ro", gmi.CreateReadToken)
246 secure.Handle("/token/secure", gmi.ToggleTokenAuth)
247 secure.Handle("/token/renew/:token", gmi.RenewToken)
248 secure.Handle("/token/delete/:token", gmi.DeleteToken)
249
250 if !config.Cfg.Ldap.Enabled {
251 secure.Handle("/chpasswd", gmi.ChangePassword)
252 }
253
254 secure.Handle("/disconnect", gmi.Disconnect)
255 secure.Handle("/disconnectall", gmi.DisconnectAll)
256
257 if config.Cfg.Git.Key != "" {
258 api := g.Group("/api")
259 api.Handle("/:key/init/:username/:repo", repo.ApiInit)
260 api.Handle("/:key/rm/:username/:repo", repo.ApiRemove)
261 api.Handle("/:key/mv/:username/:repo/:newname",
262 repo.ApiRename)
263 }
264
265 var public *gig.Group
266 if config.Cfg.Git.Public {
267 public = g.Group("/repo")
268 } else {
269 public = g.Group("/repo", passAuth)
270 }
271
272 public.Handle("", gmi.PublicList)
273 public.Handle("/:user/:repo/*", gmi.PublicFile)
274 public.Handle("/:user", gmi.PublicAccount)
275 public.Handle("/:user/:repo", gmi.PublicLog)
276 public.Handle("/:user/:repo/refs", gmi.PublicRefs)
277 public.Handle("/:user/:repo/license", gmi.PublicLicense)
278 public.Handle("/:user/:repo/readme", gmi.PublicReadme)
279 public.Handle("/:user/:repo/files", gmi.PublicFiles)
280 public.Handle("/:user/:repo/files/:blob", gmi.PublicFileContent)
281
282 g.PassAuthLoginHandle("/login", gmi.Login)
283
284 if config.Cfg.Users.Registration {
285 g.Handle("/register", gmi.Register)
286 g.Handle("/register/:name", gmi.RegisterConfirm)
287 }
288 g.Handle("/otp", gmi.LoginOTP)
289
290 g.Handle("/", func(c gig.Context) error {
291 return gmi.ShowIndex(c)
292 })
293
294 err = g.Run(config.Cfg.Gemini.Address + ":" + config.Cfg.Gemini.Port,
295 config.Cfg.Gemini.Certificate, config.Cfg.Gemini.Key)
296
297 if err != nil {
298 log.Fatal(err.Error())
299 }
300 }
301