From bd4bb52b9c8f6e18a9761e661bc7612d45679ac5 Mon Sep 17 00:00:00 2001 From: Matt Baer Date: Mon, 22 Jul 2019 14:37:32 -0400 Subject: [PATCH 01/12] Hide Public blog option on single-user instances --- templates/user/collection.tmpl | 2 ++ 1 file changed, 2 insertions(+) diff --git a/templates/user/collection.tmpl b/templates/user/collection.tmpl index 08e8886..8af3bda 100644 --- a/templates/user/collection.tmpl +++ b/templates/user/collection.tmpl @@ -58,6 +58,7 @@

A password is required to read this blog.

+ {{if not .SingleUser}}
  • + {{end}} From 3129b837f17a75383ca789b1285098d7fd78b96c Mon Sep 17 00:00:00 2001 From: Matt Baer Date: Mon, 22 Jul 2019 14:40:10 -0400 Subject: [PATCH 02/12] Hide footer links to About and Privacy pages when single-user Previously, these links showed up on user backend pages on a single-user instance, despite them not working / only being applicable on multi-user instances. --- templates/user/include/footer.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/user/include/footer.tmpl b/templates/user/include/footer.tmpl index 36a69fa..572d9d6 100644 --- a/templates/user/include/footer.tmpl +++ b/templates/user/include/footer.tmpl @@ -8,10 +8,10 @@
    From a48b746706830c62321f738f526165beae2aac3d Mon Sep 17 00:00:00 2001 From: Matt Baer Date: Mon, 22 Jul 2019 14:47:39 -0400 Subject: [PATCH 03/12] Fix empty Drafts page for single-user instances - This removes copy mentioning the Blogs page, which isn't used on single-user instances - This fixes the "Start writing" link, which on a single-user instance would've gone to the blog index, rather than the editor --- templates/user/articles.tmpl | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/templates/user/articles.tmpl b/templates/user/articles.tmpl index 4956301..67d3e0b 100644 --- a/templates/user/articles.tmpl +++ b/templates/user/articles.tmpl @@ -34,8 +34,8 @@ {{if .Summary}}

    {{.Summary}}

    {{end}} {{end}} {{ else }}

    You haven't saved any drafts yet.

    -

    They'll show up here once you do. Find your blog posts from the Blogs page.

    -

    Start writing

    {{ end }} +

    They'll show up here once you do. {{if not .SingleUser}}Find your blog posts from the Blogs page.{{end}}

    +

    Start writing

    {{ end }}
    From a75b45f060473b41d7fbd1c181d1919885cad0bf Mon Sep 17 00:00:00 2001 From: Matt Baer Date: Wed, 31 Jul 2019 22:18:40 -0400 Subject: [PATCH 04/12] Support configuring default collection visibility This adds a new `default_visibility` config value that lets an instance admin set the visibility of newly created collections. Ref T675 --- account.go | 2 +- app.go | 4 ++-- collections.go | 49 ++++++++++++++++++++++++++++++++++++------------ config/config.go | 3 +++ database.go | 6 +++--- 5 files changed, 46 insertions(+), 18 deletions(-) diff --git a/account.go b/account.go index d8ea0df..a0fffc7 100644 --- a/account.go +++ b/account.go @@ -163,7 +163,7 @@ func signupWithRegistration(app *App, signup userRegistration, w http.ResponseWr } // Create actual user - if err := app.db.CreateUser(u, desiredUsername); err != nil { + if err := app.db.CreateUser(app, u, desiredUsername); err != nil { return nil, err } diff --git a/app.go b/app.go index 79b7145..f0816ec 100644 --- a/app.go +++ b/app.go @@ -507,7 +507,7 @@ func DoConfig(app *App, configSections string) { // Create blog log.Info("Creating user %s...\n", u.Username) - err = app.db.CreateUser(u, app.cfg.App.SiteName) + err = app.db.CreateUser(app, u, app.cfg.App.SiteName) if err != nil { log.Error("Unable to create user: %s", err) os.Exit(1) @@ -702,7 +702,7 @@ func CreateUser(apper Apper, username, password string, isAdmin bool) error { userType = "admin" } log.Info("Creating %s %s...", userType, usernameDesc) - err = apper.App().db.CreateUser(u, desiredUsername) + err = apper.App().db.CreateUser(apper.App(), u, desiredUsername) if err != nil { return fmt.Errorf("Unable to create user: %s", err) } diff --git a/collections.go b/collections.go index 1a8ceca..27f740a 100644 --- a/collections.go +++ b/collections.go @@ -31,6 +31,7 @@ import ( "github.com/writeas/web-core/log" waposts "github.com/writeas/web-core/posts" "github.com/writeas/writefreely/author" + "github.com/writeas/writefreely/config" "github.com/writeas/writefreely/page" ) @@ -126,6 +127,21 @@ const ( CollProtected ) +var collVisibilityStrings = map[string]collVisibility{ + "unlisted": CollUnlisted, + "public": CollPublic, + "private": CollPrivate, + "protected": CollProtected, +} + +func defaultVisibility(cfg *config.Config) collVisibility { + vis, ok := collVisibilityStrings[cfg.App.DefaultVisibility] + if !ok { + vis = CollUnlisted + } + return vis +} + func (cf *CollectionFormat) Ascending() bool { return cf.Format == "novel" } @@ -358,35 +374,44 @@ func newCollection(app *App, w http.ResponseWriter, r *http.Request) error { return impart.HTTPError{http.StatusBadRequest, fmt.Sprintf("Parameter(s) %srequired.", missingParams)} } + var userID int64 if reqJSON && !c.Web { accessToken = r.Header.Get("Authorization") if accessToken == "" { return ErrNoAccessToken } + userID = app.db.GetUserID(accessToken) + if userID == -1 { + return ErrBadAccessToken + } } else { u = getUserSession(app, r) if u == nil { return ErrNotLoggedIn } + userID = u.ID } if !author.IsValidUsername(app.cfg, c.Alias) { return impart.HTTPError{http.StatusPreconditionFailed, "Collection alias isn't valid."} } - var coll *Collection - var err error - if accessToken != "" { - coll, err = app.db.CreateCollectionFromToken(c.Alias, c.Title, accessToken) + coll, err := app.db.CreateCollection(c.Alias, c.Title, userID) + if err != nil { + // TODO: handle this + return err + } + + // Set visibility to configured default + vis := defaultVisibility(app.cfg) + if vis != CollUnlisted { + visInt := int(vis) + err = app.db.UpdateCollection(&SubmittedCollection{ + OwnerID: uint64(userID), + Visibility: &visInt, + }, coll.Alias) if err != nil { - // TODO: handle this - return err - } - } else { - coll, err = app.db.CreateCollection(c.Alias, c.Title, u.ID) - if err != nil { - // TODO: handle this - return err + log.Error("Unable to set default visibility: %s", err) } } diff --git a/config/config.go b/config/config.go index 8009208..369015a 100644 --- a/config/config.go +++ b/config/config.go @@ -83,6 +83,9 @@ type ( // Additional functions LocalTimeline bool `ini:"local_timeline"` UserInvites string `ini:"user_invites"` + + // Defaults + DefaultVisibility string `ini:"default_visibility"` } // Config holds the complete configuration for running a writefreely instance diff --git a/database.go b/database.go index 1ea9872..e439070 100644 --- a/database.go +++ b/database.go @@ -44,7 +44,7 @@ var ( ) type writestore interface { - CreateUser(*User, string) error + CreateUser(*App, *User, string) error UpdateUserEmail(keys *key.Keychain, userID int64, email string) error UpdateEncryptedUserEmail(int64, []byte) error GetUserByID(int64) (*User, error) @@ -162,7 +162,7 @@ func (db *datastore) dateSub(l int, unit string) string { return fmt.Sprintf("DATE_SUB(NOW(), INTERVAL %d %s)", l, unit) } -func (db *datastore) CreateUser(u *User, collectionTitle string) error { +func (db *datastore) CreateUser(app *App, u *User, collectionTitle string) error { if db.PostIDExists(u.Username) { return impart.HTTPError{http.StatusConflict, "Invalid collection name."} } @@ -196,7 +196,7 @@ func (db *datastore) CreateUser(u *User, collectionTitle string) error { if collectionTitle == "" { collectionTitle = u.Username } - res, err = t.Exec("INSERT INTO collections (alias, title, description, privacy, owner_id, view_count) VALUES (?, ?, ?, ?, ?, ?)", u.Username, collectionTitle, "", CollUnlisted, u.ID, 0) + res, err = t.Exec("INSERT INTO collections (alias, title, description, privacy, owner_id, view_count) VALUES (?, ?, ?, ?, ?, ?)", u.Username, collectionTitle, "", defaultVisibility(app.cfg), u.ID, 0) if err != nil { t.Rollback() if db.isDuplicateKeyErr(err) { From 569bc792d0414a45016de61f25f1e879aba07a08 Mon Sep 17 00:00:00 2001 From: Matt Baer Date: Wed, 31 Jul 2019 22:20:00 -0400 Subject: [PATCH 05/12] Enable changing default_visibility from Admin dash Ref T675 --- admin.go | 1 + templates/user/admin.tmpl | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/admin.go b/admin.go index 99e1672..fe19ad5 100644 --- a/admin.go +++ b/admin.go @@ -391,6 +391,7 @@ func handleAdminUpdateConfig(apper Apper, u *User, w http.ResponseWriter, r *htt if apper.App().cfg.App.UserInvites == "none" { apper.App().cfg.App.UserInvites = "" } + apper.App().cfg.App.DefaultVisibility = r.FormValue("default_visibility") m := "?cm=Configuration+saved." err = apper.SaveConfig(apper.App().cfg) diff --git a/templates/user/admin.tmpl b/templates/user/admin.tmpl index 90b5d70..3cb81be 100644 --- a/templates/user/admin.tmpl +++ b/templates/user/admin.tmpl @@ -95,6 +95,14 @@ p.docs { +