From f1c2249744fafccc9f80ac14feeb748e840c276e Mon Sep 17 00:00:00 2001 From: dhax Date: Wed, 4 Oct 2017 02:52:19 +0200 Subject: [PATCH] moves claims into models --- auth/handler.go | 15 ++++++++++++-- auth/jwt.go | 52 +++++++++++++++++++++-------------------------- email/auth.go | 2 +- email/email.go | 6 +++--- models/account.go | 9 ++++++++ models/token.go | 8 ++++++++ 6 files changed, 57 insertions(+), 35 deletions(-) diff --git a/auth/handler.go b/auth/handler.go index cd01415..40a41e6 100644 --- a/auth/handler.go +++ b/auth/handler.go @@ -144,7 +144,12 @@ func (rs *Resource) token(w http.ResponseWriter, r *http.Request) { return } - access, refresh := rs.Token.GenTokenPair(acc, token) + access, refresh, err := rs.Token.GenTokenPair(acc.Claims(), token.Claims()) + if err != nil { + log(r).Error(err) + render.Render(w, r, ErrInternalServerError) + return + } acc.LastLogin = time.Now() if err := rs.store.UpdateAccount(acc); err != nil { @@ -183,7 +188,13 @@ func (rs *Resource) refresh(w http.ResponseWriter, r *http.Request) { token.Expiry = time.Now().Add(time.Minute * rs.Token.jwtRefreshExpiry) token.UpdatedAt = time.Now() - access, refresh := rs.Token.GenTokenPair(acc, token) + access, refresh, err := rs.Token.GenTokenPair(acc.Claims(), token.Claims()) + if err != nil { + log(r).Error(err) + render.Render(w, r, ErrInternalServerError) + return + } + if err := rs.store.SaveRefreshToken(token); err != nil { log(r).Error(err) render.Render(w, r, ErrInternalServerError) diff --git a/auth/jwt.go b/auth/jwt.go index e737ad2..e4be29a 100644 --- a/auth/jwt.go +++ b/auth/jwt.go @@ -4,7 +4,6 @@ import ( "net/http" "time" - "github.com/dhax/go-base/models" "github.com/go-chi/jwtauth" "github.com/spf13/viper" ) @@ -44,38 +43,33 @@ func (a *TokenAuth) Verifier() func(http.Handler) http.Handler { return jwtauth.Verifier(a.JwtAuth) } -// GenTokenPair returns both an access token and a refresh token for provided account. -func (a *TokenAuth) GenTokenPair(u *models.Account, tok *models.Token) (string, string) { - access := a.CreateJWT(u) - refresh := a.CreateRefreshJWT(tok) - return access, refresh +// GenTokenPair returns both an access token and a refresh token. +func (a *TokenAuth) GenTokenPair(ca jwtauth.Claims, cr jwtauth.Claims) (string, string, error) { + access, err := a.CreateJWT(ca) + if err != nil { + return "", "", err + } + refresh, err := a.CreateRefreshJWT(cr) + if err != nil { + return "", "", err + } + return access, refresh, nil } -// CreateJWT returns an access token for provided account. -func (a *TokenAuth) CreateJWT(acc *models.Account) string { - claims := jwtauth.Claims{ - "id": acc.ID, - "sub": acc.Name, - "roles": acc.Roles, - } - claims.SetIssuedNow() - claims.SetExpiryIn(a.jwtExpiry * time.Minute) - - _, tokenString, _ := a.JwtAuth.Encode(claims) - return tokenString +// CreateJWT returns an access token for provided account claims. +func (a *TokenAuth) CreateJWT(c jwtauth.Claims) (string, error) { + c.SetIssuedNow() + c.SetExpiryIn(a.jwtExpiry * time.Minute) + _, tokenString, err := a.JwtAuth.Encode(c) + return tokenString, err } -// CreateRefreshJWT returns a refresh token for provided account. -func (a *TokenAuth) CreateRefreshJWT(tok *models.Token) string { - claims := jwtauth.Claims{ - "id": tok.ID, - "token": tok.Token, - } - claims.SetIssuedNow() - claims.SetExpiryIn(time.Minute * a.jwtRefreshExpiry) - - _, tokenString, _ := a.JwtAuth.Encode(claims) - return tokenString +// CreateRefreshJWT returns a refresh token for provided token Claims. +func (a *TokenAuth) CreateRefreshJWT(c jwtauth.Claims) (string, error) { + c.SetIssuedNow() + c.SetExpiryIn(time.Minute * a.jwtRefreshExpiry) + _, tokenString, err := a.JwtAuth.Encode(c) + return tokenString, err } func parseClaims(c jwtauth.Claims) (AppClaims, bool) { diff --git a/email/auth.go b/email/auth.go index 8660465..5c42040 100644 --- a/email/auth.go +++ b/email/auth.go @@ -13,7 +13,7 @@ type ContentLoginToken struct { // LoginToken creates and sends a login token email with provided template content. func (m *Mailer) LoginToken(name, address string, content ContentLoginToken) error { - msg := &Mail{ + msg := &message{ from: NewEmail(m.fromName, m.from), to: NewEmail(name, address), subject: "Login Token", diff --git a/email/email.go b/email/email.go index 94240fa..e0dc91f 100644 --- a/email/email.go +++ b/email/email.go @@ -59,7 +59,7 @@ func NewMailer() (*Mailer, error) { } // Send parses the corrsponding template and sends the mail via smtp. -func (m *Mailer) Send(mail *Mail) error { +func (m *Mailer) Send(mail *message) error { buf := new(bytes.Buffer) if err := m.templates.ExecuteTemplate(buf, mail.template, mail.content); err != nil { return err @@ -95,8 +95,8 @@ func (m *Mailer) Send(mail *Mail) error { return nil } -// Mail struct holds all parts of a specific email. -type Mail struct { +// message struct holds all parts of a specific email message. +type message struct { from *Email to *Email subject string diff --git a/models/account.go b/models/account.go index 31e0d7a..5e73f8b 100644 --- a/models/account.go +++ b/models/account.go @@ -5,6 +5,7 @@ import ( "strings" "time" + "github.com/go-chi/jwtauth" validation "github.com/go-ozzo/ozzo-validation" "github.com/go-ozzo/ozzo-validation/is" "github.com/go-pg/pg/orm" @@ -70,6 +71,14 @@ func (a *Account) CanLogin() bool { return a.Active } +func (a *Account) Claims() jwtauth.Claims { + return jwtauth.Claims{ + "id": a.ID, + "sub": a.Name, + "roles": a.Roles, + } +} + // AccountFilter provides pagination and filtering options on accounts. type AccountFilter struct { orm.Pager diff --git a/models/token.go b/models/token.go index 63b435f..381fc4c 100644 --- a/models/token.go +++ b/models/token.go @@ -3,6 +3,7 @@ package models import ( "time" + "github.com/go-chi/jwtauth" "github.com/go-pg/pg/orm" ) @@ -34,3 +35,10 @@ func (t *Token) BeforeUpdate(db orm.DB) error { t.UpdatedAt = time.Now() return nil } + +func (t *Token) Claims() jwtauth.Claims { + return jwtauth.Claims{ + "id": t.ID, + "token": t.Token, + } +}