package internal import ( "fmt" "html/template" "net/http" "strings" log "github.com/sirupsen/logrus" "github.com/vcraescu/go-paginator" "git.mills.io/prologic/spyda" "git.mills.io/prologic/spyda/internal/session" "git.mills.io/prologic/spyda/types" "github.com/justinas/nosurf" "github.com/theplant-retired/timezones" ) type Meta struct { Title string Description string UpdatedAt string Image string Author string URL string Keywords string } type Context struct { Config string Debug bool BaseURL string InstanceName string SoftwareVersion string TwtsPerPage int TwtPrompt string MaxTwtLength int RegisterDisabled bool OpenProfiles bool RegisterDisabledMessage string Timezones []*timezones.Zoneinfo Reply string Username string User *User Tokens []*Token LastTwt types.Twt Profile types.Profile Authenticated bool IsAdmin bool Error bool Message string Theme string Commit string Page string Content template.HTML Title string Meta Meta Links types.Links Alternatives types.Alternatives Messages Messages NewMessages int Twter types.Twter Twts types.Twts BlogPost *BlogPost BlogPosts BlogPosts Feeds []*Feed FeedSources FeedSourceMap Pager *paginator.Paginator // Report abuse ReportNick string ReportURL string // Reset Password Token PasswordResetToken string // CSRF Token CSRFToken string } func NewContext(conf *Config, db Store, req *http.Request) *Context { ctx := &Context{ Debug: conf.Debug, BaseURL: conf.BaseURL, InstanceName: conf.Name, SoftwareVersion: spyda.FullVersion(), TwtsPerPage: conf.TwtsPerPage, TwtPrompt: conf.RandomTwtPrompt(), MaxTwtLength: conf.MaxTwtLength, RegisterDisabled: !conf.OpenRegistrations, OpenProfiles: conf.OpenProfiles, LastTwt: types.NilTwt, Commit: spyda.Commit, Theme: conf.Theme, Timezones: timezones.AllZones, Title: "", Meta: Meta{ Title: DefaultMetaTitle, Author: DefaultMetaAuthor, Keywords: DefaultMetaKeywords, Description: conf.Description, }, Alternatives: types.Alternatives{ types.Alternative{ Type: "application/atom+xml", Title: fmt.Sprintf("%s local feed", conf.Name), URL: fmt.Sprintf("%s/atom.xml", conf.BaseURL), }, }, } ctx.CSRFToken = nosurf.Token(req) if sess := req.Context().Value(session.SessionKey); sess != nil { if username, ok := sess.(*session.Session).Get("username"); ok { ctx.Authenticated = true ctx.Username = username } } if ctx.Authenticated && ctx.Username != "" { user, err := db.GetUser(ctx.Username) if err != nil { log.WithError(err).Warnf("error loading user object for %s", ctx.Username) } ctx.Twter = types.Twter{ Nick: user.Username, URL: URLForUser(conf, user.Username), } ctx.User = user tokens, err := db.GetUserTokens(user) if err != nil { log.WithError(err).Warnf("error loading tokens for %s", ctx.Username) } ctx.Tokens = tokens } else { ctx.User = &User{} ctx.Twter = types.Twter{} } if ctx.Username == conf.AdminUser { 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 }