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