From f85f0751a3a7480bc29450cf42a4360c31ff3083 Mon Sep 17 00:00:00 2001 From: Rob Loranger Date: Fri, 25 Oct 2019 12:04:24 -0700 Subject: [PATCH] address PR comments - update error messages to be correct - move suspended message into template and include for other pages - check suspended status on all relevant pages and show message if logged in user is suspended. - fix possible nil pointer error - remove changes to db schema files - add version comment to migration - add UserStatus type with UserActive and UserSuspended - change database table to use status column instead of suspended - update toggle suspended handler to be toggle status in prep for possible future inclusion of further user statuses --- account.go | 29 ++++++++++++++++++++++++++- activitypub.go | 10 ++++----- admin.go | 13 ++++++------ collections.go | 26 +++++++++++++----------- database.go | 29 ++++++++++++++------------- invites.go | 2 +- migrations/migrations.go | 2 +- migrations/v3.go | 4 ++-- posts.go | 22 +++++++++++--------- read.go | 2 +- routes.go | 2 +- schema.sql | 1 - sqlite.sql | 3 +-- templates.go | 12 +++++++---- templates/chorus-collection-post.tmpl | 3 +++ templates/chorus-collection.tmpl | 3 +++ templates/collection-post.tmpl | 3 +++ templates/collection-tags.tmpl | 3 +++ templates/collection.tmpl | 3 +++ templates/password-collection.tmpl | 3 +++ templates/post.tmpl | 3 +++ templates/user/admin/users.tmpl | 2 +- templates/user/admin/view-user.tmpl | 4 ++-- templates/user/articles.tmpl | 3 +++ templates/user/collection.tmpl | 3 +++ templates/user/collections.tmpl | 3 +++ templates/user/include/suspended.tmpl | 6 ++++++ templates/user/settings.tmpl | 9 +++------ templates/user/stats.tmpl | 3 +++ users.go | 9 ++++++++- 30 files changed, 148 insertions(+), 72 deletions(-) create mode 100644 templates/user/include/suspended.tmpl diff --git a/account.go b/account.go index c3d55ba..0faa7bb 100644 --- a/account.go +++ b/account.go @@ -750,14 +750,20 @@ func viewArticles(app *App, u *User, w http.ResponseWriter, r *http.Request) err log.Error("unable to fetch collections: %v", err) } + suspended, err := app.db.IsUserSuspended(u.ID) + if err != nil { + log.Error("view articles: %v", err) + } d := struct { *UserPage AnonymousPosts *[]PublicPost Collections *[]Collection + Suspended bool }{ UserPage: NewUserPage(app, r, u, u.Username+"'s Posts", f), AnonymousPosts: p, Collections: c, + Suspended: suspended, } d.UserPage.SetMessaging(u) w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") @@ -779,6 +785,11 @@ func viewCollections(app *App, u *User, w http.ResponseWriter, r *http.Request) uc, _ := app.db.GetUserCollectionCount(u.ID) // TODO: handle any errors + suspended, err := app.db.IsUserSuspended(u.ID) + if err != nil { + log.Error("view collections %v", err) + return fmt.Errorf("view collections: %v", err) + } d := struct { *UserPage Collections *[]Collection @@ -786,11 +797,13 @@ func viewCollections(app *App, u *User, w http.ResponseWriter, r *http.Request) UsedCollections, TotalCollections int NewBlogsDisabled bool + Suspended bool }{ UserPage: NewUserPage(app, r, u, u.Username+"'s Blogs", f), Collections: c, UsedCollections: int(uc), NewBlogsDisabled: !app.cfg.App.CanCreateBlogs(uc), + Suspended: suspended, } d.UserPage.SetMessaging(u) showUserPage(w, "collections", d) @@ -808,13 +821,20 @@ func viewEditCollection(app *App, u *User, w http.ResponseWriter, r *http.Reques return ErrCollectionNotFound } + suspended, err := app.db.IsUserSuspended(u.ID) + if err != nil { + log.Error("view edit collection %v", err) + return fmt.Errorf("view edit collection: %v", err) + } flashes, _ := getSessionFlashes(app, w, r, nil) obj := struct { *UserPage *Collection + Suspended bool }{ UserPage: NewUserPage(app, r, u, "Edit "+c.DisplayTitle(), flashes), Collection: c, + Suspended: suspended, } showUserPage(w, "collection", obj) @@ -976,17 +996,24 @@ func viewStats(app *App, u *User, w http.ResponseWriter, r *http.Request) error titleStats = c.DisplayTitle() + " " } + suspended, err := app.db.IsUserSuspended(u.ID) + if err != nil { + log.Error("view stats: %v", err) + return err + } obj := struct { *UserPage VisitsBlog string Collection *Collection TopPosts *[]PublicPost APFollowers int + Suspended bool }{ UserPage: NewUserPage(app, r, u, titleStats+"Stats", flashes), VisitsBlog: alias, Collection: c, TopPosts: topPosts, + Suspended: suspended, } if app.cfg.App.Federation { folls, err := app.db.GetAPFollowers(c) @@ -1026,7 +1053,7 @@ func viewSettings(app *App, u *User, w http.ResponseWriter, r *http.Request) err Email: fullUser.EmailClear(app.keys), HasPass: passIsSet, IsLogOut: r.FormValue("logout") == "1", - Suspended: fullUser.Suspended, + Suspended: fullUser.Status == UserSuspended, } showUserPage(w, "settings", obj) diff --git a/activitypub.go b/activitypub.go index 06b0468..eeaa1fa 100644 --- a/activitypub.go +++ b/activitypub.go @@ -82,7 +82,7 @@ func handleFetchCollectionActivities(app *App, w http.ResponseWriter, r *http.Re } suspended, err := app.db.IsUserSuspended(c.OwnerID) if err != nil { - log.Error("fetch collection inbox: get owner: %v", err) + log.Error("fetch collection activities: %v", err) return ErrInternalGeneral } if suspended { @@ -115,7 +115,7 @@ func handleFetchCollectionOutbox(app *App, w http.ResponseWriter, r *http.Reques } suspended, err := app.db.IsUserSuspended(c.OwnerID) if err != nil { - log.Error("fetch collection inbox: get owner: %v", err) + log.Error("fetch collection outbox: %v", err) return ErrInternalGeneral } if suspended { @@ -176,7 +176,7 @@ func handleFetchCollectionFollowers(app *App, w http.ResponseWriter, r *http.Req } suspended, err := app.db.IsUserSuspended(c.OwnerID) if err != nil { - log.Error("fetch collection inbox: get owner: %v", err) + log.Error("fetch collection followers: %v", err) return ErrInternalGeneral } if suspended { @@ -230,7 +230,7 @@ func handleFetchCollectionFollowing(app *App, w http.ResponseWriter, r *http.Req } suspended, err := app.db.IsUserSuspended(c.OwnerID) if err != nil { - log.Error("fetch collection inbox: get owner: %v", err) + log.Error("fetch collection following: %v", err) return ErrInternalGeneral } if suspended { @@ -272,7 +272,7 @@ func handleFetchCollectionInbox(app *App, w http.ResponseWriter, r *http.Request } suspended, err := app.db.IsUserSuspended(c.OwnerID) if err != nil { - log.Error("fetch collection inbox: get owner: %v", err) + log.Error("fetch collection inbox: %v", err) return ErrInternalGeneral } if suspended { diff --git a/admin.go b/admin.go index 1d94987..65afd5f 100644 --- a/admin.go +++ b/admin.go @@ -230,28 +230,27 @@ func handleViewAdminUser(app *App, u *User, w http.ResponseWriter, r *http.Reque return nil } -func handleAdminToggleUserSuspended(app *App, u *User, w http.ResponseWriter, r *http.Request) error { +func handleAdminToggleUserStatus(app *App, u *User, w http.ResponseWriter, r *http.Request) error { vars := mux.Vars(r) username := vars["username"] if username == "" { return impart.HTTPError{http.StatusFound, "/admin/users"} } - userToToggle, err := app.db.GetUserForAuth(username) + user, err := app.db.GetUserForAuth(username) if err != nil { log.Error("failed to get user: %v", err) return impart.HTTPError{http.StatusInternalServerError, fmt.Sprintf("Could not get user from username: %v", err)} } - if userToToggle.Suspended { - err = app.db.SetUserSuspended(userToToggle.ID, false) + if user.Status == UserSuspended { + err = app.db.SetUserStatus(user.ID, UserActive) } else { - err = app.db.SetUserSuspended(userToToggle.ID, true) + err = app.db.SetUserStatus(user.ID, UserSuspended) } if err != nil { log.Error("toggle user suspended: %v", err) - return impart.HTTPError{http.StatusInternalServerError, fmt.Sprintf("Could not toggle user suspended: %v")} + return impart.HTTPError{http.StatusInternalServerError, fmt.Sprintf("Could not toggle user status: %v")} } - // TODO: invalidate sessions return impart.HTTPError{http.StatusFound, fmt.Sprintf("/admin/user/%s#status", username)} } diff --git a/collections.go b/collections.go index c4cefeb..38ec6f1 100644 --- a/collections.go +++ b/collections.go @@ -71,6 +71,7 @@ type ( CurrentPage int TotalPages int Format *CollectionFormat + Suspended bool } SubmittedCollection struct { // Data used for updating a given collection @@ -398,7 +399,7 @@ func newCollection(app *App, w http.ResponseWriter, r *http.Request) error { } suspended, err := app.db.IsUserSuspended(userID) if err != nil { - log.Error("new collection: get user: %v", err) + log.Error("new collection: %v", err) return ErrInternalGeneral } if suspended { @@ -486,6 +487,7 @@ func fetchCollection(app *App, w http.ResponseWriter, r *http.Request) error { res.Owner = u } } + // TODO: check suspended app.db.GetPostsCount(res, isCollOwner) // Strip non-public information res.Collection.ForPublic() @@ -738,14 +740,10 @@ func handleViewCollection(app *App, w http.ResponseWriter, r *http.Request) erro suspended, err := app.db.IsUserSuspended(c.OwnerID) if err != nil { - log.Error("view collection: get owner: %v", err) + log.Error("view collection: %v", err) return ErrInternalGeneral } - if suspended { - return ErrCollectionNotFound - } - // Serve ActivityStreams data now, if requested if strings.Contains(r.Header.Get("Accept"), "application/activity+json") { ac := c.PersonObject() @@ -802,6 +800,10 @@ func handleViewCollection(app *App, w http.ResponseWriter, r *http.Request) erro log.Error("Error getting user for collection: %v", err) } } + if !isOwner && suspended { + return ErrCollectionNotFound + } + displayPage.Suspended = isOwner && suspended displayPage.Owner = owner coll.Owner = displayPage.Owner @@ -853,10 +855,6 @@ func handleViewCollectionTag(app *App, w http.ResponseWriter, r *http.Request) e return err } - if u.Suspended { - return ErrCollectionNotFound - } - page := getCollectionPage(vars) c, err := processCollectionPermissions(app, cr, u, w, r) @@ -908,6 +906,10 @@ func handleViewCollectionTag(app *App, w http.ResponseWriter, r *http.Request) e log.Error("Error getting user for collection: %v", err) } } + if !isOwner && u.Status == UserSuspended { + return ErrCollectionNotFound + } + displayPage.Suspended = u.Status == UserSuspended displayPage.Owner = owner coll.Owner = displayPage.Owner // Add more data @@ -946,7 +948,7 @@ func existingCollection(app *App, w http.ResponseWriter, r *http.Request) error collAlias := vars["alias"] isWeb := r.FormValue("web") == "1" - var u *User + u := &User{} if reqJSON && !isWeb { // Ensure an access token was given accessToken := r.Header.Get("Authorization") @@ -963,7 +965,7 @@ func existingCollection(app *App, w http.ResponseWriter, r *http.Request) error suspended, err := app.db.IsUserSuspended(u.ID) if err != nil { - log.Error("existing collection: get user suspended status: %v", err) + log.Error("existing collection: %v", err) return ErrInternalGeneral } diff --git a/database.go b/database.go index b465e68..4b0c702 100644 --- a/database.go +++ b/database.go @@ -296,7 +296,7 @@ func (db *datastore) CreateCollection(cfg *config.Config, alias, title string, u func (db *datastore) GetUserByID(id int64) (*User, error) { u := &User{ID: id} - err := db.QueryRow("SELECT username, password, email, created, suspended FROM users WHERE id = ?", id).Scan(&u.Username, &u.HashedPass, &u.Email, &u.Created, &u.Suspended) + err := db.QueryRow("SELECT username, password, email, created, status FROM users WHERE id = ?", id).Scan(&u.Username, &u.HashedPass, &u.Email, &u.Created, &u.Status) switch { case err == sql.ErrNoRows: return nil, ErrUserNotFound @@ -313,16 +313,16 @@ func (db *datastore) GetUserByID(id int64) (*User, error) { func (db *datastore) IsUserSuspended(id int64) (bool, error) { u := &User{ID: id} - err := db.QueryRow("SELECT suspended FROM users WHERE id = ?", id).Scan(&u.Suspended) + err := db.QueryRow("SELECT status FROM users WHERE id = ?", id).Scan(&u.Status) switch { case err == sql.ErrNoRows: - return false, ErrUserNotFound + return false, fmt.Errorf("is user suspended: %v", ErrUserNotFound) case err != nil: log.Error("Couldn't SELECT user password: %v", err) - return false, err + return false, fmt.Errorf("is user suspended: %v", err) } - return u.Suspended, nil + return u.Status == UserSuspended, nil } // DoesUserNeedAuth returns true if the user hasn't provided any methods for @@ -364,7 +364,7 @@ func (db *datastore) IsUserPassSet(id int64) (bool, error) { func (db *datastore) GetUserForAuth(username string) (*User, error) { u := &User{Username: username} - err := db.QueryRow("SELECT id, password, email, created, suspended FROM users WHERE username = ?", username).Scan(&u.ID, &u.HashedPass, &u.Email, &u.Created, &u.Suspended) + err := db.QueryRow("SELECT id, password, email, created, status FROM users WHERE username = ?", username).Scan(&u.ID, &u.HashedPass, &u.Email, &u.Created, &u.Status) switch { case err == sql.ErrNoRows: // Check if they've entered the wrong, unnormalized username @@ -387,7 +387,7 @@ func (db *datastore) GetUserForAuth(username string) (*User, error) { func (db *datastore) GetUserForAuthByID(userID int64) (*User, error) { u := &User{ID: userID} - err := db.QueryRow("SELECT id, password, email, created, suspended FROM users WHERE id = ?", u.ID).Scan(&u.ID, &u.HashedPass, &u.Email, &u.Created, &u.Suspended) + err := db.QueryRow("SELECT id, password, email, created, status FROM users WHERE id = ?", u.ID).Scan(&u.ID, &u.HashedPass, &u.Email, &u.Created, &u.Status) switch { case err == sql.ErrNoRows: return nil, ErrUserNotFound @@ -1650,7 +1650,7 @@ func (db *datastore) GetTotalCollections() (collCount int64, err error) { SELECT COUNT(*) FROM collections c LEFT JOIN users u ON u.id = c.owner_id - WHERE u.suspended = 0`).Scan(&collCount) + WHERE u.status = 0`).Scan(&collCount) if err != nil { log.Error("Unable to fetch collections count: %v", err) } @@ -1662,7 +1662,7 @@ func (db *datastore) GetTotalPosts() (postCount int64, err error) { SELECT COUNT(*) FROM posts p LEFT JOIN users u ON u.id = p.owner_id - WHERE u.Suspended = 0`).Scan(&postCount) + WHERE u.status = 0`).Scan(&postCount) if err != nil { log.Error("Unable to fetch posts count: %v", err) } @@ -2384,7 +2384,7 @@ func (db *datastore) GetAllUsers(page uint) (*[]User, error) { limitStr = fmt.Sprintf("%d, %d", (page-1)*adminUsersPerPage, adminUsersPerPage) } - rows, err := db.Query("SELECT id, username, created, suspended FROM users ORDER BY created DESC LIMIT " + limitStr) + rows, err := db.Query("SELECT id, username, created, status FROM users ORDER BY created DESC LIMIT " + limitStr) if err != nil { log.Error("Failed selecting from users: %v", err) return nil, impart.HTTPError{http.StatusInternalServerError, "Couldn't retrieve all users."} @@ -2394,7 +2394,7 @@ func (db *datastore) GetAllUsers(page uint) (*[]User, error) { users := []User{} for rows.Next() { u := User{} - err = rows.Scan(&u.ID, &u.Username, &u.Created, &u.Suspended) + err = rows.Scan(&u.ID, &u.Username, &u.Created, &u.Status) if err != nil { log.Error("Failed scanning GetAllUsers() row: %v", err) break @@ -2431,10 +2431,11 @@ func (db *datastore) GetUserLastPostTime(id int64) (*time.Time, error) { return &t, nil } -func (db *datastore) SetUserSuspended(id int64, suspend bool) error { - _, err := db.Exec("UPDATE users SET suspended = ? WHERE id = ?", suspend, id) +// SetUserStatus changes a user's status in the database. see Users.UserStatus +func (db *datastore) SetUserStatus(id int64, status UserStatus) error { + _, err := db.Exec("UPDATE users SET status = ? WHERE id = ?", status, id) if err != nil { - return fmt.Errorf("failed to update user suspended status: %v", err) + return fmt.Errorf("failed to update user status: %v", err) } return nil } diff --git a/invites.go b/invites.go index adff49a..8f341ec 100644 --- a/invites.go +++ b/invites.go @@ -78,7 +78,7 @@ func handleCreateUserInvite(app *App, u *User, w http.ResponseWriter, r *http.Re muVal := r.FormValue("uses") expVal := r.FormValue("expires") - if u.Suspended { + if u.Status == UserSuspended { return ErrUserSuspended } diff --git a/migrations/migrations.go b/migrations/migrations.go index de3f487..0799f8e 100644 --- a/migrations/migrations.go +++ b/migrations/migrations.go @@ -58,7 +58,7 @@ func (m *migration) Migrate(db *datastore) error { var migrations = []Migration{ New("support user invites", supportUserInvites), // -> V1 (v0.8.0) New("support dynamic instance pages", supportInstancePages), // V1 -> V2 (v0.9.0) - New("support users suspension", supportUserSuspension), // V2 -> V3 () + New("support users suspension", supportUserStatus), // V2 -> V3 (v0.11.0) } // CurrentVer returns the current migration version the application is on diff --git a/migrations/v3.go b/migrations/v3.go index c7c00a9..b5351da 100644 --- a/migrations/v3.go +++ b/migrations/v3.go @@ -10,10 +10,10 @@ package migrations -func supportUserSuspension(db *datastore) error { +func supportUserStatus(db *datastore) error { t, err := db.Begin() - _, err = t.Exec(`ALTER TABLE users ADD COLUMN suspended ` + db.typeBool() + ` DEFAULT '0' NOT NULL`) + _, err = t.Exec(`ALTER TABLE users ADD COLUMN status ` + db.typeInt() + ` DEFAULT '0' NOT NULL`) if err != nil { t.Rollback() return err diff --git a/posts.go b/posts.go index 33d4638..15d93c8 100644 --- a/posts.go +++ b/posts.go @@ -383,7 +383,7 @@ func handleViewPost(app *App, w http.ResponseWriter, r *http.Request) error { suspended, err := app.db.IsUserSuspended(ownerID.Int64) if err != nil { - log.Error("view post: get collection owner: %v", err) + log.Error("view post: %v", err) return ErrInternalGeneral } @@ -509,7 +509,7 @@ func newPost(app *App, w http.ResponseWriter, r *http.Request) error { } suspended, err := app.db.IsUserSuspended(userID) if err != nil { - log.Error("new post: get user: %v", err) + log.Error("new post: %v", err) return ErrInternalGeneral } if suspended { @@ -683,7 +683,7 @@ func existingPost(app *App, w http.ResponseWriter, r *http.Request) error { suspended, err := app.db.IsUserSuspended(userID) if err != nil { - log.Error("existing post: get user: %v", err) + log.Error("existing post: %v", err) return ErrInternalGeneral } if suspended { @@ -886,7 +886,7 @@ func addPost(app *App, w http.ResponseWriter, r *http.Request) error { suspended, err := app.db.IsUserSuspended(ownerID) if err != nil { - log.Error("add post: get user: %v", err) + log.Error("add post: %v", err) return ErrInternalGeneral } if suspended { @@ -989,7 +989,7 @@ func pinPost(app *App, w http.ResponseWriter, r *http.Request) error { suspended, err := app.db.IsUserSuspended(userID) if err != nil { - log.Error("pin post: get user: %v", err) + log.Error("pin post: %v", err) return ErrInternalGeneral } if suspended { @@ -1063,7 +1063,7 @@ func fetchPost(app *App, w http.ResponseWriter, r *http.Request) error { } suspended, err := app.db.IsUserSuspended(ownerID) if err != nil { - log.Error("fetch post: get owner: %v", err) + log.Error("fetch post: %v", err) return ErrInternalGeneral } @@ -1333,13 +1333,10 @@ func viewCollectionPost(app *App, w http.ResponseWriter, r *http.Request) error suspended, err := app.db.IsUserSuspended(c.OwnerID) if err != nil { - log.Error("view collection post: get owner: %v", err) + log.Error("view collection post: %v", err) return ErrInternalGeneral } - if suspended { - return ErrPostNotFound - } // Check collection permissions if c.IsPrivate() && (u == nil || u.ID != c.OwnerID) { return ErrPostNotFound @@ -1396,6 +1393,9 @@ Are you sure it was ever here?`, p.Collection = coll p.IsTopLevel = app.cfg.App.SingleUser + if !p.IsOwner && suspended { + return ErrPostNotFound + } // Check if post has been unpublished if p.Content == "" && p.Title.String == "" { return impart.HTTPError{http.StatusGone, "Post was unpublished."} @@ -1445,12 +1445,14 @@ Are you sure it was ever here?`, IsFound bool IsAdmin bool CanInvite bool + Suspended bool }{ PublicPost: p, StaticPage: pageForReq(app, r), IsOwner: cr.isCollOwner, IsCustomDomain: cr.isCustomDomain, IsFound: postFound, + Suspended: suspended, } tp.IsAdmin = u != nil && u.IsAdmin() tp.CanInvite = canUserInvite(app.cfg, tp.IsAdmin) diff --git a/read.go b/read.go index 86664b5..6d0c8a7 100644 --- a/read.go +++ b/read.go @@ -71,7 +71,7 @@ func (app *App) FetchPublicPosts() (interface{}, error) { FROM collections c LEFT JOIN posts p ON p.collection_id = c.id LEFT JOIN users u ON u.id = p.owner_id - WHERE c.privacy = 1 AND (p.created >= ` + app.db.dateSub(3, "month") + ` AND p.created <= ` + app.db.now() + ` AND pinned_position IS NULL) AND u.suspended = 0 + WHERE c.privacy = 1 AND (p.created >= ` + app.db.dateSub(3, "month") + ` AND p.created <= ` + app.db.now() + ` AND pinned_position IS NULL) AND u.status = 0 ORDER BY p.created DESC`) if err != nil { log.Error("Failed selecting from posts: %v", err) diff --git a/routes.go b/routes.go index 510a539..1ff250f 100644 --- a/routes.go +++ b/routes.go @@ -144,7 +144,7 @@ func InitRoutes(apper Apper, r *mux.Router) *mux.Router { write.HandleFunc("/admin", handler.Admin(handleViewAdminDash)).Methods("GET") write.HandleFunc("/admin/users", handler.Admin(handleViewAdminUsers)).Methods("GET") write.HandleFunc("/admin/user/{username}", handler.Admin(handleViewAdminUser)).Methods("GET") - write.HandleFunc("/admin/user/{username}", handler.Admin(handleAdminToggleUserSuspended)).Methods("POST") + write.HandleFunc("/admin/user/{username}/status", handler.Admin(handleAdminToggleUserStatus)).Methods("POST") write.HandleFunc("/admin/pages", handler.Admin(handleViewAdminPages)).Methods("GET") write.HandleFunc("/admin/page/{slug}", handler.Admin(handleViewAdminPage)).Methods("GET") write.HandleFunc("/admin/update/config", handler.AdminApper(handleAdminUpdateConfig)).Methods("POST") diff --git a/schema.sql b/schema.sql index 3a79736..b3fae97 100644 --- a/schema.sql +++ b/schema.sql @@ -225,7 +225,6 @@ CREATE TABLE IF NOT EXISTS `users` ( `password` char(60) CHARACTER SET latin1 COLLATE latin1_bin NOT NULL, `email` varbinary(255) DEFAULT NULL, `created` datetime NOT NULL DEFAULT CURRENT_TIMESTAMP, - `suspended` tinyint(1) NOT NULL DEFAULT 0, PRIMARY KEY (`id`), UNIQUE KEY `username` (`username`) ) ENGINE=InnoDB DEFAULT CHARSET=latin1; diff --git a/sqlite.sql b/sqlite.sql index 920ffed..90989ed 100644 --- a/sqlite.sql +++ b/sqlite.sql @@ -214,8 +214,7 @@ CREATE TABLE IF NOT EXISTS `users` ( username TEXT NOT NULL UNIQUE, password TEXT NOT NULL, email TEXT DEFAULT NULL, - created DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP, - suspended INTEGER NOT NULL DEFAULT 0 + created DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ); -- -------------------------------------------------------- diff --git a/templates.go b/templates.go index 6e9a008..968845d 100644 --- a/templates.go +++ b/templates.go @@ -11,10 +11,6 @@ package writefreely import ( - "github.com/dustin/go-humanize" - "github.com/writeas/web-core/l10n" - "github.com/writeas/web-core/log" - "github.com/writeas/writefreely/config" "html/template" "io" "io/ioutil" @@ -22,6 +18,11 @@ import ( "os" "path/filepath" "strings" + + "github.com/dustin/go-humanize" + "github.com/writeas/web-core/l10n" + "github.com/writeas/web-core/log" + "github.com/writeas/writefreely/config" ) var ( @@ -63,6 +64,7 @@ func initTemplate(parentDir, name string) { filepath.Join(parentDir, templatesDir, name+".tmpl"), filepath.Join(parentDir, templatesDir, "include", "footer.tmpl"), filepath.Join(parentDir, templatesDir, "base.tmpl"), + filepath.Join(parentDir, templatesDir, "user", "include", "suspended.tmpl"), } if name == "collection" || name == "collection-tags" || name == "chorus-collection" { // These pages list out collection posts, so we also parse templatesDir + "include/posts.tmpl" @@ -86,6 +88,7 @@ func initPage(parentDir, path, key string) { path, filepath.Join(parentDir, templatesDir, "include", "footer.tmpl"), filepath.Join(parentDir, templatesDir, "base.tmpl"), + filepath.Join(parentDir, templatesDir, "user", "include", "suspended.tmpl"), )) } @@ -98,6 +101,7 @@ func initUserPage(parentDir, path, key string) { path, filepath.Join(parentDir, templatesDir, "user", "include", "header.tmpl"), filepath.Join(parentDir, templatesDir, "user", "include", "footer.tmpl"), + filepath.Join(parentDir, templatesDir, "user", "include", "suspended.tmpl"), )) } diff --git a/templates/chorus-collection-post.tmpl b/templates/chorus-collection-post.tmpl index bab2e31..58e514f 100644 --- a/templates/chorus-collection-post.tmpl +++ b/templates/chorus-collection-post.tmpl @@ -65,6 +65,9 @@ article time.dt-published { {{template "user-navigation" .}} + {{if .Suspended}} + {{template "user-suspended"}} + {{end}}
{{if .IsScheduled}}

Scheduled

{{end}}{{if .Title.String}}

{{.FormattedDisplayTitle}}

{{end}}{{/* TODO: check format: if .Collection.Format.ShowDates*/}}
{{.HTMLContent}}
{{ if .Collection.ShowFooterBranding }} diff --git a/templates/chorus-collection.tmpl b/templates/chorus-collection.tmpl index e36d3b5..5f4d418 100644 --- a/templates/chorus-collection.tmpl +++ b/templates/chorus-collection.tmpl @@ -61,6 +61,9 @@ body#collection header nav.tabs a:first-child { {{template "user-navigation" .}} + {{if .Suspended}} + {{template "user-suspended"}} + {{end}}

{{.DisplayTitle}}

{{if .Description}}

{{.Description}}

{{end}} diff --git a/templates/collection-post.tmpl b/templates/collection-post.tmpl index 7075226..4398804 100644 --- a/templates/collection-post.tmpl +++ b/templates/collection-post.tmpl @@ -59,6 +59,9 @@
+ {{if .Suspended}} + {{template "user-suspended"}} + {{end}}
{{if .IsScheduled}}

Scheduled

{{end}}{{if .Title.String}}

{{.FormattedDisplayTitle}}

{{end}}
{{.HTMLContent}}
{{ if .Collection.ShowFooterBranding }} diff --git a/templates/collection-tags.tmpl b/templates/collection-tags.tmpl index 7cad3b7..5e2e2d3 100644 --- a/templates/collection-tags.tmpl +++ b/templates/collection-tags.tmpl @@ -53,6 +53,9 @@ + {{if .Suspended}} + {{template "user-suspended"}} + {{end}} {{if .Posts}}
{{else}}
{{end}}

{{.Tag}}

{{template "posts" .}} diff --git a/templates/collection.tmpl b/templates/collection.tmpl index 36a266b..5a33bba 100644 --- a/templates/collection.tmpl +++ b/templates/collection.tmpl @@ -62,6 +62,9 @@ {{end}}
+ {{if .Suspended}} + {{template "user-suspended"}} + {{end}}

{{if .Posts}}{{else}}write.as {{end}}{{.DisplayTitle}}

{{if .Description}}

{{.Description}}

{{end}} {{/*if not .Public/*}} diff --git a/templates/password-collection.tmpl b/templates/password-collection.tmpl index e0b755d..73c4465 100644 --- a/templates/password-collection.tmpl +++ b/templates/password-collection.tmpl @@ -25,6 +25,9 @@ + {{if .Suspended}} + {{template "user-supsended"}} + {{end}}

{{.DisplayTitle}}

diff --git a/templates/post.tmpl b/templates/post.tmpl index dd1375e..74135a3 100644 --- a/templates/post.tmpl +++ b/templates/post.tmpl @@ -36,6 +36,9 @@ + {{if .Suspended}} + {{template "user-suspended"}} + {{end}}

{{.SiteName}}