Browse Source

Make App struct public

pull/102/head
Matt Baer 2 years ago
parent
commit
d8937e89a8
  1. 52
      account.go
  2. 20
      activitypub.go
  3. 18
      admin.go
  4. 39
      app.go
  5. 24
      collections.go
  6. 4
      database.go
  7. 4
      export.go
  8. 4
      feed.go
  9. 18
      handle.go
  10. 4
      hostmeta.go
  11. 6
      invites.go
  12. 6
      keys.go
  13. 6
      pad.go
  14. 6
      pages.go
  15. 26
      posts.go
  16. 14
      read.go
  17. 16
      session.go
  18. 4
      sitemap.go
  19. 8
      unregisteredusers.go

52
account.go

@ -1,5 +1,5 @@
/*
* Copyright © 2018 A Bunch Tell LLC.
* Copyright © 2018-2019 A Bunch Tell LLC.
*
* This file is part of WriteFreely.
*
@ -49,7 +49,7 @@ type (
}
)
func NewUserPage(app *app, r *http.Request, u *User, title string, flashes []string) *UserPage {
func NewUserPage(app *App, r *http.Request, u *User, title string, flashes []string) *UserPage {
up := &UserPage{
StaticPage: pageForReq(app, r),
PageTitle: title,
@ -73,12 +73,12 @@ const (
var actuallyUsernameReg = regexp.MustCompile("username is actually ([a-z0-9\\-]+)\\. Please try that, instead")
func apiSignup(app *app, w http.ResponseWriter, r *http.Request) error {
func apiSignup(app *App, w http.ResponseWriter, r *http.Request) error {
_, err := signup(app, w, r)
return err
}
func signup(app *app, w http.ResponseWriter, r *http.Request) (*AuthUser, error) {
func signup(app *App, w http.ResponseWriter, r *http.Request) (*AuthUser, error) {
reqJSON := IsJSON(r.Header.Get("Content-Type"))
// Get params
@ -113,7 +113,7 @@ func signup(app *app, w http.ResponseWriter, r *http.Request) (*AuthUser, error)
return signupWithRegistration(app, ur, w, r)
}
func signupWithRegistration(app *app, signup userRegistration, w http.ResponseWriter, r *http.Request) (*AuthUser, error) {
func signupWithRegistration(app *App, signup userRegistration, w http.ResponseWriter, r *http.Request) (*AuthUser, error) {
reqJSON := IsJSON(r.Header.Get("Content-Type"))
// Validate required params (alias)
@ -229,7 +229,7 @@ func signupWithRegistration(app *app, signup userRegistration, w http.ResponseWr
return resUser, nil
}
func viewLogout(app *app, w http.ResponseWriter, r *http.Request) error {
func viewLogout(app *App, w http.ResponseWriter, r *http.Request) error {
session, err := app.sessionStore.Get(r, cookieName)
if err != nil {
return ErrInternalCookieSession
@ -268,7 +268,7 @@ func viewLogout(app *app, w http.ResponseWriter, r *http.Request) error {
return impart.HTTPError{http.StatusFound, "/"}
}
func handleAPILogout(app *app, w http.ResponseWriter, r *http.Request) error {
func handleAPILogout(app *App, w http.ResponseWriter, r *http.Request) error {
accessToken := r.Header.Get("Authorization")
if accessToken == "" {
return ErrNoAccessToken
@ -284,7 +284,7 @@ func handleAPILogout(app *app, w http.ResponseWriter, r *http.Request) error {
return impart.HTTPError{Status: http.StatusNoContent}
}
func viewLogin(app *app, w http.ResponseWriter, r *http.Request) error {
func viewLogin(app *App, w http.ResponseWriter, r *http.Request) error {
var earlyError string
oneTimeToken := r.FormValue("with")
if oneTimeToken != "" {
@ -333,7 +333,7 @@ func viewLogin(app *app, w http.ResponseWriter, r *http.Request) error {
return nil
}
func webLogin(app *app, w http.ResponseWriter, r *http.Request) error {
func webLogin(app *App, w http.ResponseWriter, r *http.Request) error {
err := login(app, w, r)
if err != nil {
username := r.FormValue("alias")
@ -370,7 +370,7 @@ func webLogin(app *app, w http.ResponseWriter, r *http.Request) error {
var loginAttemptUsers = sync.Map{}
func login(app *app, w http.ResponseWriter, r *http.Request) error {
func login(app *App, w http.ResponseWriter, r *http.Request) error {
reqJSON := IsJSON(r.Header.Get("Content-Type"))
oneTimeToken := r.FormValue("with")
verbose := r.FormValue("all") == "true" || r.FormValue("verbose") == "1" || r.FormValue("verbose") == "true" || (reqJSON && oneTimeToken != "")
@ -534,7 +534,7 @@ func login(app *app, w http.ResponseWriter, r *http.Request) error {
return nil
}
func getVerboseAuthUser(app *app, token string, u *User, verbose bool) *AuthUser {
func getVerboseAuthUser(app *App, token string, u *User, verbose bool) *AuthUser {
resUser := &AuthUser{
AccessToken: token,
User: u,
@ -563,7 +563,7 @@ func getVerboseAuthUser(app *app, token string, u *User, verbose bool) *AuthUser
return resUser
}
func viewExportOptions(app *app, u *User, w http.ResponseWriter, r *http.Request) error {
func viewExportOptions(app *App, u *User, w http.ResponseWriter, r *http.Request) error {
// Fetch extra user data
p := NewUserPage(app, r, u, "Export", nil)
@ -571,7 +571,7 @@ func viewExportOptions(app *app, u *User, w http.ResponseWriter, r *http.Request
return nil
}
func viewExportPosts(app *app, w http.ResponseWriter, r *http.Request) ([]byte, string, error) {
func viewExportPosts(app *App, w http.ResponseWriter, r *http.Request) ([]byte, string, error) {
var filename string
var u = &User{}
reqJSON := IsJSON(r.Header.Get("Content-Type"))
@ -635,7 +635,7 @@ func viewExportPosts(app *app, w http.ResponseWriter, r *http.Request) ([]byte,
return data, filename, err
}
func viewExportFull(app *app, w http.ResponseWriter, r *http.Request) ([]byte, string, error) {
func viewExportFull(app *App, w http.ResponseWriter, r *http.Request) ([]byte, string, error) {
var err error
filename := ""
u := getUserSession(app, r)
@ -655,7 +655,7 @@ func viewExportFull(app *app, w http.ResponseWriter, r *http.Request) ([]byte, s
return data, filename, err
}
func viewMeAPI(app *app, w http.ResponseWriter, r *http.Request) error {
func viewMeAPI(app *App, w http.ResponseWriter, r *http.Request) error {
reqJSON := IsJSON(r.Header.Get("Content-Type"))
uObj := struct {
ID int64 `json:"id,omitempty"`
@ -679,7 +679,7 @@ func viewMeAPI(app *app, w http.ResponseWriter, r *http.Request) error {
return impart.WriteSuccess(w, uObj, http.StatusOK)
}
func viewMyPostsAPI(app *app, u *User, w http.ResponseWriter, r *http.Request) error {
func viewMyPostsAPI(app *App, u *User, w http.ResponseWriter, r *http.Request) error {
reqJSON := IsJSON(r.Header.Get("Content-Type"))
if !reqJSON {
return ErrBadRequestedType
@ -710,7 +710,7 @@ func viewMyPostsAPI(app *app, u *User, w http.ResponseWriter, r *http.Request) e
return impart.WriteSuccess(w, p, http.StatusOK)
}
func viewMyCollectionsAPI(app *app, u *User, w http.ResponseWriter, r *http.Request) error {
func viewMyCollectionsAPI(app *App, u *User, w http.ResponseWriter, r *http.Request) error {
reqJSON := IsJSON(r.Header.Get("Content-Type"))
if !reqJSON {
return ErrBadRequestedType
@ -724,7 +724,7 @@ func viewMyCollectionsAPI(app *app, u *User, w http.ResponseWriter, r *http.Requ
return impart.WriteSuccess(w, p, http.StatusOK)
}
func viewArticles(app *app, u *User, w http.ResponseWriter, r *http.Request) error {
func viewArticles(app *App, u *User, w http.ResponseWriter, r *http.Request) error {
p, err := app.db.GetAnonymousPosts(u)
if err != nil {
log.Error("unable to fetch anon posts: %v", err)
@ -761,7 +761,7 @@ func viewArticles(app *app, u *User, w http.ResponseWriter, r *http.Request) err
return nil
}
func viewCollections(app *app, u *User, w http.ResponseWriter, r *http.Request) error {
func viewCollections(app *App, u *User, w http.ResponseWriter, r *http.Request) error {
c, err := app.db.GetCollections(u)
if err != nil {
log.Error("unable to fetch collections: %v", err)
@ -792,7 +792,7 @@ func viewCollections(app *app, u *User, w http.ResponseWriter, r *http.Request)
return nil
}
func viewEditCollection(app *app, u *User, w http.ResponseWriter, r *http.Request) error {
func viewEditCollection(app *App, u *User, w http.ResponseWriter, r *http.Request) error {
vars := mux.Vars(r)
c, err := app.db.GetCollection(vars["collection"])
if err != nil {
@ -815,7 +815,7 @@ func viewEditCollection(app *app, u *User, w http.ResponseWriter, r *http.Reques
return nil
}
func updateSettings(app *app, w http.ResponseWriter, r *http.Request) error {
func updateSettings(app *App, w http.ResponseWriter, r *http.Request) error {
reqJSON := IsJSON(r.Header.Get("Content-Type"))
var s userSettings
@ -904,7 +904,7 @@ func updateSettings(app *app, w http.ResponseWriter, r *http.Request) error {
return nil
}
func updatePassphrase(app *app, w http.ResponseWriter, r *http.Request) error {
func updatePassphrase(app *App, w http.ResponseWriter, r *http.Request) error {
accessToken := r.Header.Get("Authorization")
if accessToken == "" {
return ErrNoAccessToken
@ -943,7 +943,7 @@ func updatePassphrase(app *app, w http.ResponseWriter, r *http.Request) error {
return impart.WriteSuccess(w, struct{}{}, http.StatusOK)
}
func viewStats(app *app, u *User, w http.ResponseWriter, r *http.Request) error {
func viewStats(app *App, u *User, w http.ResponseWriter, r *http.Request) error {
var c *Collection
var err error
vars := mux.Vars(r)
@ -994,7 +994,7 @@ func viewStats(app *app, u *User, w http.ResponseWriter, r *http.Request) error
return nil
}
func viewSettings(app *app, u *User, w http.ResponseWriter, r *http.Request) error {
func viewSettings(app *App, u *User, w http.ResponseWriter, r *http.Request) error {
fullUser, err := app.db.GetUserByID(u.ID)
if err != nil {
log.Error("Unable to get user for settings: %s", err)
@ -1025,7 +1025,7 @@ func viewSettings(app *app, u *User, w http.ResponseWriter, r *http.Request) err
return nil
}
func saveTempInfo(app *app, key, val string, r *http.Request, w http.ResponseWriter) error {
func saveTempInfo(app *App, key, val string, r *http.Request, w http.ResponseWriter) error {
session, err := app.sessionStore.Get(r, "t")
if err != nil {
return ErrInternalCookieSession
@ -1039,7 +1039,7 @@ func saveTempInfo(app *app, key, val string, r *http.Request, w http.ResponseWri
return err
}
func getTempInfo(app *app, key string, r *http.Request, w http.ResponseWriter) string {
func getTempInfo(app *App, key string, r *http.Request, w http.ResponseWriter) string {
session, err := app.sessionStore.Get(r, "t")
if err != nil {
return ""

20
activitypub.go

@ -1,5 +1,5 @@
/*
* Copyright © 2018 A Bunch Tell LLC.
* Copyright © 2018-2019 A Bunch Tell LLC.
*
* This file is part of WriteFreely.
*
@ -62,7 +62,7 @@ func (ru *RemoteUser) AsPerson() *activitystreams.Person {
}
}
func handleFetchCollectionActivities(app *app, w http.ResponseWriter, r *http.Request) error {
func handleFetchCollectionActivities(app *App, w http.ResponseWriter, r *http.Request) error {
w.Header().Set("Server", serverSoftware)
vars := mux.Vars(r)
@ -86,7 +86,7 @@ func handleFetchCollectionActivities(app *app, w http.ResponseWriter, r *http.Re
return impart.RenderActivityJSON(w, p, http.StatusOK)
}
func handleFetchCollectionOutbox(app *app, w http.ResponseWriter, r *http.Request) error {
func handleFetchCollectionOutbox(app *App, w http.ResponseWriter, r *http.Request) error {
w.Header().Set("Server", serverSoftware)
vars := mux.Vars(r)
@ -138,7 +138,7 @@ func handleFetchCollectionOutbox(app *app, w http.ResponseWriter, r *http.Reques
return impart.RenderActivityJSON(w, ocp, http.StatusOK)
}
func handleFetchCollectionFollowers(app *app, w http.ResponseWriter, r *http.Request) error {
func handleFetchCollectionFollowers(app *App, w http.ResponseWriter, r *http.Request) error {
w.Header().Set("Server", serverSoftware)
vars := mux.Vars(r)
@ -183,7 +183,7 @@ func handleFetchCollectionFollowers(app *app, w http.ResponseWriter, r *http.Req
return impart.RenderActivityJSON(w, ocp, http.StatusOK)
}
func handleFetchCollectionFollowing(app *app, w http.ResponseWriter, r *http.Request) error {
func handleFetchCollectionFollowing(app *App, w http.ResponseWriter, r *http.Request) error {
w.Header().Set("Server", serverSoftware)
vars := mux.Vars(r)
@ -218,7 +218,7 @@ func handleFetchCollectionFollowing(app *app, w http.ResponseWriter, r *http.Req
return impart.RenderActivityJSON(w, ocp, http.StatusOK)
}
func handleFetchCollectionInbox(app *app, w http.ResponseWriter, r *http.Request) error {
func handleFetchCollectionInbox(app *App, w http.ResponseWriter, r *http.Request) error {
w.Header().Set("Server", serverSoftware)
vars := mux.Vars(r)
@ -531,7 +531,7 @@ func resolveIRI(url string) ([]byte, error) {
return body, nil
}
func deleteFederatedPost(app *app, p *PublicPost, collID int64) error {
func deleteFederatedPost(app *App, p *PublicPost, collID int64) error {
if debugging {
log.Info("Deleting federated post!")
}
@ -569,7 +569,7 @@ func deleteFederatedPost(app *app, p *PublicPost, collID int64) error {
return nil
}
func federatePost(app *app, p *PublicPost, collID int64, isUpdate bool) error {
func federatePost(app *App, p *PublicPost, collID int64, isUpdate bool) error {
if debugging {
if isUpdate {
log.Info("Federating updated post!")
@ -619,7 +619,7 @@ func federatePost(app *app, p *PublicPost, collID int64, isUpdate bool) error {
return nil
}
func getRemoteUser(app *app, actorID string) (*RemoteUser, error) {
func getRemoteUser(app *App, actorID string) (*RemoteUser, error) {
u := RemoteUser{ActorID: actorID}
err := app.db.QueryRow("SELECT id, inbox, shared_inbox FROM remoteusers WHERE actor_id = ?", actorID).Scan(&u.ID, &u.Inbox, &u.SharedInbox)
switch {
@ -633,7 +633,7 @@ func getRemoteUser(app *app, actorID string) (*RemoteUser, error) {
return &u, nil
}
func getActor(app *app, actorIRI string) (*activitystreams.Person, *RemoteUser, error) {
func getActor(app *App, actorIRI string) (*activitystreams.Person, *RemoteUser, error) {
log.Info("Fetching actor %s locally", actorIRI)
actor := &activitystreams.Person{}
remoteUser, err := getRemoteUser(app, actorIRI)

18
admin.go

@ -1,5 +1,5 @@
/*
* Copyright © 2018 A Bunch Tell LLC.
* Copyright © 2018-2019 A Bunch Tell LLC.
*
* This file is part of WriteFreely.
*
@ -96,7 +96,7 @@ func (c instanceContent) UpdatedFriendly() string {
return c.Updated.Format("January 2, 2006, 3:04 PM")
}
func handleViewAdminDash(app *app, u *User, w http.ResponseWriter, r *http.Request) error {
func handleViewAdminDash(app *App, u *User, w http.ResponseWriter, r *http.Request) error {
updateAppStats()
p := struct {
*UserPage
@ -117,7 +117,7 @@ func handleViewAdminDash(app *app, u *User, w http.ResponseWriter, r *http.Reque
return nil
}
func handleViewAdminUsers(app *app, u *User, w http.ResponseWriter, r *http.Request) error {
func handleViewAdminUsers(app *App, u *User, w http.ResponseWriter, r *http.Request) error {
p := struct {
*UserPage
Config config.AppCfg
@ -157,7 +157,7 @@ func handleViewAdminUsers(app *app, u *User, w http.ResponseWriter, r *http.Requ
return nil
}
func handleViewAdminUser(app *app, u *User, w http.ResponseWriter, r *http.Request) error {
func handleViewAdminUser(app *App, u *User, w http.ResponseWriter, r *http.Request) error {
vars := mux.Vars(r)
username := vars["username"]
if username == "" {
@ -229,7 +229,7 @@ func handleViewAdminUser(app *app, u *User, w http.ResponseWriter, r *http.Reque
return nil
}
func handleViewAdminPages(app *app, u *User, w http.ResponseWriter, r *http.Request) error {
func handleViewAdminPages(app *App, u *User, w http.ResponseWriter, r *http.Request) error {
p := struct {
*UserPage
Config config.AppCfg
@ -287,7 +287,7 @@ func handleViewAdminPages(app *app, u *User, w http.ResponseWriter, r *http.Requ
return nil
}
func handleViewAdminPage(app *app, u *User, w http.ResponseWriter, r *http.Request) error {
func handleViewAdminPage(app *App, u *User, w http.ResponseWriter, r *http.Request) error {
vars := mux.Vars(r)
slug := vars["slug"]
if slug == "" {
@ -329,7 +329,7 @@ func handleViewAdminPage(app *app, u *User, w http.ResponseWriter, r *http.Reque
return nil
}
func handleAdminUpdateSite(app *app, u *User, w http.ResponseWriter, r *http.Request) error {
func handleAdminUpdateSite(app *App, u *User, w http.ResponseWriter, r *http.Request) error {
vars := mux.Vars(r)
id := vars["page"]
@ -347,7 +347,7 @@ func handleAdminUpdateSite(app *app, u *User, w http.ResponseWriter, r *http.Req
return impart.HTTPError{http.StatusFound, "/admin/page/" + id + m}
}
func handleAdminUpdateConfig(app *app, u *User, w http.ResponseWriter, r *http.Request) error {
func handleAdminUpdateConfig(app *App, u *User, w http.ResponseWriter, r *http.Request) error {
app.cfg.App.SiteName = r.FormValue("site_name")
app.cfg.App.SiteDesc = r.FormValue("site_desc")
app.cfg.App.OpenRegistration = r.FormValue("open_registration") == "on"
@ -418,7 +418,7 @@ func updateAppStats() {
sysStatus.NumGC = m.NumGC
}
func adminResetPassword(app *app, u *User, newPass string) error {
func adminResetPassword(app *App, u *User, newPass string) error {
hashedPass, err := auth.HashPass([]byte(newPass))
if err != nil {
return impart.HTTPError{http.StatusInternalServerError, fmt.Sprintf("Could not create password hash: %v", err)}

39
app.go

@ -1,5 +1,5 @@
/*
* Copyright © 2018 A Bunch Tell LLC.
* Copyright © 2018-2019 A Bunch Tell LLC.
*
* This file is part of WriteFreely.
*
@ -62,7 +62,8 @@ var (
isSingleUser bool
)
type app struct {
// App holds data and configuration for an individual WriteFreely instance.
type App struct {
router *mux.Router
db *datastore
cfg *config.Config
@ -76,7 +77,7 @@ type app struct {
// handleViewHome shows page at root path. Will be the Pad if logged in and the
// catch-all landing page otherwise.
func handleViewHome(app *app, w http.ResponseWriter, r *http.Request) error {
func handleViewHome(app *App, w http.ResponseWriter, r *http.Request) error {
if app.cfg.App.SingleUser {
// Render blog index
return handleViewCollection(app, w, r)
@ -111,7 +112,7 @@ func handleViewHome(app *app, w http.ResponseWriter, r *http.Request) error {
return renderPage(w, "landing.tmpl", p)
}
func handleTemplatedPage(app *app, w http.ResponseWriter, r *http.Request, t *template.Template) error {
func handleTemplatedPage(app *App, w http.ResponseWriter, r *http.Request, t *template.Template) error {
p := struct {
page.StaticPage
ContentTitle string
@ -157,7 +158,7 @@ func handleTemplatedPage(app *app, w http.ResponseWriter, r *http.Request, t *te
return nil
}
func pageForReq(app *app, r *http.Request) page.StaticPage {
func pageForReq(app *App, r *http.Request) page.StaticPage {
p := page.StaticPage{
AppCfg: app.cfg.App,
Path: r.URL.Path,
@ -189,7 +190,7 @@ func pageForReq(app *app, r *http.Request) page.StaticPage {
var shttp = http.NewServeMux()
var fileRegex = regexp.MustCompile("/([^/]*\\.[^/]*)$")
func Serve(app *app, debug bool) {
func Serve(app *App, debug bool) {
debugging = debug
log.Info("Initializing...")
@ -317,14 +318,14 @@ func OutputVersion() {
}
// NewApp creates a new app instance.
func NewApp(cfgFile string) *app {
return &app{
func NewApp(cfgFile string) *App {
return &App{
cfgFile: cfgFile,
}
}
// CreateConfig creates a default configuration and saves it to the app's cfgFile.
func CreateConfig(app *app) error {
func CreateConfig(app *App) error {
log.Info("Creating configuration...")
c := config.New()
log.Info("Saving configuration %s...", app.cfgFile)
@ -336,7 +337,7 @@ func CreateConfig(app *app) error {
}
// DoConfig runs the interactive configuration process.
func DoConfig(app *app) {
func DoConfig(app *App) {
d, err := config.Configure(app.cfgFile)
if err != nil {
log.Error("Unable to configure: %v", err)
@ -374,7 +375,7 @@ func DoConfig(app *app) {
}
// GenerateKeys creates app encryption keys and saves them into the configured KeysParentDir.
func GenerateKeys(app *app) error {
func GenerateKeys(app *App) error {
// Read keys path from config
loadConfig(app)
@ -407,7 +408,7 @@ func GenerateKeys(app *app) error {
}
// CreateSchema creates all database tables needed for the application.
func CreateSchema(app *app) error {
func CreateSchema(app *App) error {
loadConfig(app)
connectToDatabase(app)
defer shutdown(app)
@ -419,7 +420,7 @@ func CreateSchema(app *app) error {
}
// Migrate runs all necessary database migrations.
func Migrate(app *app) error {
func Migrate(app *App) error {
loadConfig(app)
connectToDatabase(app)
defer shutdown(app)
@ -432,7 +433,7 @@ func Migrate(app *app) error {
}
// ResetPassword runs the interactive password reset process.
func ResetPassword(app *app, username string) error {
func ResetPassword(app *App, username string) error {
// Connect to the database
loadConfig(app)
connectToDatabase(app)
@ -470,7 +471,7 @@ func ResetPassword(app *app, username string) error {
return nil
}
func loadConfig(app *app) {
func loadConfig(app *App) {
log.Info("Loading %s configuration...", app.cfgFile)
cfg, err := config.Load(app.cfgFile)
if err != nil {
@ -480,7 +481,7 @@ func loadConfig(app *app) {
app.cfg = cfg
}
func connectToDatabase(app *app) {
func connectToDatabase(app *App) {
log.Info("Connecting to %s database...", app.cfg.Database.Type)
var db *sql.DB
@ -510,13 +511,13 @@ func connectToDatabase(app *app) {
app.db = &datastore{db, app.cfg.Database.Type}
}
func shutdown(app *app) {
func shutdown(app *App) {
log.Info("Closing database connection...")
app.db.Close()
}
// CreateUser creates a new admin or normal user from the given username:password string.
func CreateUser(app *app, credStr string, isAdmin bool) error {
func CreateUser(app *App, credStr string, isAdmin bool) error {
// Create an admin user with --create-admin
creds := strings.Split(credStr, ":")
if len(creds) != 2 {
@ -587,7 +588,7 @@ func CreateUser(app *app, credStr string, isAdmin bool) error {
return nil
}
func adminInitDatabase(app *app) error {
func adminInitDatabase(app *App) error {
schemaFileName := "schema.sql"
if app.cfg.Database.Type == driverSQLite {
schemaFileName = "sqlite.sql"

24
collections.go

@ -316,7 +316,7 @@ func (c *Collection) RenderMathJax() bool {
return c.db.CollectionHasAttribute(c.ID, "render_mathjax")
}
func newCollection(app *app, w http.ResponseWriter, r *http.Request) error {
func newCollection(app *App, w http.ResponseWriter, r *http.Request) error {
reqJSON := IsJSON(r.Header.Get("Content-Type"))
alias := r.FormValue("alias")
title := r.FormValue("title")
@ -399,7 +399,7 @@ func newCollection(app *app, w http.ResponseWriter, r *http.Request) error {
return impart.HTTPError{http.StatusFound, redirectTo}
}
func apiCheckCollectionPermissions(app *app, r *http.Request, c *Collection) (int64, error) {
func apiCheckCollectionPermissions(app *App, r *http.Request, c *Collection) (int64, error) {
accessToken := r.Header.Get("Authorization")
var userID int64 = -1
if accessToken != "" {
@ -419,7 +419,7 @@ func apiCheckCollectionPermissions(app *app, r *http.Request, c *Collection) (in
}
// fetchCollection handles the API endpoint for retrieving collection data.
func fetchCollection(app *app, w http.ResponseWriter, r *http.Request) error {
func fetchCollection(app *App, w http.ResponseWriter, r *http.Request) error {
accept := r.Header.Get("Accept")
if strings.Contains(accept, "application/activity+json") {
return handleFetchCollectionActivities(app, w, r)
@ -467,7 +467,7 @@ func fetchCollection(app *app, w http.ResponseWriter, r *http.Request) error {
// fetchCollectionPosts handles an API endpoint for retrieving a collection's
// posts.
func fetchCollectionPosts(app *app, w http.ResponseWriter, r *http.Request) error {
func fetchCollectionPosts(app *App, w http.ResponseWriter, r *http.Request) error {
vars := mux.Vars(r)
alias := vars["alias"]
@ -563,7 +563,7 @@ func processCollectionRequest(cr *collectionReq, vars map[string]string, w http.
// domain that doesn't yet have a collection associated, or if a collection
// requires a password. In either case, this will return nil, nil -- thus both
// values should ALWAYS be checked to determine whether or not to continue.
func processCollectionPermissions(app *app, cr *collectionReq, u *User, w http.ResponseWriter, r *http.Request) (*Collection, error) {
func processCollectionPermissions(app *App, cr *collectionReq, u *User, w http.ResponseWriter, r *http.Request) (*Collection, error) {
// Display collection if this is a collection
var c *Collection
var err error
@ -654,7 +654,7 @@ func processCollectionPermissions(app *app, cr *collectionReq, u *User, w http.R
return c, nil
}
func checkUserForCollection(app *app, cr *collectionReq, r *http.Request, isPostReq bool) (*User, error) {
func checkUserForCollection(app *App, cr *collectionReq, r *http.Request, isPostReq bool) (*User, error) {
u := getUserSession(app, r)
return u, nil
}
@ -682,7 +682,7 @@ func getCollectionPage(vars map[string]string) int {
}
// handleViewCollection displays the requested Collection
func handleViewCollection(app *app, w http.ResponseWriter, r *http.Request) error {
func handleViewCollection(app *App, w http.ResponseWriter, r *http.Request) error {
vars := mux.Vars(r)
cr := &collectionReq{}
@ -788,7 +788,7 @@ func handleViewCollection(app *app, w http.ResponseWriter, r *http.Request) erro
return err
}
func handleViewCollectionTag(app *app, w http.ResponseWriter, r *http.Request) error {
func handleViewCollectionTag(app *App, w http.ResponseWriter, r *http.Request) error {
vars := mux.Vars(r)
tag := vars["tag"]
@ -867,7 +867,7 @@ func handleViewCollectionTag(app *app, w http.ResponseWriter, r *http.Request) e
return nil
}
func handleCollectionPostRedirect(app *app, w http.ResponseWriter, r *http.Request) error {
func handleCollectionPostRedirect(app *App, w http.ResponseWriter, r *http.Request) error {
vars := mux.Vars(r)
slug := vars["slug"]
@ -885,7 +885,7 @@ func handleCollectionPostRedirect(app *app, w http.ResponseWriter, r *http.Reque
return impart.HTTPError{http.StatusFound, loc}
}
func existingCollection(app *app, w http.ResponseWriter, r *http.Request) error {
func existingCollection(app *App, w http.ResponseWriter, r *http.Request) error {
reqJSON := IsJSON(r.Header.Get("Content-Type"))
vars := mux.Vars(r)
collAlias := vars["alias"]
@ -980,7 +980,7 @@ func collectionAliasFromReq(r *http.Request) string {
return alias
}
func handleWebCollectionUnlock(app *app, w http.ResponseWriter, r *http.Request) error {
func handleWebCollectionUnlock(app *App, w http.ResponseWriter, r *http.Request) error {
var readReq struct {
Alias string `schema:"alias" json:"alias"`
Pass string `schema:"password" json:"password"`
@ -1047,7 +1047,7 @@ func handleWebCollectionUnlock(app *app, w http.ResponseWriter, r *http.Request)
return impart.HTTPError{http.StatusFound, next}
}
func isAuthorizedForCollection(app *app, alias string, r *http.Request) bool {
func isAuthorizedForCollection(app *App, alias string, r *http.Request) bool {
authd := false
session, err := app.sessionStore.Get(r, blogPassCookieName)
if err == nil {

4
database.go

@ -60,7 +60,7 @@ type writestore interface {
GetTemporaryAccessToken(userID int64, validSecs int) (string, error)
GetTemporaryOneTimeAccessToken(userID int64, validSecs int, oneTime bool) (string, error)
DeleteAccount(userID int64) (l *string, err error)
ChangeSettings(app *app, u *User, s *userSettings) error
ChangeSettings(app *App, u *User, s *userSettings) error
ChangePassphrase(userID int64, sudo bool, curPass string, hashedPass []byte) error
GetCollections(u *User) (*[]Collection, error)
@ -1774,7 +1774,7 @@ func (db *datastore) GetUserPostsCount(userID int64) int64 {
// ChangeSettings takes a User and applies the changes in the given
// userSettings, MODIFYING THE USER with successful changes.
func (db *datastore) ChangeSettings(app *app, u *User, s *userSettings) error {
func (db *datastore) ChangeSettings(app *App, u *User, s *userSettings) error {
var errPass error
q := query.NewUpdate()

4
export.go

@ -1,5 +1,5 @@
/*
* Copyright © 2018 A Bunch Tell LLC.
* Copyright © 2018-2019 A Bunch Tell LLC.
*
* This file is part of WriteFreely.
*
@ -92,7 +92,7 @@ func exportPostsZip(u *User, posts *[]PublicPost) []byte {
return b.Bytes()
}
func compileFullExport(app *app, u *User) *ExportUser {
func compileFullExport(app *App, u *User) *ExportUser {
exportUser := &ExportUser{
User: u,
}

4
feed.go

@ -1,5 +1,5 @@
/*
* Copyright © 2018 A Bunch Tell LLC.
* Copyright © 2018-2019 A Bunch Tell LLC.
*
* This file is part of WriteFreely.
*
@ -20,7 +20,7 @@ import (
"time"
)
func ViewFeed(app *app, w http.ResponseWriter, req *http.Request) error {
func ViewFeed(app *App, w http.ResponseWriter, req *http.Request) error {
alias := collectionAliasFromReq(req)
// Display collection if this is a collection

18
handle.go

@ -36,16 +36,16 @@ const (
)
type (
handlerFunc func(app *app, w http.ResponseWriter, r *http.Request) error
userHandlerFunc func(app *app, u *User, w http.ResponseWriter, r *http.Request) error
dataHandlerFunc func(app *app, w http.ResponseWriter, r *http.Request) ([]byte, string, error)
authFunc func(app *app, r *http.Request) (*User, error)
handlerFunc func(app *App, w http.ResponseWriter, r *http.Request) error
userHandlerFunc func(app *App, u *User, w http.ResponseWriter, r *http.Request) error
dataHandlerFunc func(app *App, w http.ResponseWriter, r *http.Request) ([]byte, string, error)
authFunc func(app *App, r *http.Request) (*User, error)
)
type Handler struct {
errors *ErrorPages
sessionStore *sessions.CookieStore
app *app
app *App
}
// ErrorPages hold template HTML error pages for displaying errors to the user.
@ -59,7 +59,7 @@ type ErrorPages struct {
// NewHandler returns a new Handler instance, using the given StaticPage data,
// and saving alias to the application's CookieStore.
func NewHandler(app *app) *Handler {
func NewHandler(app *App) *Handler {
h := &Handler{
errors: &ErrorPages{
NotFound: template.Must(template.New("").Parse("{{define \"base\"}}<html><head><title>404</title></head><body><p>Not found.</p></body></html>{{end}}")),
@ -160,7 +160,7 @@ func (h *Handler) Admin(f userHandlerFunc) http.HandlerFunc {
// UserAPI handles requests made in the API by the authenticated user.
// This provides user-friendly HTML pages and actions that work in the browser.
func (h *Handler) UserAPI(f userHandlerFunc) http.HandlerFunc {
return h.UserAll(false, f, func(app *app, r *http.Request) (*User, error) {
return h.UserAll(false, f, func(app *App, r *http.Request) (*User, error) {
// Authorize user from Authorization header
t := r.Header.Get("Authorization")
if t == "" {
@ -222,7 +222,7 @@ func (h *Handler) UserAll(web bool, f userHandlerFunc, a authFunc) http.HandlerF
}
func (h *Handler) RedirectOnErr(f handlerFunc, loc string) handlerFunc {
return func(app *app, w http.ResponseWriter, r *http.Request) error {
return func(app *App, w http.ResponseWriter, r *http.Request) error {
err := f(app, w, r)
if err != nil {
if ie, ok := err.(impart.HTTPError); ok {
@ -239,7 +239,7 @@ func (h *Handler) RedirectOnErr(f handlerFunc, loc string) handlerFunc {
}
func (h *Handler) Page(n string) http.HandlerFunc {
return h.Web(func(app *app, w http.ResponseWriter, r *http.Request) error {
return h.Web(func(app *App, w http.ResponseWriter, r *http.Request) error {
t, ok := pages[n]
if !ok {
return impart.HTTPError{http.StatusNotFound, "Page not found."}

4
hostmeta.go

@ -1,5 +1,5 @@
/*
* Copyright © 2018 A Bunch Tell LLC.
* Copyright © 2018-2019 A Bunch Tell LLC.
*
* This file is part of WriteFreely.
*
@ -15,7 +15,7 @@ import (
"net/http"
)
func handleViewHostMeta(app *app, w http.ResponseWriter, r *http.Request) error {
func handleViewHostMeta(app *App, w http.ResponseWriter, r *http.Request) error {
w.Header().Set("Server", serverSoftware)
w.Header().Set("Content-Type", "application/xrd+xml; charset=utf-8")

6
invites.go

@ -45,7 +45,7 @@ func (i Invite) ExpiresFriendly() string {
return i.Expires.Format("January 2, 2006, 3:04 PM")
}
func handleViewUserInvites(app *app, u *User, w http.ResponseWriter, r *http.Request) error {
func handleViewUserInvites(app *App, u *User, w http.ResponseWriter, r *http.Request) error {
// Don't show page if instance doesn't allow it
if !(app.cfg.App.UserInvites != "" && (u.IsAdmin() || app.cfg.App.UserInvites != "admin")) {
return impart.HTTPError{http.StatusNotFound, ""}
@ -73,7 +73,7 @@ func handleViewUserInvites(app *app, u *User, w http.ResponseWriter, r *http.Req
return nil
}
func handleCreateUserInvite(app *app, u *User, w http.ResponseWriter, r *http.Request) error {
func handleCreateUserInvite(app *App, u *User, w http.ResponseWriter, r *http.Request) error {
muVal := r.FormValue("uses")
expVal := r.FormValue("expires")
@ -106,7 +106,7 @@ func handleCreateUserInvite(app *app, u *User, w http.ResponseWriter, r *http.Re
return impart.HTTPError{http.StatusFound, "/me/invites"}
}
func handleViewInvite(app *app, w http.ResponseWriter, r *http.Request) error {
func handleViewInvite(app *App, w http.ResponseWriter, r *http.Request) error {
inviteCode := mux.Vars(r)["code"]
i, err := app.db.GetUserInvite(inviteCode)

6
keys.go

@ -1,5 +1,5 @@
/*
* Copyright © 2018 A Bunch Tell LLC.
* Copyright © 2018-2019 A Bunch Tell LLC.
*
* This file is part of WriteFreely.
*
@ -34,13 +34,13 @@ type keychain struct {
emailKey, cookieAuthKey, cookieKey []byte
}
func initKeyPaths(app *app) {
func initKeyPaths(app *App) {
emailKeyPath = filepath.Join(app.cfg.Server.KeysParentDir, emailKeyPath)
cookieAuthKeyPath = filepath.Join(app.cfg.Server.KeysParentDir, cookieAuthKeyPath)
cookieKeyPath = filepath.Join(app.cfg.Server.KeysParentDir, cookieKeyPath)
}
func initKeys(app *app) error {
func initKeys(app *App) error {
var err error
app.keys = &keychain{}

6
pad.go

@ -1,5 +1,5 @@
/*
* Copyright © 2018 A Bunch Tell LLC.
* Copyright © 2018-2019 A Bunch Tell LLC.
*
* This file is part of WriteFreely.
*
@ -19,7 +19,7 @@ import (
"strings"
)
func handleViewPad(app *app, w http.ResponseWriter, r *http.Request) error {
func handleViewPad(app *App, w http.ResponseWriter, r *http.Request) error {
vars := mux.Vars(r)
action := vars["action"]
slug := vars["slug"]
@ -102,7 +102,7 @@ func handleViewPad(app *app, w http.ResponseWriter, r *http.Request) error {
return nil
}
func handleViewMeta(app *app, w http.ResponseWriter, r *http.Request) error {
func handleViewMeta(app *App, w http.ResponseWriter, r *http.Request) error {
vars := mux.Vars(r)
action := vars["action"]
slug := vars["slug"]

6
pages.go

@ -1,5 +1,5 @@
/*
* Copyright © 2018 A Bunch Tell LLC.
* Copyright © 2018-2019 A Bunch Tell LLC.
*
* This file is part of WriteFreely.
*
@ -18,7 +18,7 @@ import (
var defaultPageUpdatedTime = time.Date(2018, 11, 8, 12, 0, 0, 0, time.Local)
func getAboutPage(app *app) (*instanceContent, error) {
func getAboutPage(app *App) (*instanceContent, error) {
c, err := app.db.GetDynamicContent("about")
if err != nil {
return nil, err
@ -40,7 +40,7 @@ func defaultAboutTitle(cfg *config.Config) sql.NullString {
return sql.NullString{String: "About " + cfg.App.SiteName, Valid: true}
}
func getPrivacyPage(app *app) (*instanceContent, error) {
func getPrivacyPage(app *App) (*instanceContent, error) {
c, err := app.db.GetDynamicContent("privacy")
if err != nil {
return nil, err

26
posts.go

@ -1,5 +1,5 @@
/*
* Copyright © 2018 A Bunch Tell LLC.
* Copyright © 2018-2019 A Bunch Tell LLC.
*
* This file is part of WriteFreely.
*
@ -260,7 +260,7 @@ func (p *Post) HasTitleLink() bool {
return hasLink
}
func handleViewPost(app *app, w http.ResponseWriter, r *http.Request) error {
func handleViewPost(app *App, w http.ResponseWriter, r *http.Request) error {
vars := mux.Vars(r)
friendlyID := vars["post"]
@ -466,7 +466,7 @@ func handleViewPost(app *app, w http.ResponseWriter, r *http.Request) error {
// /posts
// /posts?collection={alias}
// ? /collections/{alias}/posts
func newPost(app *app, w http.ResponseWriter, r *http.Request) error {
func newPost(app *App, w http.ResponseWriter, r *http.Request) error {
reqJSON := IsJSON(r.Header.Get("Content-Type"))
vars := mux.Vars(r)
collAlias := vars["alias"]
@ -591,7 +591,7 @@ func newPost(app *app, w http.ResponseWriter, r *http.Request) error {
return response
}
func existingPost(app *app, w http.ResponseWriter, r *http.Request) error {
func existingPost(app *App, w http.ResponseWriter, r *http.Request) error {
reqJSON := IsJSON(r.Header.Get("Content-Type"))
vars := mux.Vars(r)
postID := vars["post"]
@ -711,7 +711,7 @@ func existingPost(app *app, w http.ResponseWriter, r *http.Request) error {
return nil
}
func deletePost(app *app, w http.ResponseWriter, r *http.Request) error {
func deletePost(app *App, w http.ResponseWriter, r *http.Request) error {
vars := mux.Vars(r)
friendlyID := vars["post"]
editToken := r.FormValue("token")
@ -830,7 +830,7 @@ func deletePost(app *app, w http.ResponseWriter, r *http.Request) error {
}
// addPost associates a post with the authenticated user.
func addPost(app *app, w http.ResponseWriter, r *http.Request) error {
func addPost(app *App, w http.ResponseWriter, r *http.Request) error {
var ownerID int64
// Authenticate user
@ -879,7 +879,7 @@ func addPost(app *app, w http.ResponseWriter, r *http.Request) error {
return impart.WriteSuccess(w, res, http.StatusOK)
}
func dispersePost(app *app, w http.ResponseWriter, r *http.Request) error {
func dispersePost(app *App, w http.ResponseWriter, r *http.Request) error {
var ownerID int64
// Authenticate user
@ -923,7 +923,7 @@ type (
)
// pinPost pins a post to a blog
func pinPost(app *app, w http.ResponseWriter, r *http.Request) error {
func pinPost(app *App, w http.ResponseWriter, r *http.Request) error {
var userID int64
// Authenticate user
@ -981,7 +981,7 @@ func pinPost(app *app, w http.ResponseWriter, r *http.Request) error {
return impart.WriteSuccess(w, res, http.StatusOK)
}
func fetchPost(app *app, w http.ResponseWriter, r *http.Request) error {
func fetchPost(app *App, w http.ResponseWriter, r *http.Request) error {
var collID int64
var coll *Collection
var err error
@ -1030,7 +1030,7 @@ func fetchPost(app *app, w http.ResponseWriter, r *http.Request) error {
return impart.WriteSuccess(w, p, http.StatusOK)
}
func fetchPostProperty(app *app, w http.ResponseWriter, r *http.Request) error {
func fetchPostProperty(app *App, w http.ResponseWriter, r *http.Request) error {
vars := mux.Vars(r)
p, err := app.db.GetPostProperty(vars["post"], 0, vars["property"])
if err != nil {
@ -1128,7 +1128,7 @@ func (p *SubmittedPost) isFontValid() bool {
return valid
}
func getRawPost(app *app, friendlyID string) *RawPost {
func getRawPost(app *App, friendlyID string) *RawPost {
var content, font, title string
var isRTL sql.NullBool
var lang sql.NullString
@ -1148,7 +1148,7 @@ func getRawPost(app *app, friendlyID string) *RawPost {
}
// TODO; return a Post!
func getRawCollectionPost(app *app, slug, collAlias string) *RawPost {
func getRawCollectionPost(app *App, slug, collAlias string) *RawPost {
var id, title, content, font string
var isRTL sql.NullBool
var lang sql.NullString
@ -1185,7 +1185,7 @@ func getRawCollectionPost(app *app, slug, collAlias string) *RawPost {
}
}
func viewCollectionPost(app *app, w http.ResponseWriter, r *http.Request) error {
func viewCollectionPost(app *App, w http.ResponseWriter, r *http.Request) error {
vars := mux.Vars(r)
slug := vars["slug"]

14
read.go

@ -1,5 +1,5 @@
/*
* Copyright © 2018 A Bunch Tell LLC.
* Copyright © 2018-2019 A Bunch Tell LLC.
*
* This file is part of WriteFreely.
*
@ -49,7 +49,7 @@ type readPublication struct {
TotalPages int
}
func initLocalTimeline(app *app) {
func initLocalTimeline(app *App) {
app.timeline = &localTimeline{
postsPerPage: tlPostsPerPage,
m: memo.New(app.db.FetchPublicPosts, 10*time.Minute),
@ -108,7 +108,7 @@ func (db *datastore) FetchPublicPosts() (interface{}, error) {
return posts, nil
}
func viewLocalTimelineAPI(app *app, w http.ResponseWriter, r *http.Request) error {
func viewLocalTimelineAPI(app *App, w http.ResponseWriter, r *http.Request) error {
updateTimelineCache(app.timeline)
skip, _ := strconv.Atoi(r.FormValue("skip"))
@ -121,7 +121,7 @@ func viewLocalTimelineAPI(app *app, w http.ResponseWriter, r *http.Request) erro
return impart.WriteSuccess(w, posts, http.StatusOK)
}
func viewLocalTimeline(app *app, w http.ResponseWriter, r *http.Request) error {
func viewLocalTimeline(app *App, w http.ResponseWriter, r *http.Request) error {
if !app.cfg.App.LocalTimeline {
return impart.HTTPError{http.StatusNotFound, "Page doesn't exist."}
}
@ -153,7 +153,7 @@ func updateTimelineCache(tl *localTimeline) {
}
}
func showLocalTimeline(app *app, w http.ResponseWriter, r *http.Request, page int, author, tag string) error {
func showLocalTimeline(app *App, w http.ResponseWriter, r *http.Request, page int, author, tag string) error {
updateTimelineCache(app.timeline)
pl := len(*(app.timeline.posts))
@ -226,7 +226,7 @@ func (c *readPublication) PrevPageURL(n int) string {
// handlePostIDRedirect handles a route where a post ID is given and redirects
// the user to the canonical post URL.
func handlePostIDRedirect(app *app, w http.ResponseWriter, r *http.Request) error {
func handlePostIDRedirect(app *App, w http.ResponseWriter, r *http.Request) error {
vars := mux.Vars(r)
postID := vars["post"]
p, err := app.db.GetPost(postID, 0)
@ -249,7 +249,7 @@ func handlePostIDRedirect(app *app, w http.ResponseWriter, r *http.Request) erro
return impart.HTTPError{http.StatusFound, c.CanonicalURL() + p.Slug.String}
}
func viewLocalTimelineFeed(app *app, w http.ResponseWriter, req *http.Request) error {
func viewLocalTimelineFeed(app *App, w http.ResponseWriter, req *http.Request) error {
if !app.cfg.App.LocalTimeline {
return impart.HTTPError{http.StatusNotFound, "Page doesn't exist."}
}

16
session.go

@ -1,5 +1,5 @@
/*
* Copyright © 2018 A Bunch Tell LLC.
* Copyright © 2018-2019 A Bunch Tell LLC.
*
* This file is part of WriteFreely.
*
@ -29,7 +29,7 @@ const (
// initSession creates the cookie store. It depends on the keychain already
// being loaded.
func initSession(app *app) *sessions.CookieStore {
func initSession(app *App) *sessions.CookieStore {
// Register complex data types we'll be storing in cookies
gob.Register(&User{})
@ -44,7 +44,7 @@ func initSession(app *app) *sessions.CookieStore {
return store
}
func getSessionFlashes(app *app, w http.ResponseWriter, r *http.Request, session *sessions.Session) ([]string, error) {
func getSessionFlashes(app *App, w http.ResponseWriter, r *http.Request, session *sessions.Session) ([]string, error) {
var err error
if session == nil {
session, err = app.sessionStore.Get(r, cookieName)
@ -66,7 +66,7 @@ func getSessionFlashes(app *app, w http.ResponseWriter, r *http.Request, session
return f, nil
}
func addSessionFlash(app *app, w http.ResponseWriter, r *http.Request, m string, session *sessions.Session) error {
func addSessionFlash(app *App, w http.ResponseWriter, r *http.Request, m string, session *sessions.Session) error {
var err error
if session == nil {
session, err = app.sessionStore.Get(r, cookieName)
@ -82,7 +82,7 @@ func addSessionFlash(app *app, w http.ResponseWriter, r *http.Request, m string,
return nil
}
func getUserAndSession(app *app, r *http.Request) (*User, *sessions.Session) {
func getUserAndSession(app *App, r *http.Request) (*User, *sessions.Session) {
session, err := app.sessionStore.Get(r, cookieName)
if err == nil {
// Got the currently logged-in user
@ -97,12 +97,12 @@ func getUserAndSession(app *app, r *http.Request) (*User, *sessions.Session) {
return nil, nil
}
func getUserSession(app *app, r *http.Request) *User {
func getUserSession(app *App, r *http.Request) *User {
u, _ := getUserAndSession(app, r)
return u
}
func saveUserSession(app *app, r *http.Request, w http.ResponseWriter) error {
func saveUserSession(app *App, r *http.Request, w http.ResponseWriter) error