Simplify authentication (#660)

This commit is contained in:
andig 2021-02-11 17:24:01 +01:00 • committed by GitHub
parent f01ed0dc1c
commit 2ee8a854cc
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 28 additions and 40 deletions

View file

@ -51,12 +51,7 @@ func generateToken(user, pass string) {
client.DeviceHandler(codePrompt)
ts, err := client.Login(user, pass)
if err != nil {
log.FATAL.Fatalln(err)
}
token, err := ts.Token()
token, err := client.Login(user, pass)
if err != nil {
log.FATAL.Fatalln(err)
}

4
go.mod
View file

@ -8,6 +8,7 @@ require (
github.com/asaskevich/EventBus v0.0.0-20200907212545-49d423059eef
github.com/avast/retry-go v3.0.0+incompatible
github.com/benbjohnson/clock v1.0.3
github.com/bogosj/tesla v0.0.0-20210211144207-92a50058e036
github.com/containrrr/shoutrrr v0.4.0
github.com/denisbrodbeck/machineid v1.0.1
github.com/eclipse/paho.mqtt.golang v1.3.1
@ -31,7 +32,6 @@ require (
github.com/itchyny/gojq v0.12.1
github.com/jeremywohl/flatten v1.0.1
github.com/joeshaw/carwings v0.0.0-20191118152321-61b46581307a
github.com/jsgoecke/tesla v0.0.0-20200530171421-e02ebd220e5a
github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51
github.com/koron/go-ssdp v0.0.2
github.com/korylprince/ipnetgen v1.0.0
@ -62,5 +62,3 @@ require (
)
replace github.com/spf13/viper => github.com/andig/viper v1.6.3-0.20201123175942-a5af09afab5b
replace github.com/jsgoecke/tesla => github.com/andig/tesla v0.0.0-20210203084021-0d6f2d3bb496

5
go.sum
View file

@ -47,8 +47,6 @@ github.com/andig/evcc-config v0.0.0-20210210171605-531c04a6bb59/go.mod h1:N0hIjI
github.com/andig/gosunspec v0.0.0-20200429133549-3cf6a82fed9c/go.mod h1:YkshK8WMzYn1iXAZzHUO75gIqhMSan2ctgBVtBkRIyA=
github.com/andig/gosunspec v0.0.0-20201103081418-ec9af6feefde h1:QgUO3swXFjTXjqT+EA1k7XZbTxtl8AenEckO0UF3Dfw=
github.com/andig/gosunspec v0.0.0-20201103081418-ec9af6feefde/go.mod h1:YkshK8WMzYn1iXAZzHUO75gIqhMSan2ctgBVtBkRIyA=
github.com/andig/tesla v0.0.0-20210203084021-0d6f2d3bb496 h1:+rbLd40c9NzFQKJNd4QxF7Wz/ZotfrBTTp9mwugFvXA=
github.com/andig/tesla v0.0.0-20210203084021-0d6f2d3bb496/go.mod h1:Iu7IX0ScvW2BhZeJhH9lEyUMKRst4LnvPhrwa+dpdjM=
github.com/andig/viper v1.6.3-0.20201123175942-a5af09afab5b h1:n3O7DTcqZzpl8/6zVCCkHYbc/zyTfXQCk4xaTAkQ5aE=
github.com/andig/viper v1.6.3-0.20201123175942-a5af09afab5b/go.mod h1:6ISKOGKh+gHA6RIFKvIhSS7V8qY41Gi2LG6QyIJVuCs=
github.com/andybalholm/cascadia v1.1.0 h1:BuuO6sSfQNFRu1LppgbD25Hr2vLYW25JvxHs5zzsLTo=
@ -65,6 +63,8 @@ github.com/beorn7/perks v0.0.0-20180321164747-3a771d992973/go.mod h1:Dwedo/Wpr24
github.com/beorn7/perks v1.0.0/go.mod h1:KWe93zE9D1o94FZ5RNwFwVgaQK1VOXiVxmqh+CedLV8=
github.com/beorn7/perks v1.0.1 h1:VlbKKnNfV8bJzeqoa4cOKqO6bYr3WgKZxO8Z16+hsOM=
github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6rlkpw=
github.com/bogosj/tesla v0.0.0-20210211144207-92a50058e036 h1:bkSWyrNev6+gvKxa1ZlH5i8MfNHsEVn3go1S9aCi6Y0=
github.com/bogosj/tesla v0.0.0-20210211144207-92a50058e036/go.mod h1:KT8NxKXUX5A0v1wX4PXGJqK1+J1BywYDgGhVruqzlmI=
github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU=
github.com/cespare/xxhash/v2 v2.1.1 h1:6MnRN8NT7+YBpUIWxHtefFZOKTAPgGjpQSxqLNn0+qY=
github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs=
@ -285,6 +285,7 @@ github.com/jeremywohl/flatten v1.0.1/go.mod h1:4AmD/VxjWcI5SRB0n6szE2A6s2fsNHDLO
github.com/joeshaw/carwings v0.0.0-20191118152321-61b46581307a h1:wOlcxK/k5rPhtMyEFVayqVh0x3lWvnyEaK8Aw96zx4M=
github.com/joeshaw/carwings v0.0.0-20191118152321-61b46581307a/go.mod h1:tB0OlpicmRVTL1Vksc5XRiYo+wkK2kl/GI7eGMIl6Rs=
github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo=
github.com/jsgoecke/tesla v0.0.0-20200530171421-e02ebd220e5a/go.mod h1:GlLJU/C6KA3FEAIZTFDvIDlNGE1+YlKGHHXdNVkt5ow=
github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU=
github.com/json-iterator/go v1.1.9 h1:9yzud/Ht36ygwatGx56VwCZtlI/2AD15T1X2sjSuGns=
github.com/json-iterator/go v1.1.9/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=

View file

@ -1,6 +1,7 @@
package vehicle
import (
"context"
"errors"
"fmt"
"strings"
@ -11,7 +12,7 @@ import (
"github.com/andig/evcc/util"
"github.com/andig/evcc/util/request"
auth "github.com/andig/evcc/vehicle/tesla"
"github.com/jsgoecke/tesla"
"github.com/bogosj/tesla"
"golang.org/x/oauth2"
)
@ -64,18 +65,19 @@ func NewTeslaFromConfig(other map[string]interface{}) (api.Vehicle, error) {
return nil, err
}
ts, err := tokenSource(authClient, cc.User, cc.Password, cc.Tokens)
token, err := teslaToken(authClient, cc.User, cc.Password, cc.Tokens)
if err != nil {
return nil, fmt.Errorf("login failed: %w", err)
}
client, err := tesla.NewClient(&tesla.Auth{
TokenSource: ts,
HTTPClient: request.NewHelper(log),
})
if err != nil {
return nil, err
}
// authenticated http client with logging
ctx := context.Background()
http := authClient.Config.Client(ctx, token)
http.Transport = request.NewTripper(log, http.Transport)
// injected to the Tesla client
client := &tesla.Client{HTTP: http}
tesla.ActiveClient = client
vehicles, err := client.Vehicles()
if err != nil {
@ -103,30 +105,31 @@ func NewTeslaFromConfig(other map[string]interface{}) (api.Vehicle, error) {
}
// token creates the Tesla access token
func tokenSource(auth *auth.Client, user, password string, tokens teslaTokens) (oauth2.TokenSource, error) {
func teslaToken(auth *auth.Client, user, password string, tokens teslaTokens) (*oauth2.Token, error) {
// without tokens try to login - will fail if MFA enabled
if tokens.Access == "" {
ts, err := auth.Login(user, password)
token, err := auth.Login(user, password)
if err != nil {
err = fmt.Errorf("%w: if using multi-factor authentication, create tokens using `evcc tesla-token`", err)
}
return ts, err
return token, err
}
// create tokensource with given tokens
ts := auth.TokenSource(&oauth2.Token{
ctx := context.Background()
ts := auth.Config.TokenSource(ctx, &oauth2.Token{
AccessToken: tokens.Access,
RefreshToken: tokens.Refresh,
})
// test the token source
_, err := ts.Token()
token, err := ts.Token()
if err != nil {
err = fmt.Errorf("%w: token refresh failed, check access and refresh tokens are valid", err)
}
return ts, err
return token, err
}
// chargeState implements the api.Vehicle interface

View file

@ -18,7 +18,7 @@ import (
// Client is the tesla authentication client
type Client struct {
config *oauth2.Config
Config *oauth2.Config
auth *tesla.Auth
verifier string
}
@ -76,7 +76,7 @@ func NewClient(log *util.Logger) (*Client, error) {
}
client := &Client{
config: config,
Config: config,
auth: auth,
verifier: verifier,
}
@ -86,27 +86,18 @@ func NewClient(log *util.Logger) (*Client, error) {
}
// Login executes the MFA or non-MFA login
func (c *Client) Login(username, password string) (oauth2.TokenSource, error) {
func (c *Client) Login(username, password string) (*oauth2.Token, error) {
ctx := context.Background()
code, err := c.auth.Do(ctx, username, password)
if err != nil {
return nil, err
}
token, err := c.config.Exchange(ctx, code,
token, err := c.Config.Exchange(ctx, code,
oauth2.SetAuthURLParam("code_verifier", c.verifier),
)
if err != nil {
return nil, fmt.Errorf("exchange: %w", err)
}
return c.TokenSource(token), nil
}
// TokenSource creates an oauth tokensource from given token
func (c *Client) TokenSource(token *oauth2.Token) oauth2.TokenSource {
ctx := context.Background()
return c.config.TokenSource(ctx, token)
return token, err
}
// DeviceHandler sets an alternative authentication device handler