diff --git a/.gitignore b/.gitignore index d5f19d8..c3e2d52 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ node_modules package-lock.json +*.db diff --git a/db.go b/db.go index 6c22a69..7070278 100644 --- a/db.go +++ b/db.go @@ -19,11 +19,12 @@ import ( // Link is the structure stored for each go short link. type Link struct { - Short string // the "foo" part of http://go/foo - Long string // the target URL or text/template pattern to run - Created time.Time - LastEdit time.Time // when the link was last edited - Owner string // user@domain + Short string // the "foo" part of http://go/foo + Long string // the target URL or text/template pattern to run + Created time.Time + LastEdit time.Time // when the link was last edited + Owner string // user@domain + GloballyEditable bool // when set, link is editable by everyone on the tailnet } // ClickStats is the number of clicks a set of links have received in a given @@ -67,14 +68,14 @@ func NewSQLiteDB(f string) (*SQLiteDB, error) { // The caller owns the returned values. func (s *SQLiteDB) LoadAll() ([]*Link, error) { var links []*Link - rows, err := s.db.Query("SELECT Short, Long, Created, LastEdit, Owner FROM Links") + rows, err := s.db.Query("SELECT Short, Long, Created, LastEdit, Owner, GloballyEditable FROM Links") if err != nil { return nil, err } for rows.Next() { link := new(Link) var created, lastEdit int64 - err := rows.Scan(&link.Short, &link.Long, &created, &lastEdit, &link.Owner) + err := rows.Scan(&link.Short, &link.Long, &created, &lastEdit, &link.Owner, &link.GloballyEditable) if err != nil { return nil, err } @@ -93,8 +94,8 @@ func (s *SQLiteDB) LoadAll() ([]*Link, error) { func (s *SQLiteDB) Load(short string) (*Link, error) { link := new(Link) var created, lastEdit int64 - row := s.db.QueryRow("SELECT Short, Long, Created, LastEdit, Owner FROM Links WHERE ID = ?1 LIMIT 1", linkID(short)) - err := row.Scan(&link.Short, &link.Long, &created, &lastEdit, &link.Owner) + row := s.db.QueryRow("SELECT Short, Long, Created, LastEdit, Owner, GloballyEditable FROM Links WHERE ID = ?1 LIMIT 1", linkID(short)) + err := row.Scan(&link.Short, &link.Long, &created, &lastEdit, &link.Owner, &link.GloballyEditable) if err != nil { if errors.Is(err, sql.ErrNoRows) { err = fs.ErrNotExist @@ -108,7 +109,7 @@ func (s *SQLiteDB) Load(short string) (*Link, error) { // Save saves a Link. func (s *SQLiteDB) Save(link *Link) error { - result, err := s.db.Exec("INSERT OR REPLACE INTO Links (ID, Short, Long, Created, LastEdit, Owner) VALUES (?, ?, ?, ?, ?, ?)", linkID(link.Short), link.Short, link.Long, link.Created.Unix(), link.LastEdit.Unix(), link.Owner) + result, err := s.db.Exec("INSERT OR REPLACE INTO Links (ID, Short, Long, Created, LastEdit, Owner, GloballyEditable) VALUES (?, ?, ?, ?, ?, ?, ?)", linkID(link.Short), link.Short, link.Long, link.Created.Unix(), link.LastEdit.Unix(), link.Owner, link.GloballyEditable) if err != nil { return err } diff --git a/golink.go b/golink.go index 67b2cba..b891448 100644 --- a/golink.go +++ b/golink.go @@ -344,6 +344,10 @@ func serveDetail(w http.ResponseWriter, r *http.Request) { data.Link.Owner = login } + if link.GloballyEditable { + data.Editable = true + } + detailTmpl.Execute(w, data) } @@ -456,7 +460,7 @@ func serveSave(w http.ResponseWriter, r *http.Request) { http.Error(w, err.Error(), http.StatusInternalServerError) } - if link != nil && link.Owner != "" && link.Owner != login { + if link != nil && link.Owner != "" && link.Owner != login && !link.GloballyEditable { exists, err := userExists(r.Context(), link.Owner) if err != nil { log.Printf("looking up tailnet user %q: %v", link.Owner, err) @@ -484,6 +488,8 @@ func serveSave(w http.ResponseWriter, r *http.Request) { owner = login } + globallyEditable := r.FormValue("globally-editable") == "on" + now := time.Now().UTC() if link == nil { link = &Link{ @@ -495,6 +501,7 @@ func serveSave(w http.ResponseWriter, r *http.Request) { link.Long = long link.LastEdit = now link.Owner = owner + link.GloballyEditable = globallyEditable if err := db.Save(link); err != nil { http.Error(w, err.Error(), http.StatusInternalServerError) return diff --git a/schema.sql b/schema.sql index ac6dd04..9aaa45b 100644 --- a/schema.sql +++ b/schema.sql @@ -4,7 +4,8 @@ CREATE TABLE IF NOT EXISTS Links ( Long TEXT NOT NULL DEFAULT "", Created INTEGER NOT NULL DEFAULT (strftime('%s', 'now')), -- unix seconds LastEdit INTEGER NOT NULL DEFAULT (strftime('%s', 'now')), -- unix seconds - Owner TEXT NOT NULL DEFAULT "" + Owner TEXT NOT NULL DEFAULT "", + GloballyEditable INTEGER NOT NULL DEFAULT FALSE ); CREATE TABLE IF NOT EXISTS Stats ( diff --git a/tmpl/detail.html b/tmpl/detail.html index f87f3ce..77cf9dd 100644 --- a/tmpl/detail.html +++ b/tmpl/detail.html @@ -17,6 +17,8 @@