fix(web): clone failures, internal errors and stale sessions
4 files changed, +25 −13
- pull.go modified +6 −2
- static/style.css modified +3 −3
- store.go modified +4 −6
- web.go modified +12 −2
pull.go modified
| @@ -4,6 +4,7 @@ import ( | ||
| 4 | 4 | "database/sql" |
| 5 | 5 | "errors" |
| 6 | 6 | "fmt" |
| 7 | + "log" | |
| 7 | 8 | "html/template" |
| 8 | 9 | "net/http" |
| 9 | 10 | "os" |
| @@ -828,12 +829,15 @@ func (s *Server) fork(w http.ResponseWriter, r *http.Request, repo Repo) { | ||
| 828 | 829 | return |
| 829 | 830 | } |
| 830 | 831 | dir := s.repoDir(fork) |
| 831 | - if err := os.MkdirAll(filepath.Dir(dir), 0o755); err == nil { | |
| 832 | + err = os.MkdirAll(filepath.Dir(dir), 0o755) | |
| 833 | + if err == nil { | |
| 832 | 834 | err = cloneRepo(s.repoDir(repo), dir) |
| 833 | 835 | } |
| 834 | 836 | if err != nil { |
| 837 | + log.Printf("create %s: %v", fork.Path(), err) | |
| 838 | + os.RemoveAll(dir) | |
| 835 | 839 | s.store.DeleteRepo(fork.ID) |
| 836 | - s.fail(w, r, 500, err.Error()) | |
| 840 | + s.fail(w, r, 500, "Could not create the repository") | |
| 837 | 841 | return |
| 838 | 842 | } |
| 839 | 843 | installHook(s.root, dir) |
static/style.css modified
| @@ -190,9 +190,9 @@ input[type=file]{border:0;padding:0} | ||
| 190 | 190 | .twocol{display:grid;grid-template-columns:1fr 1fr;gap:2rem;margin-bottom:2rem} |
| 191 | 191 | .twocol label{display:flex;flex-direction:column;gap:.25rem;margin-bottom:.8rem} |
| 192 | 192 | .twocol .legend{display:block;margin-bottom:.4rem} |
| 193 | -label.radio,.twocol label.check,.modes label.radio{flex-direction:row;flex-wrap:wrap;align-items:center;gap:.4rem;margin-bottom:.6rem} | |
| 194 | -label.radio small,.modes label.radio small{flex-basis:100%;color:var(--muted);padding-left:1.4rem} | |
| 195 | -.modes input[type=radio]{width:auto;margin:0} | |
| 193 | +label.radio,.twocol label.check{flex-direction:row;flex-wrap:wrap;align-items:center;gap:.4rem;margin-bottom:.6rem} | |
| 194 | +label.radio small{flex-basis:100%;color:var(--muted);padding-left:1.4rem} | |
| 195 | +label.radio input[type=radio]{width:auto;margin:0} | |
| 196 | 196 | h3.plain{border:0;font-size:1.25rem} |
| 197 | 197 | .columns.browse{grid-template-columns:minmax(0,2fr) 1fr} |
| 198 | 198 | .search input[name=search],.search input[name=q]{width:100%} |
store.go modified
| @@ -404,6 +404,10 @@ func (s *Store) DeleteSession(id string) { | ||
| 404 | 404 | s.db.Exec(`delete from sessions where id = ?`, id) |
| 405 | 405 | } |
| 406 | 406 | |
| 407 | +func (s *Store) KeepOnlySession(user int64, id string) { | |
| 408 | + s.db.Exec(`delete from sessions where user = ? and id != ?`, user, id) | |
| 409 | +} | |
| 410 | + | |
| 407 | 411 | func (s *Store) DeleteSessions(user int64) { |
| 408 | 412 | s.db.Exec(`delete from sessions where user = ?`, user) |
| 409 | 413 | } |
| @@ -1050,12 +1054,6 @@ func (s *Store) Starred(user, repo int64) bool { | ||
| 1050 | 1054 | return n > 0 |
| 1051 | 1055 | } |
| 1052 | 1056 | |
| 1053 | -func (s *Store) StarCount(repo int64) int { | |
| 1054 | - var n int | |
| 1055 | - s.db.QueryRow(`select count(*) from stars where repo = ?`, repo).Scan(&n) | |
| 1056 | - return n | |
| 1057 | -} | |
| 1058 | - | |
| 1059 | 1057 | func (s *Store) StarredCount(user int64) int { |
| 1060 | 1058 | var n int |
| 1061 | 1059 | s.db.QueryRow(`select count(*) from stars st join repos r on r.id = st.repo where st.user = ? and r.private = 0`, user).Scan(&n) |
web.go modified
| @@ -198,6 +198,10 @@ func (s *Server) render(w http.ResponseWriter, r *http.Request, name string, p p | ||
| 198 | 198 | } |
| 199 | 199 | |
| 200 | 200 | func (s *Server) fail(w http.ResponseWriter, r *http.Request, code int, msg string) { |
| 201 | + if code >= 500 { | |
| 202 | + log.Printf("%s %s: %s", r.Method, r.URL.Path, msg) | |
| 203 | + msg = "Something went wrong" | |
| 204 | + } | |
| 201 | 205 | w.WriteHeader(code) |
| 202 | 206 | s.render(w, r, "error", page{Title: msg, Error: msg}) |
| 203 | 207 | } |
| @@ -437,12 +441,15 @@ func (s *Server) create(w http.ResponseWriter, r *http.Request) { | ||
| 437 | 441 | return |
| 438 | 442 | } |
| 439 | 443 | dir := s.repoDir(repo) |
| 440 | - if err := os.MkdirAll(filepath.Dir(dir), 0o755); err == nil { | |
| 444 | + err = os.MkdirAll(filepath.Dir(dir), 0o755) | |
| 445 | + if err == nil { | |
| 441 | 446 | err = initRepo(dir) |
| 442 | 447 | } |
| 443 | 448 | if err != nil { |
| 449 | + log.Printf("create %s: %v", repo.Path(), err) | |
| 450 | + os.RemoveAll(dir) | |
| 444 | 451 | s.store.DeleteRepo(repo.ID) |
| 445 | - s.fail(w, r, 500, err.Error()) | |
| 452 | + s.fail(w, r, 500, "Could not create the repository") | |
| 446 | 453 | return |
| 447 | 454 | } |
| 448 | 455 | installHook(s.root, dir) |
| @@ -819,6 +826,9 @@ func (s *Server) password(w http.ResponseWriter, r *http.Request) { | ||
| 819 | 826 | http.Redirect(w, r, "/settings/security?error="+template.URLQueryEscaper(err.Error()), http.StatusSeeOther) |
| 820 | 827 | return |
| 821 | 828 | } |
| 829 | + if c, err := r.Cookie("session"); err == nil { | |
| 830 | + s.store.KeepOnlySession(u.ID, c.Value) | |
| 831 | + } | |
| 822 | 832 | http.Redirect(w, r, "/settings/security", http.StatusSeeOther) |
| 823 | 833 | } |
| 824 | 834 | |