Simplify authentication (#660)
This commit is contained in:
parent
f01ed0dc1c
commit
2ee8a854cc
5 changed files with 28 additions and 40 deletions
|
|
@ -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
4
go.mod
|
|
@ -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
5
go.sum
|
|
@ -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=
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue