Make App struct public
This commit is contained in:
parent
9023d4eb3f
commit
d8937e89a8
52
account.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 ""
|
||||
|
|
|
@ -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
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
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"
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -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
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
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."}
|
||||
|
|
|
@ -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")
|
||||
|
||||
|
|
|
@ -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
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
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
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
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
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
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 {
|
||||
session, err := app.sessionStore.Get(r, cookieName)
|
||||
if err != nil {
|
||||
return ErrInternalCookieSession
|
||||
|
@ -127,7 +127,7 @@ func saveUserSession(app *app, r *http.Request, w http.ResponseWriter) error {
|
|||
return err
|
||||
}
|
||||
|
||||
func getFullUserSession(app *app, r *http.Request) *User {
|
||||
func getFullUserSession(app *App, r *http.Request) *User {
|
||||
u := getUserSession(app, r)
|
||||
if u == nil {
|
||||
return nil
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
/*
|
||||
* Copyright © 2018 A Bunch Tell LLC.
|
||||
* Copyright © 2018-2019 A Bunch Tell LLC.
|
||||
*
|
||||
* This file is part of WriteFreely.
|
||||
*
|
||||
|
@ -34,7 +34,7 @@ func buildSitemap(host, alias string) *stm.Sitemap {
|
|||
return sm
|
||||
}
|
||||
|
||||
func handleViewSitemap(app *app, w http.ResponseWriter, r *http.Request) error {
|
||||
func handleViewSitemap(app *App, w http.ResponseWriter, r *http.Request) error {
|
||||
vars := mux.Vars(r)
|
||||
|
||||
// Determine canonical blog URL
|
||||
|
|
|
@ -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 (
|
|||
"net/http"
|
||||
)
|
||||
|
||||
func handleWebSignup(app *app, w http.ResponseWriter, r *http.Request) error {
|
||||
func handleWebSignup(app *App, w http.ResponseWriter, r *http.Request) error {
|
||||
reqJSON := IsJSON(r.Header.Get("Content-Type"))
|
||||
|
||||
// Get params
|
||||
|
@ -67,7 +67,7 @@ func handleWebSignup(app *app, w http.ResponseWriter, r *http.Request) error {
|
|||
|
||||
// { "username": "asdf" }
|
||||
// result: { code: 204 }
|
||||
func handleUsernameCheck(app *app, w http.ResponseWriter, r *http.Request) error {
|
||||
func handleUsernameCheck(app *App, w http.ResponseWriter, r *http.Request) error {
|
||||
reqJSON := IsJSON(r.Header.Get("Content-Type"))
|
||||
|
||||
// Get params
|
||||
|
@ -112,7 +112,7 @@ func handleUsernameCheck(app *app, w http.ResponseWriter, r *http.Request) error
|
|||
return impart.HTTPError{http.StatusConflict, "Username is already taken."}
|
||||
}
|
||||
|
||||
func getValidUsername(app *app, reqName, prevName string) (string, *impart.HTTPError) {
|
||||
func getValidUsername(app *App, reqName, prevName string) (string, *impart.HTTPError) {
|
||||
// Check if username is okay
|
||||
finalUsername := getSlug(reqName, "")
|
||||
if finalUsername == "" {
|
||||
|
|
Loading…
Reference in New Issue