diff options
Diffstat (limited to 'service/service.go')
-rw-r--r-- | service/service.go | 497 |
1 files changed, 261 insertions, 236 deletions
diff --git a/service/service.go b/service/service.go index 1666959..084993c 100644 --- a/service/service.go +++ b/service/service.go @@ -1,10 +1,8 @@ package service import ( - "context" "errors" "fmt" - "html/template" "mime/multipart" "net/url" "strings" @@ -16,146 +14,152 @@ import ( ) var ( - ctx = context.Background() - errInvalidArgument = errors.New("invalid argument") + errInvalidArgument = errors.New("invalid argument") + errInvalidSession = errors.New("invalid session") + errInvalidCSRFToken = errors.New("invalid csrf token") ) type service struct { - clientName string - clientScope string - clientWebsite string - customCSS string - postFormats []model.PostFormat - renderer renderer.Renderer - sessionRepo model.SessionRepo - appRepo model.AppRepo - singleInstance string -} - -func NewService(clientName string, - clientScope string, - clientWebsite string, - customCSS string, - postFormats []model.PostFormat, - renderer renderer.Renderer, - sessionRepo model.SessionRepo, - appRepo model.AppRepo, - singleInstance string, -) *service { + cname string + cscope string + cwebsite string + css string + 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 { return &service{ - clientName: clientName, - clientScope: clientScope, - clientWebsite: clientWebsite, - customCSS: customCSS, - postFormats: postFormats, - renderer: renderer, - sessionRepo: sessionRepo, - appRepo: appRepo, - singleInstance: singleInstance, - } -} - -func getRendererContext(c *client) *renderer.Context { - var settings model.Settings - var session model.Session - var referrer string - if c != nil { - settings = c.Session.Settings - session = c.Session - referrer = c.url() - } else { - settings = *model.NewSettings() + cname: cname, + cscope: cscope, + cwebsite: cwebsite, + css: css, + 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 } - return &renderer.Context{ - HideAttachments: settings.HideAttachments, - MaskNSFW: settings.MaskNSFW, - ThreadInNewTab: settings.ThreadInNewTab, - FluorideMode: settings.FluorideMode, - DarkMode: settings.DarkMode, - CSRFToken: session.CSRFToken, - UserID: session.UserID, - AntiDopamineMode: settings.AntiDopamineMode, - Referrer: referrer, + if len(sid) < 1 { + return errInvalidSession } -} - -func addToReplyMap(m map[string][]mastodon.ReplyInfo, key interface{}, - val string, number int) { - if key == nil { - return + c.s, err = s.sessionRepo.Get(sid) + if err != nil { + return errInvalidSession } - keyStr, ok := key.(string) - if !ok { - return + sett = &c.s.Settings + app, err := s.appRepo.Get(c.s.InstanceDomain) + if err != nil { + return err } - _, ok = m[keyStr] - if !ok { - m[keyStr] = []mastodon.ReplyInfo{} + 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 } - m[keyStr] = append(m[keyStr], mastodon.ReplyInfo{val, number}) + return } -func (s *service) getCommonData(c *client, title string) (data *renderer.CommonData) { +func (s *service) cdata(c *client, title string, count int, rinterval int, + target string) (data *renderer.CommonData) { data = &renderer.CommonData{ - Title: title + " - " + s.clientName, - CustomCSS: s.customCSS, + Title: title + " - " + s.cname, + CustomCSS: s.css, + Count: count, + RefreshInterval: rinterval, + Target: target, } - if c != nil && c.Session.IsLoggedIn() { - data.CSRFToken = c.Session.CSRFToken + if c != nil && c.s.IsLoggedIn() { + data.CSRFToken = c.s.CSRFToken } return } -func (s *service) ErrorPage(c *client, err error) { +func (s *service) ErrorPage(c *client, err error, retry bool) error { var errStr string + var sessionErr bool if err != nil { errStr = err.Error() + if err == errInvalidSession || err == errInvalidCSRFToken { + sessionErr = true + } } - commonData := s.getCommonData(nil, "error") + cdata := s.cdata(nil, "error", 0, 0, "") data := &renderer.ErrorData{ - CommonData: commonData, - Error: errStr, + CommonData: cdata, + Err: errStr, + Retry: retry, + SessionErr: sessionErr, } - rCtx := getRendererContext(c) - s.renderer.Render(rCtx, c, renderer.ErrorPage, data) + return s.renderer.Render(c.rctx, c.w, renderer.ErrorPage, data) } func (s *service) SigninPage(c *client) (err error) { - commonData := s.getCommonData(nil, "signin") + cdata := s.cdata(nil, "signin", 0, 0, "") data := &renderer.SigninData{ - CommonData: commonData, + CommonData: cdata, } - rCtx := getRendererContext(nil) - return s.renderer.Render(rCtx, c, renderer.SigninPage, data) + return s.renderer.Render(c.rctx, c.w, renderer.SigninPage, data) } func (s *service) RootPage(c *client) (err error) { data := &renderer.RootData{ - Title: s.clientName, + Title: s.cname, } - rCtx := getRendererContext(c) - return s.renderer.Render(rCtx, c, renderer.RootPage, data) + return s.renderer.Render(c.rctx, c.w, renderer.RootPage, data) } func (s *service) NavPage(c *client) (err error) { - u, err := c.GetAccountCurrentUser(ctx) + u, err := c.GetAccountCurrentUser(c.ctx) if err != nil { return } - postContext := model.PostContext{ - DefaultVisibility: c.Session.Settings.DefaultVisibility, - DefaultFormat: c.Session.Settings.DefaultFormat, + pctx := model.PostContext{ + DefaultVisibility: c.s.Settings.DefaultVisibility, + DefaultFormat: c.s.Settings.DefaultFormat, Formats: s.postFormats, } - commonData := s.getCommonData(c, "nav") - commonData.Target = "main" + cdata := s.cdata(c, "nav", 0, 0, "main") data := &renderer.NavData{ User: u, - CommonData: commonData, - PostContext: postContext, + CommonData: cdata, + PostContext: pctx, } - rCtx := getRendererContext(c) - return s.renderer.Render(rCtx, c, renderer.NavPage, data) + return s.renderer.Render(c.rctx, c.w, renderer.NavPage, data) } func (s *service) TimelinePage(c *client, tType string, instance string, @@ -173,21 +177,21 @@ func (s *service) TimelinePage(c *client, tType string, instance string, default: return errInvalidArgument case "home": - statuses, err = c.GetTimelineHome(ctx, &pg) + statuses, err = c.GetTimelineHome(c.ctx, &pg) title = "Timeline" case "direct": - statuses, err = c.GetTimelineDirect(ctx, &pg) + statuses, err = c.GetTimelineDirect(c.ctx, &pg) title = "Direct Timeline" case "local": - statuses, err = c.GetTimelinePublic(ctx, true, "", &pg) + statuses, err = c.GetTimelinePublic(c.ctx, true, "", &pg) title = "Local Timeline" case "remote": if len(instance) > 0 { - statuses, err = c.GetTimelinePublic(ctx, false, instance, &pg) + statuses, err = c.GetTimelinePublic(c.ctx, false, instance, &pg) } title = "Remote Timeline" case "twkn": - statuses, err = c.GetTimelinePublic(ctx, false, "", &pg) + statuses, err = c.GetTimelinePublic(c.ctx, false, "", &pg) title = "The Whole Known Network" } if err != nil { @@ -218,7 +222,7 @@ func (s *service) TimelinePage(c *client, tType string, instance string, nextLink = "/timeline/" + tType + "?" + v.Encode() } - commonData := s.getCommonData(c, tType+" timeline ") + cdata := s.cdata(c, tType+" timeline ", 0, 0, "") data := &renderer.TimelineData{ Title: title, Type: tType, @@ -226,17 +230,31 @@ func (s *service) TimelinePage(c *client, tType string, instance string, Statuses: statuses, NextLink: nextLink, PrevLink: prevLink, - CommonData: commonData, + CommonData: cdata, } + return s.renderer.Render(c.rctx, c.w, renderer.TimelinePage, data) +} - rCtx := getRendererContext(c) - return s.renderer.Render(rCtx, c, renderer.TimelinePage, data) +func addToReplyMap(m map[string][]mastodon.ReplyInfo, key interface{}, + val string, number int) { + if key == nil { + return + } + keyStr, ok := key.(string) + if !ok { + return + } + _, ok = m[keyStr] + if !ok { + m[keyStr] = []mastodon.ReplyInfo{} + } + m[keyStr] = append(m[keyStr], mastodon.ReplyInfo{val, number}) } func (s *service) ThreadPage(c *client, id string, reply bool) (err error) { - var postContext model.PostContext + var pctx model.PostContext - status, err := c.GetStatus(ctx, id) + status, err := c.GetStatus(c.ctx, id) if err != nil { return } @@ -244,26 +262,26 @@ func (s *service) ThreadPage(c *client, id string, reply bool) (err error) { if reply { var content string var visibility string - if c.Session.UserID != status.Account.ID { + if c.s.UserID != status.Account.ID { content += "@" + status.Account.Acct + " " } for i := range status.Mentions { - if status.Mentions[i].ID != c.Session.UserID && + if status.Mentions[i].ID != c.s.UserID && status.Mentions[i].ID != status.Account.ID { content += "@" + status.Mentions[i].Acct + " " } } isDirect := status.Visibility == "direct" - if isDirect || c.Session.Settings.CopyScope { + if isDirect || c.s.Settings.CopyScope { visibility = status.Visibility } else { - visibility = c.Session.Settings.DefaultVisibility + visibility = c.s.Settings.DefaultVisibility } - postContext = model.PostContext{ + pctx = model.PostContext{ DefaultVisibility: visibility, - DefaultFormat: c.Session.Settings.DefaultFormat, + DefaultFormat: c.s.Settings.DefaultFormat, Formats: s.postFormats, ReplyContext: &model.ReplyContext{ InReplyToID: id, @@ -274,7 +292,7 @@ func (s *service) ThreadPage(c *client, id string, reply bool) (err error) { } } - context, err := c.GetStatusContext(ctx, id) + context, err := c.GetStatusContext(c.ctx, id) if err != nil { return } @@ -293,16 +311,14 @@ func (s *service) ThreadPage(c *client, id string, reply bool) (err error) { addToReplyMap(replies, statuses[i].InReplyToID, statuses[i].ID, i+1) } - commonData := s.getCommonData(c, "post by "+status.Account.DisplayName) + cdata := s.cdata(c, "post by "+status.Account.DisplayName, 0, 0, "") data := &renderer.ThreadData{ Statuses: statuses, - PostContext: postContext, + PostContext: pctx, ReplyMap: replies, - CommonData: commonData, + CommonData: cdata, } - - rCtx := getRendererContext(c) - return s.renderer.Render(rCtx, c, renderer.ThreadPage, data) + return s.renderer.Render(c.rctx, c.w, renderer.ThreadPage, data) } func (svc *service) StatusPopup(c *client, id string) (err error) { @@ -315,31 +331,29 @@ func (svc *service) StatusPopup(c *client, id string) (err error) { } func (s *service) LikedByPage(c *client, id string) (err error) { - likers, err := c.GetFavouritedBy(ctx, id, nil) + likers, err := c.GetFavouritedBy(c.ctx, id, nil) if err != nil { return } - commonData := s.getCommonData(c, "likes") + cdata := s.cdata(c, "likes", 0, 0, "") data := &renderer.LikedByData{ - CommonData: commonData, + CommonData: cdata, Users: likers, } - rCtx := getRendererContext(c) - return s.renderer.Render(rCtx, c, renderer.LikedByPage, data) + return s.renderer.Render(c.rctx, c.w, renderer.LikedByPage, data) } func (s *service) RetweetedByPage(c *client, id string) (err error) { - retweeters, err := c.GetRebloggedBy(ctx, id, nil) + retweeters, err := c.GetRebloggedBy(c.ctx, id, nil) if err != nil { return } - commonData := s.getCommonData(c, "retweets") + cdata := s.cdata(c, "retweets", 0, 0, "") data := &renderer.RetweetedByData{ - CommonData: commonData, + CommonData: cdata, Users: retweeters, } - rCtx := getRendererContext(c) - return s.renderer.Render(rCtx, c, renderer.RetweetedByPage, data) + return s.renderer.Render(c.rctx, c.w, renderer.RetweetedByPage, data) } func (s *service) NotificationPage(c *client, maxID string, @@ -355,11 +369,11 @@ func (s *service) NotificationPage(c *client, maxID string, Limit: 20, } - if c.Session.Settings.AntiDopamineMode { + if c.s.Settings.AntiDopamineMode { excludes = []string{"follow", "favourite", "reblog"} } - notifications, err := c.GetNotifications(ctx, &pg, excludes) + notifications, err := c.GetNotifications(c.ctx, &pg, excludes) if err != nil { return } @@ -377,19 +391,16 @@ func (s *service) NotificationPage(c *client, maxID string, nextLink = "/notifications?max_id=" + pg.MaxID } - commonData := s.getCommonData(c, "notifications") - commonData.RefreshInterval = c.Session.Settings.NotificationInterval - commonData.Target = "main" - commonData.Count = unreadCount + cdata := s.cdata(c, "notifications", unreadCount, + c.s.Settings.NotificationInterval, "main") data := &renderer.NotificationData{ Notifications: notifications, UnreadCount: unreadCount, ReadID: readID, NextLink: nextLink, - CommonData: commonData, + CommonData: cdata, } - rCtx := getRendererContext(c) - return s.renderer.Render(rCtx, c, renderer.NotificationPage, data) + return s.renderer.Render(c.rctx, c.w, renderer.NotificationPage, data) } func (s *service) UserPage(c *client, id string, pageType string, @@ -404,15 +415,15 @@ func (s *service) UserPage(c *client, id string, pageType string, Limit: 20, } - user, err := c.GetAccount(ctx, id) + user, err := c.GetAccount(c.ctx, id) if err != nil { return } - isCurrent := c.Session.UserID == user.ID + isCurrent := c.s.UserID == user.ID switch pageType { case "": - statuses, err = c.GetAccountStatuses(ctx, id, false, &pg) + statuses, err = c.GetAccountStatuses(c.ctx, id, false, &pg) if err != nil { return } @@ -421,7 +432,7 @@ func (s *service) UserPage(c *client, id string, pageType string, pg.MaxID) } case "following": - users, err = c.GetAccountFollowing(ctx, id, &pg) + users, err = c.GetAccountFollowing(c.ctx, id, &pg) if err != nil { return } @@ -430,7 +441,7 @@ func (s *service) UserPage(c *client, id string, pageType string, id, pg.MaxID) } case "followers": - users, err = c.GetAccountFollowers(ctx, id, &pg) + users, err = c.GetAccountFollowers(c.ctx, id, &pg) if err != nil { return } @@ -439,7 +450,7 @@ func (s *service) UserPage(c *client, id string, pageType string, id, pg.MaxID) } case "media": - statuses, err = c.GetAccountStatuses(ctx, id, true, &pg) + statuses, err = c.GetAccountStatuses(c.ctx, id, true, &pg) if err != nil { return } @@ -451,7 +462,7 @@ func (s *service) UserPage(c *client, id string, pageType string, if !isCurrent { return errInvalidArgument } - statuses, err = c.GetBookmarks(ctx, &pg) + statuses, err = c.GetBookmarks(c.ctx, &pg) if err != nil { return } @@ -463,7 +474,7 @@ func (s *service) UserPage(c *client, id string, pageType string, if !isCurrent { return errInvalidArgument } - users, err = c.GetMutes(ctx, &pg) + users, err = c.GetMutes(c.ctx, &pg) if err != nil { return } @@ -475,7 +486,7 @@ func (s *service) UserPage(c *client, id string, pageType string, if !isCurrent { return errInvalidArgument } - users, err = c.GetBlocks(ctx, &pg) + users, err = c.GetBlocks(c.ctx, &pg) if err != nil { return } @@ -487,7 +498,7 @@ func (s *service) UserPage(c *client, id string, pageType string, if !isCurrent { return errInvalidArgument } - statuses, err = c.GetFavourites(ctx, &pg) + statuses, err = c.GetFavourites(c.ctx, &pg) if err != nil { return } @@ -499,7 +510,7 @@ func (s *service) UserPage(c *client, id string, pageType string, if !isCurrent { return errInvalidArgument } - users, err = c.GetFollowRequests(ctx, &pg) + users, err = c.GetFollowRequests(c.ctx, &pg) if err != nil { return } @@ -517,7 +528,7 @@ func (s *service) UserPage(c *client, id string, pageType string, } } - commonData := s.getCommonData(c, user.DisplayName) + cdata := s.cdata(c, user.DisplayName+" @"+user.Acct, 0, 0, "") data := &renderer.UserData{ User: user, IsCurrent: isCurrent, @@ -525,10 +536,9 @@ func (s *service) UserPage(c *client, id string, pageType string, Users: users, Statuses: statuses, NextLink: nextLink, - CommonData: commonData, + CommonData: cdata, } - rCtx := getRendererContext(c) - return s.renderer.Render(rCtx, c, renderer.UserPage, data) + return s.renderer.Render(c.rctx, c.w, renderer.UserPage, data) } func (s *service) UserSearchPage(c *client, @@ -537,14 +547,14 @@ func (s *service) UserSearchPage(c *client, var nextLink string var title = "search" - user, err := c.GetAccount(ctx, id) + user, err := c.GetAccount(c.ctx, id) if err != nil { return } var results *mastodon.Results if len(q) > 0 { - results, err = c.Search(ctx, q, "statuses", 20, true, offset, id) + results, err = c.Search(c.ctx, q, "statuses", 20, true, offset, id) if err != nil { return err } @@ -558,44 +568,40 @@ func (s *service) UserSearchPage(c *client, url.QueryEscape(q), offset) } - qq := template.HTMLEscapeString(q) if len(q) > 0 { - title += " \"" + qq + "\"" + title += " \"" + q + "\"" } - commonData := s.getCommonData(c, title) + cdata := s.cdata(c, title, 0, 0, "") data := &renderer.UserSearchData{ - CommonData: commonData, + CommonData: cdata, User: user, - Q: qq, + Q: q, Statuses: results.Statuses, NextLink: nextLink, } - rCtx := getRendererContext(c) - return s.renderer.Render(rCtx, c, renderer.UserSearchPage, data) + return s.renderer.Render(c.rctx, c.w, renderer.UserSearchPage, data) } func (s *service) AboutPage(c *client) (err error) { - commonData := s.getCommonData(c, "about") + cdata := s.cdata(c, "about", 0, 0, "") data := &renderer.AboutData{ - CommonData: commonData, + CommonData: cdata, } - rCtx := getRendererContext(c) - return s.renderer.Render(rCtx, c, renderer.AboutPage, data) + return s.renderer.Render(c.rctx, c.w, renderer.AboutPage, data) } func (s *service) EmojiPage(c *client) (err error) { - emojis, err := c.GetInstanceEmojis(ctx) + emojis, err := c.GetInstanceEmojis(c.ctx) if err != nil { return } - commonData := s.getCommonData(c, "emojis") + cdata := s.cdata(c, "emojis", 0, 0, "") data := &renderer.EmojiData{ Emojis: emojis, - CommonData: commonData, + CommonData: cdata, } - rCtx := getRendererContext(c) - return s.renderer.Render(rCtx, c, renderer.EmojiPage, data) + return s.renderer.Render(c.rctx, c.w, renderer.EmojiPage, data) } func (s *service) SearchPage(c *client, @@ -606,7 +612,7 @@ func (s *service) SearchPage(c *client, var results *mastodon.Results if len(q) > 0 { - results, err = c.Search(ctx, q, qType, 20, true, offset, "") + results, err = c.Search(c.ctx, q, qType, 20, true, offset, "") if err != nil { return err } @@ -621,44 +627,54 @@ func (s *service) SearchPage(c *client, url.QueryEscape(q), qType, offset) } - qq := template.HTMLEscapeString(q) if len(q) > 0 { - title += " \"" + qq + "\"" + title += " \"" + q + "\"" } - commonData := s.getCommonData(c, title) + cdata := s.cdata(c, title, 0, 0, "") data := &renderer.SearchData{ - CommonData: commonData, - Q: qq, + CommonData: cdata, + Q: q, Type: qType, Users: results.Accounts, Statuses: results.Statuses, NextLink: nextLink, } - rCtx := getRendererContext(c) - return s.renderer.Render(rCtx, c, renderer.SearchPage, data) + return s.renderer.Render(c.rctx, c.w, renderer.SearchPage, data) } func (s *service) SettingsPage(c *client) (err error) { - commonData := s.getCommonData(c, "settings") + cdata := s.cdata(c, "settings", 0, 0, "") data := &renderer.SettingsData{ - CommonData: commonData, - Settings: &c.Session.Settings, + CommonData: cdata, + Settings: &c.s.Settings, PostFormats: s.postFormats, } - rCtx := getRendererContext(c) - return s.renderer.Render(rCtx, c, renderer.SettingsPage, data) + return s.renderer.Render(c.rctx, c.w, renderer.SettingsPage, data) +} + +func (svc *service) FiltersPage(c *client) (err error) { + filters, err := c.GetFilters(c.ctx) + if err != nil { + return + } + cdata := svc.cdata(c, "filters", 0, 0, "") + data := &renderer.FiltersData{ + CommonData: cdata, + Filters: filters, + } + return svc.renderer.Render(c.rctx, c.w, renderer.FiltersPage, data) } func (s *service) SingleInstance() (instance string, ok bool) { - if len(s.singleInstance) > 0 { - instance = s.singleInstance + if len(s.instance) > 0 { + instance = s.instance ok = true } return } -func (s *service) NewSession(instance string) (rurl string, sid string, err error) { +func (s *service) NewSession(c *client, instance string) (rurl string, sid string, err error) { var instanceURL string if strings.HasPrefix(instance, "https://") { instanceURL = instance @@ -671,18 +687,18 @@ func (s *service) NewSession(instance string) (rurl string, sid string, err erro if err != nil { return } - csrfToken, err := util.NewCSRFToken() + csrf, err := util.NewCSRFToken() if err != nil { return } - session := model.Session{ + sess := model.Session{ ID: sid, InstanceDomain: instance, - CSRFToken: csrfToken, + CSRFToken: csrf, Settings: *model.NewSettings(), } - err = s.sessionRepo.Add(session) + err = s.sessionRepo.Add(sess) if err != nil { return } @@ -692,12 +708,12 @@ func (s *service) NewSession(instance string) (rurl string, sid string, err erro if err != model.ErrAppNotFound { return } - mastoApp, err := mastodon.RegisterApp(ctx, &mastodon.AppConfig{ + mastoApp, err := mastodon.RegisterApp(c.ctx, &mastodon.AppConfig{ Server: instanceURL, - ClientName: s.clientName, - Scopes: s.clientScope, - Website: s.clientWebsite, - RedirectURIs: s.clientWebsite + "/oauth_callback", + ClientName: s.cname, + Scopes: s.cscope, + Website: s.cwebsite, + RedirectURIs: s.cwebsite + "/oauth_callback", }) if err != nil { return "", "", err @@ -723,36 +739,33 @@ func (s *service) NewSession(instance string) (rurl string, sid string, err erro q.Set("scope", "read write follow") q.Set("client_id", app.ClientID) q.Set("response_type", "code") - q.Set("redirect_uri", s.clientWebsite+"/oauth_callback") + q.Set("redirect_uri", s.cwebsite+"/oauth_callback") u.RawQuery = q.Encode() rurl = instanceURL + u.String() return } -func (s *service) Signin(c *client, code string) (token string, - userID string, err error) { - +func (s *service) Signin(c *client, code string) (err error) { if len(code) < 1 { err = errInvalidArgument return } - err = c.AuthenticateToken(ctx, code, s.clientWebsite+"/oauth_callback") + err = c.AuthenticateToken(c.ctx, code, s.cwebsite+"/oauth_callback") if err != nil { return } - token = c.GetAccessToken(ctx) - - u, err := c.GetAccountCurrentUser(ctx) + u, err := c.GetAccountCurrentUser(c.ctx) if err != nil { return } - userID = u.ID - return + 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.Session.ID) + s.sessionRepo.Remove(c.s.ID) return } @@ -762,7 +775,7 @@ func (s *service) Post(c *client, content string, replyToID string, var mediaIDs []string for _, f := range files { - a, err := c.UploadMediaFromMultipartFileHeader(ctx, f) + a, err := c.UploadMediaFromMultipartFileHeader(c.ctx, f) if err != nil { return "", err } @@ -777,7 +790,7 @@ func (s *service) Post(c *client, content string, replyToID string, Visibility: visibility, Sensitive: isNSFW, } - st, err := c.PostStatus(ctx, tweet) + st, err := c.PostStatus(c.ctx, tweet) if err != nil { return } @@ -785,7 +798,7 @@ func (s *service) Post(c *client, content string, replyToID string, } func (s *service) Like(c *client, id string) (count int64, err error) { - st, err := c.Favourite(ctx, id) + st, err := c.Favourite(c.ctx, id) if err != nil { return } @@ -794,7 +807,7 @@ func (s *service) Like(c *client, id string) (count int64, err error) { } func (s *service) UnLike(c *client, id string) (count int64, err error) { - st, err := c.Unfavourite(ctx, id) + st, err := c.Unfavourite(c.ctx, id) if err != nil { return } @@ -803,7 +816,7 @@ func (s *service) UnLike(c *client, id string) (count int64, err error) { } func (s *service) Retweet(c *client, id string) (count int64, err error) { - st, err := c.Reblog(ctx, id) + st, err := c.Reblog(c.ctx, id) if err != nil { return } @@ -815,7 +828,7 @@ func (s *service) Retweet(c *client, id string) (count int64, err error) { func (s *service) UnRetweet(c *client, id string) ( count int64, err error) { - st, err := c.Unreblog(ctx, id) + st, err := c.Unreblog(c.ctx, id) if err != nil { return } @@ -824,55 +837,55 @@ func (s *service) UnRetweet(c *client, id string) ( } func (s *service) Vote(c *client, id string, choices []string) (err error) { - _, err = c.Vote(ctx, id, choices) + _, err = c.Vote(c.ctx, id, choices) return } func (s *service) Follow(c *client, id string, reblogs *bool) (err error) { - _, err = c.AccountFollow(ctx, id, reblogs) + _, err = c.AccountFollow(c.ctx, id, reblogs) return } func (s *service) UnFollow(c *client, id string) (err error) { - _, err = c.AccountUnfollow(ctx, id) + _, err = c.AccountUnfollow(c.ctx, id) return } func (s *service) Accept(c *client, id string) (err error) { - return c.FollowRequestAuthorize(ctx, id) + return c.FollowRequestAuthorize(c.ctx, id) } func (s *service) Reject(c *client, id string) (err error) { - return c.FollowRequestReject(ctx, id) + return c.FollowRequestReject(c.ctx, id) } func (s *service) Mute(c *client, id string) (err error) { - _, err = c.AccountMute(ctx, id) + _, err = c.AccountMute(c.ctx, id) return } func (s *service) UnMute(c *client, id string) (err error) { - _, err = c.AccountUnmute(ctx, id) + _, err = c.AccountUnmute(c.ctx, id) return } func (s *service) Block(c *client, id string) (err error) { - _, err = c.AccountBlock(ctx, id) + _, err = c.AccountBlock(c.ctx, id) return } func (s *service) UnBlock(c *client, id string) (err error) { - _, err = c.AccountUnblock(ctx, id) + _, err = c.AccountUnblock(c.ctx, id) return } func (s *service) Subscribe(c *client, id string) (err error) { - _, err = c.Subscribe(ctx, id) + _, err = c.Subscribe(c.ctx, id) return } func (s *service) UnSubscribe(c *client, id string) (err error) { - _, err = c.UnSubscribe(ctx, id) + _, err = c.UnSubscribe(c.ctx, id) return } @@ -882,38 +895,50 @@ func (s *service) SaveSettings(c *client, settings *model.Settings) (err error) default: return errInvalidArgument } - session, err := s.sessionRepo.Get(c.Session.ID) + if len(settings.CSS) > 1<<20 { + return errInvalidArgument + } + sess, err := s.sessionRepo.Get(c.s.ID) if err != nil { return } - session.Settings = *settings - return s.sessionRepo.Add(session) + sess.Settings = *settings + return s.sessionRepo.Add(sess) } func (s *service) MuteConversation(c *client, id string) (err error) { - _, err = c.MuteConversation(ctx, id) + _, err = c.MuteConversation(c.ctx, id) return } func (s *service) UnMuteConversation(c *client, id string) (err error) { - _, err = c.UnmuteConversation(ctx, id) + _, err = c.UnmuteConversation(c.ctx, id) return } func (s *service) Delete(c *client, id string) (err error) { - return c.DeleteStatus(ctx, id) + return c.DeleteStatus(c.ctx, id) } func (s *service) ReadNotifications(c *client, maxID string) (err error) { - return c.ReadNotifications(ctx, maxID) + return c.ReadNotifications(c.ctx, maxID) } func (s *service) Bookmark(c *client, id string) (err error) { - _, err = c.Bookmark(ctx, id) + _, err = c.Bookmark(c.ctx, id) return } func (s *service) UnBookmark(c *client, id string) (err error) { - _, err = c.Unbookmark(ctx, id) + _, err = c.Unbookmark(c.ctx, id) return } + +func (svc *service) Filter(c *client, phrase string, wholeWord bool) (err error) { + fctx := []string{"home", "notifications", "public", "thread"} + return c.AddFilter(c.ctx, phrase, fctx, true, wholeWord, nil) +} + +func (svc *service) UnFilter(c *client, id string) (err error) { + return c.RemoveFilter(c.ctx, id) +} |