You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
67 lines
1.7 KiB
Go
67 lines
1.7 KiB
Go
package mobilizon
|
|
|
|
import (
|
|
"context"
|
|
"encoding/base64"
|
|
"encoding/json"
|
|
"net/http"
|
|
"strings"
|
|
"time"
|
|
|
|
gql "github.com/hasura/go-graphql-client"
|
|
)
|
|
|
|
type bearerTokenTransport string
|
|
|
|
func (t bearerTokenTransport) RoundTrip(req *http.Request) (*http.Response, error) {
|
|
req.Header.Add("Authorization", "Bearer "+string(t))
|
|
return http.DefaultTransport.RoundTrip(req)
|
|
}
|
|
|
|
func (c *MobilizonClient) Authorize(email, pass string) (*User, error) {
|
|
var mut struct {
|
|
Login Login `graphql:"login(email: $email, password: $pass)"`
|
|
}
|
|
vars := map[string]interface{}{"email": String(email), "pass": String(pass)}
|
|
err := c.client.Mutate(context.Background(), &mut, vars)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
c.applyAuth(mut.Login.Auth)
|
|
return &mut.Login.User, nil
|
|
}
|
|
|
|
func (c *MobilizonClient) applyAuth(auth Auth) {
|
|
// FIXME: should set a mutex!
|
|
c.httpClient = &http.Client{
|
|
Transport: bearerTokenTransport(auth.AccessToken),
|
|
}
|
|
c.refreshToken = auth.RefreshToken
|
|
c.client = gql.NewClient(c.url, c.httpClient)
|
|
go func() {
|
|
time.Sleep(jwtExpiresIn(string(auth.AccessToken)) - 10*time.Second)
|
|
c.reauthorize(c.refreshToken)
|
|
}()
|
|
}
|
|
|
|
func (c *MobilizonClient) reauthorize(refreshToken String) error {
|
|
var mut struct {
|
|
Auth Auth `graphql:"refreshToken(refreshToken: $t)"`
|
|
}
|
|
vars := map[string]interface{}{"t": refreshToken}
|
|
err := c.client.Mutate(context.Background(), &mut, vars)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
c.applyAuth(mut.Auth)
|
|
return nil
|
|
}
|
|
|
|
func jwtExpiresIn(token string) time.Duration {
|
|
jwtParts := strings.Split(token, ".")
|
|
jwtJson, _ := base64.RawStdEncoding.DecodeString(jwtParts[1])
|
|
var jwt struct{ Exp int64 }
|
|
json.Unmarshal([]byte(jwtJson), &jwt)
|
|
return time.Unix(jwt.Exp, 0).Sub(time.Now())
|
|
}
|