From a75b45f060473b41d7fbd1c181d1919885cad0bf Mon Sep 17 00:00:00 2001 From: Matt Baer Date: Wed, 31 Jul 2019 22:18:40 -0400 Subject: [PATCH] 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) {