diff --git a/templates/user/admin/users.tmpl b/templates/user/admin/users.tmpl index 6d5d6f7..03a3f6c 100644 --- a/templates/user/admin/users.tmpl +++ b/templates/user/admin/users.tmpl @@ -1,36 +1,35 @@ {{define "users"}} {{template "header" .}}
{{template "admin-header" .}}

Users {{.TotalUsers}} total

{{range .Users}} + {{if .IsSuspended}}suspended{{else}}active{{end}} + {{end}}
User Joined Type Status
{{.Username}} {{.CreatedFriendly}} {{if .IsAdmin}}Admin{{else}}User{{end}} - {{if eq .Status 1}}suspended{{else}}active{{end}}
{{template "footer" .}} {{end}} diff --git a/templates/user/admin/view-user.tmpl b/templates/user/admin/view-user.tmpl index 01eb1f0..9226c39 100644 --- a/templates/user/admin/view-user.tmpl +++ b/templates/user/admin/view-user.tmpl @@ -1,119 +1,120 @@ {{define "view-user"}} {{template "header" .}}
{{template "admin-header" .}}

{{.User.Username}}

- {{if eq .User.Status 1}} - - {{else}} {{end}} +
No. {{.User.ID}}
Type {{if .User.IsAdmin}}Admin{{else}}User{{end}}
Username {{.User.Username}}
Joined {{.User.CreatedFriendly}}
Total Posts {{.TotalPosts}}
Last Post {{if .LastPost}}{{.LastPost}}{{else}}Never{{end}}
Status

User is currently Suspended

-

User is currently Active

+ {{if .User.IsSuspended}} +

Suspended

+ + {{else}} +

Active

-

Blogs

{{range .Colls}}

{{.Title}}

{{if $.Config.Federation}} {{end}}
Alias {{.Alias}}
Title {{.Title}}
Description {{.Description}}
Visibility {{.FriendlyVisibility}}
Views {{.Views}}
Posts {{.TotalPosts}}
Last Post {{if .LastPost}}{{.LastPost}}{{else}}Never{{end}}
Fediverse Followers {{.Followers}}
{{end}}
{{template "footer" .}} {{end}} diff --git a/users.go b/users.go index 05b5bb4..5eb2e61 100644 --- a/users.go +++ b/users.go @@ -1,128 +1,132 @@ /* * Copyright © 2018 A Bunch Tell LLC. * * This file is part of WriteFreely. * * WriteFreely is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License, included * in the LICENSE file in this source code package. */ package writefreely import ( "time" "github.com/guregu/null/zero" "github.com/writeas/web-core/data" "github.com/writeas/web-core/log" "github.com/writeas/writefreely/key" ) type UserStatus int const ( UserActive = iota UserSuspended ) type ( userCredentials struct { Alias string `json:"alias" schema:"alias"` Pass string `json:"pass" schema:"pass"` Email string `json:"email" schema:"email"` Web bool `json:"web" schema:"-"` To string `json:"-" schema:"to"` EmailLogin bool `json:"via_email" schema:"via_email"` } userRegistration struct { userCredentials InviteCode string `json:"invite_code" schema:"invite_code"` Honeypot string `json:"fullname" schema:"fullname"` Normalize bool `json:"normalize" schema:"normalize"` Signup bool `json:"signup" schema:"signup"` } // AuthUser contains information for a newly authenticated user (either // from signing up or logging in). AuthUser struct { AccessToken string `json:"access_token,omitempty"` Password string `json:"password,omitempty"` User *User `json:"user"` // Verbose user data Posts *[]PublicPost `json:"posts,omitempty"` Collections *[]Collection `json:"collections,omitempty"` } // User is a consistent user object in the database and all contexts (auth // and non-auth) in the API. User struct { ID int64 `json:"-"` Username string `json:"username"` HashedPass []byte `json:"-"` HasPass bool `json:"has_pass"` Email zero.String `json:"email"` Created time.Time `json:"created"` Status UserStatus `json:"status"` clearEmail string `json:"email"` } userMeStats struct { TotalCollections, TotalArticles, CollectionPosts uint64 } ExportUser struct { *User Collections *[]CollectionObj `json:"collections"` AnonymousPosts []PublicPost `json:"posts"` } PublicUser struct { Username string `json:"username"` } ) // EmailClear decrypts and returns the user's email, caching it in the user // object. func (u *User) EmailClear(keys *key.Keychain) string { if u.clearEmail != "" { return u.clearEmail } if u.Email.Valid && u.Email.String != "" { email, err := data.Decrypt(keys.EmailKey, []byte(u.Email.String)) if err != nil { log.Error("Error decrypting user email: %v", err) } else { u.clearEmail = string(email) return u.clearEmail } } return "" } func (u User) CreatedFriendly() string { /* // TODO: accept a locale in this method and use that for the format var loc monday.Locale = monday.LocaleEnUS return monday.Format(u.Created, monday.DateTimeFormatsByLocale[loc], loc) */ return u.Created.Format("January 2, 2006, 3:04 PM") } // Cookie strips down an AuthUser to contain only information necessary for // cookies. func (u User) Cookie() *User { u.HashedPass = []byte{} return &u } func (u *User) IsAdmin() bool { // TODO: get this from database return u.ID == 1 } + +func (u *User) IsSuspended() bool { + return u.Status&UserSuspended != 0 +}