From 1e92d1fd37d2fa2dd99e68082e224b8ed7d634fb Mon Sep 17 00:00:00 2001 From: rtz12 Date: Sun, 13 Nov 2016 03:46:22 +0100 Subject: Userspezifische Anilist-API und Koppelung implementiert diff --git a/charakterin.go b/charakterin.go index 415c94b..2878f1f 100644 --- a/charakterin.go +++ b/charakterin.go @@ -3,13 +3,17 @@ package charakterin import ( "database/sql" "errors" + "fmt" "io/ioutil" "log" "net/http" "net/url" - "time" "regexp" + "time" + + "fagott.pw/goanilist" + "github.com/julienschmidt/httprouter" _ "github.com/lib/pq" ) @@ -22,12 +26,10 @@ const ( // Renderer wird verwendet, um die Routen (bspw. Login-Route) zu rendern. Damit bleibt Charakterin selbst ohne Template. type Renderer interface { - // RenderLoginPage zeigt die Login-Seite an. RenderLoginPage(w http.ResponseWriter, data map[string]interface{}) - // RenderRegistrationPage zeigt die Registrations-Seite an. RenderRegistrationPage(w http.ResponseWriter, data map[string]interface{}) - // RenderUserSettingsPage zeigt die Seite für die Benutzereinstellungen an. RenderUserSettingsPage(w http.ResponseWriter, data map[string]interface{}) + RenderAPICouplePage(w http.ResponseWriter, data map[string]interface{}) } // Charakterin ist das tolle Login- und Accountmanagementsystem. @@ -35,6 +37,9 @@ type Charakterin struct { renderer Renderer FallbackRoute string Database *sql.DB + + anilistClientID string + anilistClientSecret string } var reEmail, _ = regexp.Compile(`(\w[-._\w]*\w@\w[-._\w]*\w\.\w{2,})`) @@ -47,9 +52,8 @@ func New(db *sql.DB) *Charakterin { return nil } return &Charakterin{ - nil, - "/", - db, + FallbackRoute: "/", + Database: db, } } @@ -58,6 +62,11 @@ func (c *Charakterin) UseRenderer(renderer Renderer) { c.renderer = renderer } +func (c *Charakterin) EnableAnilistAPI(id, secret string) { + c.anilistClientID = id + c.anilistClientSecret = secret +} + // DisplayLoginWithData rendert die Loginseite mit Daten (vorheriger Benutzer, Fehlermeldung) func (c *Charakterin) DisplayLoginWithData(w http.ResponseWriter, r *http.Request, data map[string]interface{}) { if c.IsLoggedIn(r) { @@ -386,6 +395,44 @@ func (c *Charakterin) Register(w http.ResponseWriter, r *http.Request) { http.Redirect(w, r, c.FallbackRoute, 302) } +func (c *Charakterin) DisplayAPICouplePage(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { + user, err := c.GetUserFromRequest(r) + if err != nil { + http.Error(w, "403", http.StatusForbidden) + return + } + data := make(map[string]interface{}) + data["user"] = user + data["name"] = ps.ByName("type") + c.renderer.RenderAPICouplePage(w, data) +} + +func (c *Charakterin) CoupleAPI(w http.ResponseWriter, r *http.Request, ps httprouter.Params) { + user, err := c.GetUserFromRequest(r) + if err != nil { + http.Error(w, "403", http.StatusForbidden) + return + } + body, err := readBody(r) + if err != nil { + http.Error(w, "400", http.StatusBadRequest) + return + } + switch ps.ByName("type") { + case "Anilist": + err = user.AnilistClient.CoupleByPin(body["code"][0]) + } + if err != nil { + data := make(map[string]interface{}) + data["user"] = user + data["name"] = ps.ByName("type") + data["error"] = err.Error() + c.renderer.RenderAPICouplePage(w, data) + return + } + http.Redirect(w, r, fmt.Sprintf("/user/%d", user.ID), 302) +} + func (c *Charakterin) GetUserFromRequest(r *http.Request) (*User, error) { cookie, err := r.Cookie("session") if err != nil { @@ -404,14 +451,22 @@ func (c *Charakterin) GetUserFromRequest(r *http.Request) (*User, error) { } user := &User{ - id, - name, - email, - password, - displayName, - lastActivity, - isActive, - r.Header.Get("User-Agent"), + ID: id, + Name: name, + EMail: email, + Password: password, + DisplayName: displayName, + LastActivity: lastActivity, + IsActive: isActive, + Agent: r.Header.Get("User-Agent"), + } + + if c.anilistClientID != "" && c.anilistClientSecret != "" { + user.AnilistClient = goanilist.NewClient( + c.Database, + id, + c.anilistClientID, + c.anilistClientSecret) } return user, nil @@ -424,6 +479,13 @@ func (c *Charakterin) GetUserByID(id int) (*User, error) { if err != nil { return nil, err } + if c.anilistClientID != "" && c.anilistClientSecret != "" { + user.AnilistClient = goanilist.NewClient( + c.Database, + id, + c.anilistClientID, + c.anilistClientSecret) + } return user, nil } diff --git a/user.go b/user.go index 31ec560..cea3420 100644 --- a/user.go +++ b/user.go @@ -3,6 +3,8 @@ package charakterin import ( "database/sql" "time" + + "fagott.pw/goanilist" ) // Ein User ist ein ganz toller Benutzer. @@ -15,6 +17,9 @@ type User struct { LastActivity *time.Time IsActive bool Agent string + + AnilistClient *goanilist.Client + externalServices []ExternalService } // GetName gibt den Anzeigenamen oder wenn dieser nicht gesetzt ist den Benutzernamen zurück. @@ -24,3 +29,43 @@ func (u *User) GetName() string { } return u.Name } + +func (u *User) HasExternalServices() bool { + return u.AnilistClient.IsCoupled +} + +func (u *User) ExternalServices() []ExternalService { + if u.externalServices != nil { + return u.externalServices + } + ss := []ExternalService{} + if u.AnilistClient != nil { + s := ExternalService{ + Name: "Anilist", + IsEnabled: u.AnilistClient.IsCoupled, + AuthType: "copy-paste", + AuthorizeURL: u.AnilistClient.AuthorizeURL(), + CoupleURL: "/settings/api/Anilist/couple", + } + if u.AnilistClient.IsCoupled { + user, err := u.AnilistClient.User() + if err != nil { + s.UserName = err.Error() + } else { + s.UserName = user.DisplayName + } + } + ss = append(ss, s) + } + u.externalServices = ss + return ss +} + +type ExternalService struct { + Name string + IsEnabled bool + AuthType string + AuthorizeURL string + CoupleURL string + UserName string +} -- cgit v0.10.1