More fixes

This commit is contained in:
James Mills
2021-01-30 15:26:24 +10:00
parent 401f635b3b
commit 8495ba0319
8 changed files with 15 additions and 304 deletions

View File

@@ -34,16 +34,13 @@ var (
type API struct {
router *Router
config *Config
cache *Cache
archive Archiver
db Store
pm passwords.Passwords
tasks *Dispatcher
}
// NewAPI ...
func NewAPI(router *Router, config *Config, cache *Cache, archive Archiver, db Store, pm passwords.Passwords, tasks *Dispatcher) *API {
api := &API{router, config, cache, archive, db, pm, tasks}
func NewAPI(router *Router, config *Config, db Store, pm passwords.Passwords) *API {
api := &API{router, config, db, pm}
api.initRoutes()
@@ -54,11 +51,6 @@ func (a *API) initRoutes() {
router := a.router.Group("/api/v1")
router.GET("/ping", a.PingEndpoint())
router.POST("/auth", a.AuthEndpoint())
// Support / Report endpoints
router.POST("/support", a.isAuthorized(a.SupportEndpoint()))
router.POST("/report", a.isAuthorized(a.ReportEndpoint()))
}
// CreateToken ...
@@ -116,14 +108,6 @@ func (a *API) getLoggedInUser(r *http.Request) *User {
return nil
}
// Every registered new user follows themselves
// TODO: Make this configurable server behaviour?
if user.Following == nil {
user.Following = make(map[string]string)
}
user.Following[user.Username] = user.URL
return user
}
@@ -154,13 +138,6 @@ func (a *API) isAuthorized(endpoint httprouter.Handle) httprouter.Handle {
return
}
// Every registered new user follows themselves
// TODO: Make this configurable server behaviour?
if user.Following == nil {
user.Following = make(map[string]string)
}
user.Following[user.Username] = user.URL
ctx := context.WithValue(r.Context(), TokenContextKey, token)
ctx = context.WithValue(ctx, UserContextKey, user)

View File

@@ -77,79 +77,6 @@ func (bs *BitcaskStore) DelFeed(name string) error {
return bs.db.Delete(key)
}
func (bs *BitcaskStore) GetFeed(name string) (*Feed, error) {
key := []byte(fmt.Sprintf("%s/%s", feedsKeyPrefix, name))
data, err := bs.db.Get(key)
if err == bitcask.ErrKeyNotFound {
return nil, ErrFeedNotFound
}
return LoadFeed(data)
}
func (bs *BitcaskStore) SetFeed(name string, feed *Feed) error {
data, err := feed.Bytes()
if err != nil {
return err
}
key := []byte(fmt.Sprintf("%s/%s", feedsKeyPrefix, name))
if err := bs.db.Put(key, data); err != nil {
return err
}
return nil
}
func (bs *BitcaskStore) LenFeeds() int64 {
var count int64
if err := bs.db.Scan([]byte(feedsKeyPrefix), func(_ []byte) error {
count++
return nil
}); err != nil {
log.WithError(err).Error("error scanning")
}
return count
}
func (bs *BitcaskStore) SearchFeeds(prefix string) []string {
var keys []string
if err := bs.db.Scan([]byte(feedsKeyPrefix), func(key []byte) error {
if strings.HasPrefix(strings.ToLower(string(key)), prefix) {
keys = append(keys, strings.TrimPrefix(string(key), "/feeds/"))
}
return nil
}); err != nil {
log.WithError(err).Error("error scanning")
}
return keys
}
func (bs *BitcaskStore) GetAllFeeds() ([]*Feed, error) {
var feeds []*Feed
err := bs.db.Scan([]byte(feedsKeyPrefix), func(key []byte) error {
data, err := bs.db.Get(key)
if err != nil {
return err
}
feed, err := LoadFeed(data)
if err != nil {
return err
}
feeds = append(feeds, feed)
return nil
})
if err != nil {
return nil, err
}
return feeds, nil
}
func (bs *BitcaskStore) HasUser(username string) bool {
key := []byte(fmt.Sprintf("%s/%s", usersKeyPrefix, username))
return bs.db.Has(key)

View File

@@ -3,7 +3,6 @@ package internal
import (
"html/template"
"net/http"
"strings"
log "github.com/sirupsen/logrus"
"github.com/vcraescu/go-paginator"
@@ -116,16 +115,5 @@ func NewContext(conf *Config, db Store, req *http.Request) *Context {
ctx.IsAdmin = true
}
// Set the theme based on user preferences
theme := strings.ToLower(ctx.User.Theme)
switch theme {
case "", "auto":
ctx.Theme = ""
case "light", "dark":
ctx.Theme = theme
default:
log.WithField("name", theme).Warn("invalid theme found")
}
return ctx
}

View File

@@ -28,18 +28,15 @@ func init() {
StartupJobs = map[string]JobSpec{}
}
type JobFactory func(conf *Config, blogs *BlogsCache, cache *Cache, archive Archiver, store Store) cron.Job
type JobFactory func(conf *Config, store Store) cron.Job
type SyncStoreJob struct {
conf *Config
blogs *BlogsCache
cache *Cache
archive Archiver
db Store
}
func NewSyncStoreJob(conf *Config, blogs *BlogsCache, cache *Cache, archive Archiver, db Store) cron.Job {
return &SyncStoreJob{conf: conf, blogs: blogs, cache: cache, archive: archive, db: db}
func NewSyncStoreJob(conf *Config, db Store) cron.Job {
return &SyncStoreJob{conf: conf, db: db}
}
func (job *SyncStoreJob) Run() {

View File

@@ -2,8 +2,6 @@ package internal
import (
"encoding/json"
"fmt"
"net/url"
"time"
"github.com/creasty/defaults"
@@ -73,12 +71,7 @@ func LoadUser(data []byte) (user *User, err error) {
}
func (u *User) String() string {
url, err := url.Parse(u.URL)
if err != nil {
log.WithError(err).Warn("error parsing user url")
return u.Username
}
return fmt.Sprintf("%s@%s", u.Username, url.Hostname())
}
// HasToken will add a token to a user if it doesn't exist already

View File

@@ -2,7 +2,6 @@ package internal
import (
"net/url"
"regexp"
"time"
)
@@ -174,14 +173,6 @@ func WithAdminEmail(adminEmail string) Option {
}
}
// WithFeedSources sets the feed sources to use for external feeds
func WithFeedSources(feedSources []string) Option {
return func(cfg *Config) error {
cfg.FeedSources = feedSources
return nil
}
}
// WithName sets the instance's name
func WithName(name string) Option {
return func(cfg *Config) error {
@@ -206,14 +197,6 @@ func WithTheme(theme string) Option {
}
}
// WithOpenRegistrations sets the open registrations flag
func WithOpenRegistrations(openRegistrations bool) Option {
return func(cfg *Config) error {
cfg.OpenRegistrations = openRegistrations
return nil
}
}
// WithCookieSecret sets the server's cookie secret
func WithCookieSecret(secret string) Option {
return func(cfg *Config) error {
@@ -246,14 +229,6 @@ func WithSessionExpiry(expiry time.Duration) Option {
}
}
// WithTranscoderTimeout sets the video transcoding timeout
func WithTranscoderTimeout(timeout time.Duration) Option {
return func(cfg *Config) error {
cfg.TranscoderTimeout = timeout
return nil
}
}
// WithMagicLinkSecret sets the MagicLinkSecert used to create password reset tokens
func WithMagicLinkSecret(secret string) Option {
return func(cfg *Config) error {
@@ -262,22 +237,6 @@ func WithMagicLinkSecret(secret string) Option {
}
}
// WithSMTPBind sets the interface and port to bind to for SMTP
func WithSMTPBind(smtpBind string) Option {
return func(cfg *Config) error {
cfg.SMTPBind = smtpBind
return nil
}
}
// WithPOP3Bind sets the interface and port to use for POP3
func WithPOP3Bind(pop3Bind string) Option {
return func(cfg *Config) error {
cfg.POP3Bind = pop3Bind
return nil
}
}
// WithSMTPHost sets the SMTPHost to use for sending email
func WithSMTPHost(host string) Option {
return func(cfg *Config) error {
@@ -318,14 +277,6 @@ func WithSMTPFrom(from string) Option {
}
}
// WithMaxFetchLimit sets the maximum feed fetch limit in bytes
func WithMaxFetchLimit(limit int64) Option {
return func(cfg *Config) error {
cfg.MaxFetchLimit = limit
return nil
}
}
// WithAPISessionTime sets the API session time for tokens
func WithAPISessionTime(duration time.Duration) Option {
return func(cfg *Config) error {
@@ -341,17 +292,3 @@ func WithAPISigningKey(key string) Option {
return nil
}
}
// WithWhitelistedDomains sets the list of domains whitelisted and permitted for external iamges
func WithWhitelistedDomains(whitelistedDomains []string) Option {
return func(cfg *Config) error {
for _, whitelistedDomain := range whitelistedDomains {
re, err := regexp.Compile(whitelistedDomain)
if err != nil {
return err
}
cfg.whitelistedDomains = append(cfg.whitelistedDomains, re)
}
return nil
}
}

View File

@@ -41,27 +41,12 @@ type Server struct {
router *Router
server *http.Server
// Blogs Cache
blogs *BlogsCache
// Messages Cache
msgs *MessagesCache
// Feed Cache
cache *Cache
// Feed Archiver
archive Archiver
// Data Store
db Store
// Scheduler
cron *cron.Cron
// Dispatcher
tasks *Dispatcher
// Auth
am *auth.Manager
@@ -72,21 +57,11 @@ type Server struct {
// API
api *API
// POP3 Service
pop3Service *POP3Service
// SMTP Service
smtpService *SMTPService
// Passwords
pm passwords.Passwords
}
func (s *Server) render(name string, w http.ResponseWriter, ctx *Context) {
if ctx.Authenticated && ctx.Username != "" {
ctx.NewMessages = s.msgs.Get(ctx.User.Username)
}
buf, err := s.tmplman.Exec(name, ctx)
if err != nil {
http.Error(w, err.Error(), http.StatusInternalServerError)
@@ -112,8 +87,6 @@ func (s *Server) AddShutdownHook(f func()) {
// Shutdown ...
func (s *Server) Shutdown(ctx context.Context) error {
s.cron.Stop()
s.tasks.Stop()
s.smtpService.Stop()
if err := s.server.Shutdown(ctx); err != nil {
log.WithError(err).Error("error shutting down server")
@@ -190,13 +163,6 @@ func (s *Server) setupMetrics() {
)
// database keys
metrics.NewGaugeFunc(
"db", "feeds",
"Number of database /feeds keys",
func() float64 {
return float64(s.db.LenFeeds())
},
)
metrics.NewGaugeFunc(
"db", "sessions",
"Number of database /sessions keys",
@@ -264,7 +230,7 @@ func (s *Server) setupCronJobs() error {
continue
}
job := jobSpec.Factory(s.config, s.blogs, s.cache, s.archive, s.db)
job := jobSpec.Factory(s.config, s.db)
if err := s.cron.AddJob(jobSpec.Schedule, job); err != nil {
return err
}
@@ -279,7 +245,7 @@ func (s *Server) runStartupJobs() {
log.Info("running startup jobs")
for name, jobSpec := range StartupJobs {
job := jobSpec.Factory(s.config, s.blogs, s.cache, s.archive, s.db)
job := jobSpec.Factory(s.config, s.db)
log.Infof("running %s now...", name)
job.Run()
}
@@ -380,38 +346,6 @@ func NewServer(bind string, options ...Option) (*Server, error) {
return nil, fmt.Errorf("error validating config: %w", err)
}
blogs, err := LoadBlogsCache(config.Data)
if err != nil {
log.WithError(err).Error("error loading blogs cache (re-creating)")
blogs = NewBlogsCache()
log.Info("updating blogs cache")
blogs.UpdateBlogs(config)
}
if len(blogs.Blogs) == 0 {
log.Info("empty blogs cache, updating...")
blogs.UpdateBlogs(config)
}
msgs, err := LoadMessagesCache(config.Data)
if err != nil {
log.WithError(err).Error("error loading messages cache (re-creating)")
msgs = NewMessagesCache()
}
log.Info("updating messages cache")
msgs.Refresh(config)
cache, err := LoadCache(config.Data)
if err != nil {
log.WithError(err).Error("error loading feed cache")
return nil, err
}
archive, err := NewDiskArchiver(filepath.Join(config.Data, archiveDir))
if err != nil {
log.WithError(err).Error("error creating feed archiver")
return nil, err
}
db, err := NewStore(config.Store)
if err != nil {
log.WithError(err).Error("error creating store")
@@ -433,8 +367,6 @@ func NewServer(bind string, options ...Option) (*Server, error) {
am := auth.NewManager(auth.NewOptions("/login", "/register"))
tasks := NewDispatcher(10, 100) // TODO: Make this configurable?
pm := passwords.NewScryptPasswords(nil)
sc := NewSessionStore(db, config.SessionCacheTTL)
@@ -449,11 +381,7 @@ func NewServer(bind string, options ...Option) (*Server, error) {
sc,
)
api := NewAPI(router, config, cache, archive, db, pm, tasks)
pop3Service := NewPOP3Service(config, db, pm, msgs, tasks)
smtpService := NewSMTPService(config, db, pm, msgs, tasks)
api := NewAPI(router, config, db, pm)
csrfHandler := nosurf.New(router)
csrfHandler.ExemptGlob("/api/v1/*")
@@ -479,33 +407,12 @@ func NewServer(bind string, options ...Option) (*Server, error) {
// API
api: api,
// POP3 Servicee
pop3Service: pop3Service,
// SMTP Servicee
smtpService: smtpService,
// Blogs Cache
blogs: blogs,
// Messages Cache
msgs: msgs,
// Feed Cache
cache: cache,
// Feed Archiver
archive: archive,
// Data Store
db: db,
// Schedular
cron: cron.New(),
// Dispatcher
tasks: tasks,
// Auth Manager
am: am,
@@ -527,12 +434,6 @@ func NewServer(bind string, options ...Option) (*Server, error) {
server.tasks.Start()
log.Info("started task dispatcher")
server.pop3Service.Start()
log.Info("started POP3 service")
server.smtpService.Start()
log.Info("started SMTP service")
server.setupMetrics()
log.Infof("serving metrics endpoint at %s/metrics", server.config.BaseURL)

View File

@@ -11,7 +11,6 @@ var (
ErrInvalidStore = errors.New("error: invalid store")
ErrUserNotFound = errors.New("error: user not found")
ErrTokenNotFound = errors.New("error: token not found")
ErrFeedNotFound = errors.New("error: feed not found")
ErrInvalidSession = errors.New("error: invalid session")
)
@@ -20,14 +19,6 @@ type Store interface {
Close() error
Sync() error
DelFeed(name string) error
HasFeed(name string) bool
GetFeed(name string) (*Feed, error)
SetFeed(name string, user *Feed) error
LenFeeds() int64
SearchFeeds(prefix string) []string
GetAllFeeds() ([]*Feed, error)
DelUser(username string) error
HasUser(username string) bool
GetUser(username string) (*User, error)