aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--INSTALL10
-rw-r--r--Makefile4
-rw-r--r--bloat.conf7
-rw-r--r--config/config.go8
-rw-r--r--main.go24
-rw-r--r--model/app.go21
-rw-r--r--model/session.go60
-rw-r--r--model/settings.go33
-rw-r--r--repo/appRepo.go42
-rw-r--r--repo/sessionRepo.go47
-rw-r--r--service/client.go111
-rw-r--r--service/service.go119
-rw-r--r--service/transport.go143
-rw-r--r--util/kv.go91
14 files changed, 225 insertions, 495 deletions
diff --git a/INSTALL b/INSTALL
index 8f8c6d4..2d8047f 100644
--- a/INSTALL
+++ b/INSTALL
@@ -23,16 +23,8 @@ most cases, you only need to change the value of "client_website".
# cp bloat.gen.conf /etc/bloat.conf
# $EDITOR /etc/bloat.conf
-4. Create database directory
-Create a directory to store session information. Optionally, create a user
-to run bloat and change the ownership of the database directory accordingly.
-# mkdir /var/bloat
-# useradd _bloat
-# chown -R _bloat:_bloat /var/bloat
-Replace /var/bloat with the value you specified in the config file.
-
5. Run the binary
-# su _bloat -c bloat
+$ bloat
Now you should create an init script to automatically start bloat at system
startup.
diff --git a/Makefile b/Makefile
index c38de6b..104bfb1 100644
--- a/Makefile
+++ b/Makefile
@@ -10,7 +10,6 @@ SRC=main.go \
mastodon/*.go \
model/*.go \
renderer/*.go \
- repo/*.go \
service/*.go \
util/*.go \
@@ -18,8 +17,7 @@ all: bloat
bloat: $(SRC) $(TMPL)
$(GO) build $(GOFLAGS) -o bloat main.go
- sed -e "s%=database%=/var/bloat%g" \
- -e "s%=templates%=$(SHAREPATH)/templates%g" \
+ sed -e "s%=templates%=$(SHAREPATH)/templates%g" \
-e "s%=static%=$(SHAREPATH)/static%g" \
< bloat.conf > bloat.gen.conf
diff --git a/bloat.conf b/bloat.conf
index dd77875..ddf18fc 100644
--- a/bloat.conf
+++ b/bloat.conf
@@ -3,10 +3,6 @@
# - Key and Value are separated by a single '='
# - Leading and trailing white spaces in Key and Value are ignored
# - Quoting and multi-line values are not supported
-#
-# Changing values of client_name, client_scope or client_website will cause
-# previously generated access tokens and client tokens to be invalid. Issue the
-# `rm -r database_path/*` command to clean the database afterwards.
# Address to listen to. Value can be of "HOSTNAME:PORT" or "IP:PORT" form. In
# case of empty HOSTNAME or IP, "0.0.0.0:PORT" is used.
@@ -25,9 +21,6 @@ client_name=bloat
# See https://docs.joinmastodon.org/api/oauth-scopes/
client_scope=read write follow
-# Path of database directory. It's used to store session information.
-database_path=database
-
# Path of directory containing template files.
templates_path=templates
diff --git a/config/config.go b/config/config.go
index bbb327c..a92d66f 100644
--- a/config/config.go
+++ b/config/config.go
@@ -18,7 +18,6 @@ type config struct {
SingleInstance string
StaticDirectory string
TemplatesPath string
- DatabasePath string
CustomCSS string
PostFormats []model.PostFormat
LogFile string
@@ -30,8 +29,7 @@ func (c *config) IsValid() bool {
len(c.ClientScope) < 1 ||
len(c.ClientWebsite) < 1 ||
len(c.StaticDirectory) < 1 ||
- len(c.TemplatesPath) < 1 ||
- len(c.DatabasePath) < 1 {
+ len(c.TemplatesPath) < 1 {
return false
}
return true
@@ -75,10 +73,10 @@ func Parse(r io.Reader) (c *config, err error) {
c.StaticDirectory = val
case "templates_path":
c.TemplatesPath = val
- case "database_path":
- c.DatabasePath = val
case "custom_css":
c.CustomCSS = val
+ case "database_path":
+ // ignore
case "post_formats":
vals := strings.Split(val, ",")
var formats []model.PostFormat
diff --git a/main.go b/main.go
index 3b5ccba..b717b7d 100644
--- a/main.go
+++ b/main.go
@@ -12,9 +12,7 @@ import (
"bloat/config"
"bloat/renderer"
- "bloat/repo"
"bloat/service"
- "bloat/util"
)
var (
@@ -48,26 +46,6 @@ func main() {
errExit(err)
}
- err = os.Mkdir(config.DatabasePath, 0755)
- if err != nil && !os.IsExist(err) {
- errExit(err)
- }
-
- sessionDBPath := filepath.Join(config.DatabasePath, "session")
- sessionDB, err := util.NewDatabse(sessionDBPath)
- if err != nil {
- errExit(err)
- }
-
- appDBPath := filepath.Join(config.DatabasePath, "app")
- appDB, err := util.NewDatabse(appDBPath)
- if err != nil {
- errExit(err)
- }
-
- sessionRepo := repo.NewSessionRepo(sessionDB)
- appRepo := repo.NewAppRepo(appDB)
-
customCSS := config.CustomCSS
if len(customCSS) > 0 && !strings.HasPrefix(customCSS, "http://") &&
!strings.HasPrefix(customCSS, "https://") {
@@ -89,7 +67,7 @@ func main() {
s := service.NewService(config.ClientName, config.ClientScope,
config.ClientWebsite, customCSS, config.SingleInstance,
- config.PostFormats, renderer, sessionRepo, appRepo)
+ config.PostFormats, renderer)
handler := service.NewHandler(s, logger, config.StaticDirectory)
logger.Println("listening on", config.ListenAddress)
diff --git a/model/app.go b/model/app.go
deleted file mode 100644
index 8f172c8..0000000
--- a/model/app.go
+++ /dev/null
@@ -1,21 +0,0 @@
-package model
-
-import (
- "errors"
-)
-
-var (
- ErrAppNotFound = errors.New("app not found")
-)
-
-type App struct {
- InstanceDomain string `json:"instance_domain"`
- InstanceURL string `json:"instance_url"`
- ClientID string `json:"client_id"`
- ClientSecret string `json:"client_secret"`
-}
-
-type AppRepo interface {
- Add(app App) (err error)
- Get(instanceDomain string) (app App, err error)
-}
diff --git a/model/session.go b/model/session.go
index 5ff079b..6ada4aa 100644
--- a/model/session.go
+++ b/model/session.go
@@ -1,28 +1,48 @@
package model
-import (
- "errors"
-)
-
-var (
- ErrSessionNotFound = errors.New("session not found")
-)
-
type Session struct {
- ID string `json:"id"`
- UserID string `json:"user_id"`
- InstanceDomain string `json:"instance_domain"`
- AccessToken string `json:"access_token"`
- CSRFToken string `json:"csrf_token"`
- Settings Settings `json:"settings"`
-}
-
-type SessionRepo interface {
- Add(session Session) (err error)
- Get(sessionID string) (session Session, err error)
- Remove(sessionID string)
+ ID string `json:"id,omitempty"`
+ UserID string `json:"uid,omitempty"`
+ Instance string `json:"ins,omitempty"`
+ ClientID string `json:"cid,omitempty"`
+ ClientSecret string `json:"cs,omitempty"`
+ AccessToken string `json:"at,omitempty"`
+ CSRFToken string `json:"csrf,omitempty"`
+ Settings Settings `json:"sett,omitempty"`
}
func (s Session) IsLoggedIn() bool {
return len(s.AccessToken) > 0
}
+
+type Settings struct {
+ DefaultVisibility string `json:"dv,omitempty"`
+ DefaultFormat string `json:"df,omitempty"`
+ CopyScope bool `json:"cs,omitempty"`
+ ThreadInNewTab bool `json:"tnt,omitempty"`
+ HideAttachments bool `json:"ha,omitempty"`
+ MaskNSFW bool `json:"mn,omitempty"`
+ NotificationInterval int `json:"ni,omitempty"`
+ FluorideMode bool `json:"fm,omitempty"`
+ DarkMode bool `json:"dm,omitempty"`
+ AntiDopamineMode bool `json:"adm,omitempty"`
+ HideUnsupportedNotifs bool `json:"hun,omitempty"`
+ CSS string `json:"css,omitempty"`
+}
+
+func NewSettings() *Settings {
+ return &Settings{
+ DefaultVisibility: "public",
+ DefaultFormat: "",
+ CopyScope: true,
+ ThreadInNewTab: false,
+ HideAttachments: false,
+ MaskNSFW: true,
+ NotificationInterval: 0,
+ FluorideMode: false,
+ DarkMode: false,
+ AntiDopamineMode: false,
+ HideUnsupportedNotifs: false,
+ CSS: "",
+ }
+}
diff --git a/model/settings.go b/model/settings.go
deleted file mode 100644
index 1f83c75..0000000
--- a/model/settings.go
+++ /dev/null
@@ -1,33 +0,0 @@
-package model
-
-type Settings struct {
- DefaultVisibility string `json:"default_visibility"`
- DefaultFormat string `json:"default_format"`
- CopyScope bool `json:"copy_scope"`
- ThreadInNewTab bool `json:"thread_in_new_tab"`
- HideAttachments bool `json:"hide_attachments"`
- MaskNSFW bool `json:"mask_nfsw"`
- NotificationInterval int `json:"notifications_interval"`
- FluorideMode bool `json:"fluoride_mode"`
- DarkMode bool `json:"dark_mode"`
- AntiDopamineMode bool `json:"anti_dopamine_mode"`
- HideUnsupportedNotifs bool `json:"hide_unsupported_notifs"`
- CSS string `json:"css"`
-}
-
-func NewSettings() *Settings {
- return &Settings{
- DefaultVisibility: "public",
- DefaultFormat: "",
- CopyScope: true,
- ThreadInNewTab: false,
- HideAttachments: false,
- MaskNSFW: true,
- NotificationInterval: 0,
- FluorideMode: false,
- DarkMode: false,
- AntiDopamineMode: false,
- HideUnsupportedNotifs: false,
- CSS: "",
- }
-}
diff --git a/repo/appRepo.go b/repo/appRepo.go
deleted file mode 100644
index d97ac1f..0000000
--- a/repo/appRepo.go
+++ /dev/null
@@ -1,42 +0,0 @@
-package repo
-
-import (
- "encoding/json"
-
- "bloat/util"
- "bloat/model"
-)
-
-type appRepo struct {
- db *util.Database
-}
-
-func NewAppRepo(db *util.Database) *appRepo {
- return &appRepo{
- db: db,
- }
-}
-
-func (repo *appRepo) Add(a model.App) (err error) {
- data, err := json.Marshal(a)
- if err != nil {
- return
- }
- err = repo.db.Set(a.InstanceDomain, data)
- return
-}
-
-func (repo *appRepo) Get(instanceDomain string) (a model.App, err error) {
- data, err := repo.db.Get(instanceDomain)
- if err != nil {
- err = model.ErrAppNotFound
- return
- }
-
- err = json.Unmarshal(data, &a)
- if err != nil {
- return
- }
-
- return
-}
diff --git a/repo/sessionRepo.go b/repo/sessionRepo.go
deleted file mode 100644
index 2097c3e..0000000
--- a/repo/sessionRepo.go
+++ /dev/null
@@ -1,47 +0,0 @@
-package repo
-
-import (
- "encoding/json"
-
- "bloat/util"
- "bloat/model"
-)
-
-type sessionRepo struct {
- db *util.Database
-}
-
-func NewSessionRepo(db *util.Database) *sessionRepo {
- return &sessionRepo{
- db: db,
- }
-}
-
-func (repo *sessionRepo) Add(s model.Session) (err error) {
- data, err := json.Marshal(s)
- if err != nil {
- return
- }
- err = repo.db.Set(s.ID, data)
- return
-}
-
-func (repo *sessionRepo) Get(id string) (s model.Session, err error) {
- data, err := repo.db.Get(id)
- if err != nil {
- err = model.ErrSessionNotFound
- return
- }
-
- err = json.Unmarshal(data, &s)
- if err != nil {
- return
- }
-
- return
-}
-
-func (repo *sessionRepo) Remove(id string) {
- repo.db.Remove(id)
- return
-}
diff --git a/service/client.go b/service/client.go
new file mode 100644
index 0000000..3affd57
--- /dev/null
+++ b/service/client.go
@@ -0,0 +1,111 @@
+package service
+
+import (
+ "context"
+ "encoding/base64"
+ "encoding/json"
+ "net/http"
+ "strings"
+ "time"
+
+ "bloat/mastodon"
+ "bloat/model"
+ "bloat/renderer"
+)
+
+type client struct {
+ *mastodon.Client
+ w http.ResponseWriter
+ r *http.Request
+ s *model.Session
+ csrf string
+ ctx context.Context
+ rctx *renderer.Context
+}
+
+func (c *client) setSession(sess *model.Session) error {
+ var sb strings.Builder
+ bw := base64.NewEncoder(base64.URLEncoding, &sb)
+ err := json.NewEncoder(bw).Encode(sess)
+ bw.Close()
+ if err != nil {
+ return err
+ }
+ http.SetCookie(c.w, &http.Cookie{
+ Name: "session",
+ Value: sb.String(),
+ Expires: time.Now().Add(365 * 24 * time.Hour),
+ })
+ return nil
+}
+
+func (c *client) getSession() (sess *model.Session, err error) {
+ cookie, _ := c.r.Cookie("session")
+ if cookie == nil {
+ return nil, errInvalidSession
+ }
+ br := base64.NewDecoder(base64.URLEncoding, strings.NewReader(cookie.Value))
+ err = json.NewDecoder(br).Decode(&sess)
+ return
+}
+
+func (c *client) unsetSession() {
+ http.SetCookie(c.w, &http.Cookie{
+ Name: "session",
+ Value: "",
+ Expires: time.Now(),
+ })
+}
+
+func (c *client) writeJson(data interface{}) error {
+ return json.NewEncoder(c.w).Encode(map[string]interface{}{
+ "data": data,
+ })
+}
+
+func (c *client) redirect(url string) {
+ c.w.Header().Add("Location", url)
+ c.w.WriteHeader(http.StatusFound)
+}
+
+func (c *client) authenticate(t int) (err error) {
+ csrf := c.r.FormValue("csrf_token")
+ ref := c.r.URL.RequestURI()
+ defer func() {
+ if c.s == nil {
+ c.s = &model.Session{
+ Settings: *model.NewSettings(),
+ }
+ }
+ c.rctx = &renderer.Context{
+ HideAttachments: c.s.Settings.HideAttachments,
+ MaskNSFW: c.s.Settings.MaskNSFW,
+ ThreadInNewTab: c.s.Settings.ThreadInNewTab,
+ FluorideMode: c.s.Settings.FluorideMode,
+ DarkMode: c.s.Settings.DarkMode,
+ CSRFToken: c.s.CSRFToken,
+ UserID: c.s.UserID,
+ AntiDopamineMode: c.s.Settings.AntiDopamineMode,
+ UserCSS: c.s.Settings.CSS,
+ Referrer: ref,
+ }
+ }()
+ if t < SESSION {
+ return
+ }
+ sess, err := c.getSession()
+ if err != nil {
+ return err
+ }
+ c.s = sess
+ c.Client = mastodon.NewClient(&mastodon.Config{
+ Server: "https://" + c.s.Instance,
+ ClientID: c.s.ClientID,
+ ClientSecret: c.s.ClientSecret,
+ AccessToken: c.s.AccessToken,
+ })
+ if t >= CSRF && (len(csrf) < 1 || csrf != c.s.CSRFToken) {
+ return errInvalidCSRFToken
+ }
+ return
+}
diff --git a/service/service.go b/service/service.go
index cda42f8..432f938 100644
--- a/service/service.go
+++ b/service/service.go
@@ -27,14 +27,11 @@ type service struct {
instance string
postFormats []model.PostFormat
renderer renderer.Renderer
- sessionRepo model.SessionRepo
- appRepo model.AppRepo
}
func NewService(cname string, cscope string, cwebsite string,
css string, instance string, postFormats []model.PostFormat,
- renderer renderer.Renderer, sessionRepo model.SessionRepo,
- appRepo model.AppRepo) *service {
+ renderer renderer.Renderer) *service {
return &service{
cname: cname,
cscope: cscope,
@@ -43,57 +40,9 @@ func NewService(cname string, cscope string, cwebsite string,
instance: instance,
postFormats: postFormats,
renderer: renderer,
- sessionRepo: sessionRepo,
- appRepo: appRepo,
}
}
-func (s *service) authenticate(c *client, sid string, csrf string, ref string, t int) (err error) {
- var sett *model.Settings
- defer func() {
- if sett == nil {
- sett = model.NewSettings()
- }
- c.rctx = &renderer.Context{
- HideAttachments: sett.HideAttachments,
- MaskNSFW: sett.MaskNSFW,
- ThreadInNewTab: sett.ThreadInNewTab,
- FluorideMode: sett.FluorideMode,
- DarkMode: sett.DarkMode,
- CSRFToken: c.s.CSRFToken,
- UserID: c.s.UserID,
- AntiDopamineMode: sett.AntiDopamineMode,
- UserCSS: sett.CSS,
- Referrer: ref,
- }
- }()
- if t < SESSION {
- return
- }
- if len(sid) < 1 {
- return errInvalidSession
- }
- c.s, err = s.sessionRepo.Get(sid)
- if err != nil {
- return errInvalidSession
- }
- sett = &c.s.Settings
- app, err := s.appRepo.Get(c.s.InstanceDomain)
- if err != nil {
- return err
- }
- c.Client = mastodon.NewClient(&mastodon.Config{
- Server: app.InstanceURL,
- ClientID: app.ClientID,
- ClientSecret: app.ClientSecret,
- AccessToken: c.s.AccessToken,
- })
- if t >= CSRF && (len(csrf) < 1 || csrf != c.s.CSRFToken) {
- return errInvalidCSRFToken
- }
- return
-}
-
func (s *service) cdata(c *client, title string, count int, rinterval int,
target string) (data *renderer.CommonData) {
data = &renderer.CommonData{
@@ -820,7 +769,7 @@ func (s *service) SingleInstance() (instance string, ok bool) {
return
}
-func (s *service) NewSession(c *client, instance string) (rurl string, sid string, err error) {
+func (s *service) NewSession(c *client, instance string) (rurl string, sess *model.Session, err error) {
var instanceURL string
if strings.HasPrefix(instance, "https://") {
instanceURL = instance
@@ -829,7 +778,7 @@ func (s *service) NewSession(c *client, instance string) (rurl string, sid strin
instanceURL = "https://" + instance
}
- sid, err = util.NewSessionID()
+ sid, err := util.NewSessionID()
if err != nil {
return
}
@@ -838,42 +787,23 @@ func (s *service) NewSession(c *client, instance string) (rurl string, sid strin
return
}
- sess := model.Session{
- ID: sid,
- InstanceDomain: instance,
- CSRFToken: csrf,
- Settings: *model.NewSettings(),
- }
- err = s.sessionRepo.Add(sess)
+ app, err := mastodon.RegisterApp(c.ctx, &mastodon.AppConfig{
+ Server: instanceURL,
+ ClientName: s.cname,
+ Scopes: s.cscope,
+ Website: s.cwebsite,
+ RedirectURIs: s.cwebsite + "/oauth_callback",
+ })
if err != nil {
return
}
-
- app, err := s.appRepo.Get(instance)
- if err != nil {
- if err != model.ErrAppNotFound {
- return
- }
- mastoApp, err := mastodon.RegisterApp(c.ctx, &mastodon.AppConfig{
- Server: instanceURL,
- ClientName: s.cname,
- Scopes: s.cscope,
- Website: s.cwebsite,
- RedirectURIs: s.cwebsite + "/oauth_callback",
- })
- if err != nil {
- return "", "", err
- }
- app = model.App{
- InstanceDomain: instance,
- InstanceURL: instanceURL,
- ClientID: mastoApp.ClientID,
- ClientSecret: mastoApp.ClientSecret,
- }
- err = s.appRepo.Add(app)
- if err != nil {
- return "", "", err
- }
+ sess = &model.Session{
+ ID: sid,
+ Instance: instance,
+ ClientID: app.ClientID,
+ ClientSecret: app.ClientSecret,
+ CSRFToken: csrf,
+ Settings: *model.NewSettings(),
}
u, err := url.Parse("/oauth/authorize")
@@ -907,12 +837,7 @@ func (s *service) Signin(c *client, code string) (err error) {
}
c.s.AccessToken = c.GetAccessToken(c.ctx)
c.s.UserID = u.ID
- return s.sessionRepo.Add(c.s)
-}
-
-func (s *service) Signout(c *client) (err error) {
- s.sessionRepo.Remove(c.s.ID)
- return
+ return c.setSession(c.s)
}
func (s *service) Post(c *client, content string, replyToID string,
@@ -1044,12 +969,8 @@ func (s *service) SaveSettings(c *client, settings *model.Settings) (err error)
if len(settings.CSS) > 1<<20 {
return errInvalidArgument
}
- sess, err := s.sessionRepo.Get(c.s.ID)
- if err != nil {
- return
- }
- sess.Settings = *settings
- return s.sessionRepo.Add(sess)
+ c.s.Settings = *settings
+ return c.setSession(c.s)
}
func (s *service) MuteConversation(c *client, id string) (err error) {
diff --git a/service/transport.go b/service/transport.go
index 4518b1a..471a7d4 100644
--- a/service/transport.go
+++ b/service/transport.go
@@ -1,25 +1,18 @@
package service
import (
- "context"
"encoding/json"
"log"
"net/http"
"strconv"
"time"
- "bloat/mastodon"
"bloat/model"
- "bloat/renderer"
"github.com/gorilla/mux"
)
const (
- sessionExp = 365 * 24 * time.Hour
-)
-
-const (
HTML int = iota
JSON
)
@@ -30,35 +23,6 @@ const (
CSRF
)
-type client struct {
- *mastodon.Client
- w http.ResponseWriter
- r *http.Request
- s model.Session
- csrf string
- ctx context.Context
- rctx *renderer.Context
-}
-
-func setSessionCookie(w http.ResponseWriter, sid string, exp time.Duration) {
- http.SetCookie(w, &http.Cookie{
- Name: "session_id",
- Value: sid,
- Expires: time.Now().Add(exp),
- })
-}
-
-func writeJson(c *client, data interface{}) error {
- return json.NewEncoder(c.w).Encode(map[string]interface{}{
- "data": data,
- })
-}
-
-func redirect(c *client, url string) {
- c.w.Header().Add("Location", url)
- c.w.WriteHeader(http.StatusFound)
-}
-
func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
r := mux.NewRouter()
@@ -75,16 +39,6 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
}
}
- authenticate := func(c *client, t int) error {
- var sid string
- if cookie, _ := c.r.Cookie("session_id"); cookie != nil {
- sid = cookie.Value
- }
- csrf := c.r.FormValue("csrf_token")
- ref := c.r.URL.RequestURI()
- return s.authenticate(c, sid, csrf, ref, t)
- }
-
handle := func(f func(c *client) error, at int, rt int) http.HandlerFunc {
return func(w http.ResponseWriter, req *http.Request) {
var err error
@@ -108,7 +62,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
}
c.w.Header().Add("Content-Type", ct)
- err = authenticate(c, at)
+ err = c.authenticate(at)
if err != nil {
writeError(c, err, rt, req.Method == http.MethodGet)
return
@@ -123,16 +77,16 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
}
rootPage := handle(func(c *client) error {
- err := authenticate(c, SESSION)
+ err := c.authenticate(SESSION)
if err != nil {
if err == errInvalidSession {
- redirect(c, "/signin")
+ c.redirect("/signin")
return nil
}
return err
}
if !c.s.IsLoggedIn() {
- redirect(c, "/signin")
+ c.redirect("/signin")
return nil
}
return s.RootPage(c)
@@ -147,12 +101,12 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if !ok {
return s.SigninPage(c)
}
- url, sid, err := s.NewSession(c, instance)
+ url, sess, err := s.NewSession(c, instance)
if err != nil {
return err
}
- setSessionCookie(c.w, sid, sessionExp)
- redirect(c, url)
+ c.setSession(sess)
+ c.redirect(url)
return nil
}, NOAUTH, HTML)
@@ -167,7 +121,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
}, SESSION, HTML)
defaultTimelinePage := handle(func(c *client) error {
- redirect(c, "/timeline/home")
+ c.redirect("/timeline/home")
return nil
}, SESSION, HTML)
@@ -243,12 +197,12 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
signin := handle(func(c *client) error {
instance := c.r.FormValue("instance")
- url, sid, err := s.NewSession(c, instance)
+ url, sess, err := s.NewSession(c, instance)
if err != nil {
return err
}
- setSessionCookie(c.w, sid, sessionExp)
- redirect(c, url)
+ c.setSession(sess)
+ c.redirect(url)
return nil
}, NOAUTH, HTML)
@@ -259,7 +213,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- redirect(c, "/")
+ c.redirect("/")
return nil
}, SESSION, HTML)
@@ -287,7 +241,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
} else {
location = c.r.FormValue("referrer")
}
- redirect(c, location)
+ c.redirect(location)
return nil
}, CSRF, HTML)
@@ -301,7 +255,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if len(rid) > 0 {
id = rid
}
- redirect(c, c.r.FormValue("referrer")+"#status-"+id)
+ c.redirect(c.r.FormValue("referrer") + "#status-" + id)
return nil
}, CSRF, HTML)
@@ -315,7 +269,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if len(rid) > 0 {
id = rid
}
- redirect(c, c.r.FormValue("referrer")+"#status-"+id)
+ c.redirect(c.r.FormValue("referrer") + "#status-" + id)
return nil
}, CSRF, HTML)
@@ -329,7 +283,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if len(rid) > 0 {
id = rid
}
- redirect(c, c.r.FormValue("referrer")+"#status-"+id)
+ c.redirect(c.r.FormValue("referrer") + "#status-" + id)
return nil
}, CSRF, HTML)
@@ -343,7 +297,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if len(rid) > 0 {
id = rid
}
- redirect(c, c.r.FormValue("referrer")+"#status-"+id)
+ c.redirect(c.r.FormValue("referrer") + "#status-" + id)
return nil
}, CSRF, HTML)
@@ -355,7 +309,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- redirect(c, c.r.FormValue("referrer")+"#status-"+statusID)
+ c.redirect(c.r.FormValue("referrer") + "#status-" + statusID)
return nil
}, CSRF, HTML)
@@ -371,7 +325,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- redirect(c, c.r.FormValue("referrer"))
+ c.redirect(c.r.FormValue("referrer"))
return nil
}, CSRF, HTML)
@@ -381,7 +335,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- redirect(c, c.r.FormValue("referrer"))
+ c.redirect(c.r.FormValue("referrer"))
return nil
}, CSRF, HTML)
@@ -391,7 +345,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- redirect(c, c.r.FormValue("referrer"))
+ c.redirect(c.r.FormValue("referrer"))
return nil
}, CSRF, HTML)
@@ -401,7 +355,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- redirect(c, c.r.FormValue("referrer"))
+ c.redirect(c.r.FormValue("referrer"))
return nil
}, CSRF, HTML)
@@ -417,7 +371,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- redirect(c, c.r.FormValue("referrer"))
+ c.redirect(c.r.FormValue("referrer"))
return nil
}, CSRF, HTML)
@@ -427,7 +381,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- redirect(c, c.r.FormValue("referrer"))
+ c.redirect(c.r.FormValue("referrer"))
return nil
}, CSRF, HTML)
@@ -437,7 +391,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- redirect(c, c.r.FormValue("referrer"))
+ c.redirect(c.r.FormValue("referrer"))
return nil
}, CSRF, HTML)
@@ -447,7 +401,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- redirect(c, c.r.FormValue("referrer"))
+ c.redirect(c.r.FormValue("referrer"))
return nil
}, CSRF, HTML)
@@ -457,7 +411,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- redirect(c, c.r.FormValue("referrer"))
+ c.redirect(c.r.FormValue("referrer"))
return nil
}, CSRF, HTML)
@@ -467,7 +421,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- redirect(c, c.r.FormValue("referrer"))
+ c.redirect(c.r.FormValue("referrer"))
return nil
}, CSRF, HTML)
@@ -504,7 +458,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- redirect(c, "/")
+ c.redirect("/")
return nil
}, CSRF, HTML)
@@ -514,7 +468,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- redirect(c, c.r.FormValue("referrer"))
+ c.redirect(c.r.FormValue("referrer"))
return nil
}, CSRF, HTML)
@@ -524,7 +478,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- redirect(c, c.r.FormValue("referrer"))
+ c.redirect(c.r.FormValue("referrer"))
return nil
}, CSRF, HTML)
@@ -534,7 +488,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- redirect(c, c.r.FormValue("referrer"))
+ c.redirect(c.r.FormValue("referrer"))
return nil
}, CSRF, HTML)
@@ -545,7 +499,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- redirect(c, c.r.FormValue("referrer"))
+ c.redirect(c.r.FormValue("referrer"))
return nil
}, CSRF, HTML)
@@ -559,7 +513,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if len(rid) > 0 {
id = rid
}
- redirect(c, c.r.FormValue("referrer")+"#status-"+id)
+ c.redirect(c.r.FormValue("referrer") + "#status-" + id)
return nil
}, CSRF, HTML)
@@ -573,7 +527,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if len(rid) > 0 {
id = rid
}
- redirect(c, c.r.FormValue("referrer")+"#status-"+id)
+ c.redirect(c.r.FormValue("referrer") + "#status-" + id)
return nil
}, CSRF, HTML)
@@ -584,7 +538,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- redirect(c, c.r.FormValue("referrer"))
+ c.redirect(c.r.FormValue("referrer"))
return nil
}, CSRF, HTML)
@@ -594,7 +548,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- redirect(c, c.r.FormValue("referrer"))
+ c.redirect(c.r.FormValue("referrer"))
return nil
}, CSRF, HTML)
@@ -608,7 +562,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- redirect(c, c.r.FormValue("referrer"))
+ c.redirect(c.r.FormValue("referrer"))
return nil
}, CSRF, HTML)
@@ -618,7 +572,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- redirect(c, c.r.FormValue("referrer"))
+ c.redirect(c.r.FormValue("referrer"))
return nil
}, CSRF, HTML)
@@ -629,7 +583,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- redirect(c, c.r.FormValue("referrer"))
+ c.redirect(c.r.FormValue("referrer"))
return nil
}, CSRF, HTML)
@@ -648,7 +602,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- redirect(c, c.r.FormValue("referrer"))
+ c.redirect(c.r.FormValue("referrer"))
return nil
}, CSRF, HTML)
@@ -660,14 +614,13 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- redirect(c, c.r.FormValue("referrer"))
+ c.redirect(c.r.FormValue("referrer"))
return nil
}, CSRF, HTML)
signout := handle(func(c *client) error {
- s.Signout(c)
- setSessionCookie(c.w, "", 0)
- redirect(c, "/")
+ c.unsetSession()
+ c.redirect("/")
return nil
}, CSRF, HTML)
@@ -677,7 +630,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- return writeJson(c, count)
+ return c.writeJson(count)
}, CSRF, JSON)
fUnlike := handle(func(c *client) error {
@@ -686,7 +639,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- return writeJson(c, count)
+ return c.writeJson(count)
}, CSRF, JSON)
fRetweet := handle(func(c *client) error {
@@ -695,7 +648,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- return writeJson(c, count)
+ return c.writeJson(count)
}, CSRF, JSON)
fUnretweet := handle(func(c *client) error {
@@ -704,7 +657,7 @@ func NewHandler(s *service, logger *log.Logger, staticDir string) http.Handler {
if err != nil {
return err
}
- return writeJson(c, count)
+ return c.writeJson(count)
}, CSRF, JSON)
r.HandleFunc("/", rootPage).Methods(http.MethodGet)
diff --git a/util/kv.go b/util/kv.go
deleted file mode 100644
index df61654..0000000
--- a/util/kv.go
+++ /dev/null
@@ -1,91 +0,0 @@
-package util
-
-import (
- "errors"
- "io/ioutil"
- "os"
- "path/filepath"
- "strings"
- "sync"
-)
-
-var (
- errInvalidKey = errors.New("invalid key")
- errNoSuchKey = errors.New("no such key")
-)
-
-type Database struct {
- cache map[string][]byte
- basedir string
- m sync.RWMutex
-}
-
-func NewDatabse(basedir string) (db *Database, err error) {
- err = os.Mkdir(basedir, 0755)
- if err != nil && !os.IsExist(err) {
- return
- }
-
- return &Database{
- cache: make(map[string][]byte),
- basedir: basedir,
- }, nil
-}
-
-func (db *Database) Set(key string, val []byte) (err error) {
- if len(key) < 1 || strings.ContainsRune(key, os.PathSeparator) {
- return errInvalidKey
- }
-
- err = ioutil.WriteFile(filepath.Join(db.basedir, key), val, 0644)
- if err != nil {
- return
- }
-
- db.m.Lock()
- db.cache[key] = val
- db.m.Unlock()
-
- return
-}
-
-func (db *Database) Get(key string) (val []byte, err error) {
- if len(key) < 1 || strings.ContainsRune(key, os.PathSeparator) {
- return nil, errInvalidKey
- }
-
- db.m.RLock()
- data, ok := db.cache[key]
- db.m.RUnlock()
-
- if !ok {
- data, err = ioutil.ReadFile(filepath.Join(db.basedir, key))
- if err != nil {
- err = errNoSuchKey
- return nil, err
- }
-
- db.m.Lock()
- db.cache[key] = data
- db.m.Unlock()
- }
-
- val = make([]byte, len(data))
- copy(val, data)
-
- return
-}
-
-func (db *Database) Remove(key string) {
- if len(key) < 1 || strings.ContainsRune(key, os.PathSeparator) {
- return
- }
-
- os.Remove(filepath.Join(db.basedir, key))
-
- db.m.Lock()
- delete(db.cache, key)
- db.m.Unlock()
-
- return
-}