chore: remove unused code (#31088)
This commit is contained in:
parent
6cd76d78bc
commit
be75289a3b
12 changed files with 0 additions and 629 deletions
|
|
@ -170,9 +170,6 @@ func ForwarderRules() []ForwarderRule {
|
|||
return forwarderRules
|
||||
}
|
||||
|
||||
// StartForwarder is a no-op; hooks fire on every charger connection.
|
||||
func StartForwarder() {}
|
||||
|
||||
// actionsRelayedToUpstream lists actions for which upstream is the authoritative
|
||||
// Central System: evcc's handler is bypassed and upstream's reply relayed back.
|
||||
var actionsRelayedToUpstream = map[string]bool{
|
||||
|
|
|
|||
|
|
@ -1,51 +0,0 @@
|
|||
package oauth
|
||||
|
||||
import (
|
||||
"time"
|
||||
|
||||
"github.com/evcc-io/evcc/util"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
// Refresh refreshes the token every 5m. If token refresh fails 5 times, it is aborted.
|
||||
func Refresh(log *util.Logger, token *oauth2.Token, ts oauth2.TokenSource, optMaxTokenLifetime ...time.Duration) {
|
||||
var failed int
|
||||
|
||||
// limit lifetime of initial token
|
||||
limitTokenLife(token, optMaxTokenLifetime...)
|
||||
|
||||
for range time.Tick(5 * time.Minute) {
|
||||
// get token- either previous or new
|
||||
t, err := ts.Token()
|
||||
if err != nil {
|
||||
// error means refresh failed
|
||||
failed++
|
||||
if failed > 5 {
|
||||
log.ERROR.Printf("token refresh: %v, giving up", err)
|
||||
return
|
||||
}
|
||||
|
||||
log.ERROR.Printf("token refresh: %v", err)
|
||||
continue
|
||||
}
|
||||
|
||||
failed = 0
|
||||
|
||||
// limit lifetime of new tokens
|
||||
if t.Expiry != token.Expiry {
|
||||
token = t
|
||||
limitTokenLife(token, optMaxTokenLifetime...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func limitTokenLife(token *oauth2.Token, optMaxTokenLifetime ...time.Duration) {
|
||||
if len(optMaxTokenLifetime) != 1 {
|
||||
return
|
||||
}
|
||||
|
||||
maxTokenLifetime := optMaxTokenLifetime[0]
|
||||
if time.Until(token.Expiry) > maxTokenLifetime {
|
||||
token.Expiry = time.Now().Add(maxTokenLifetime)
|
||||
}
|
||||
}
|
||||
|
|
@ -16,15 +16,6 @@ func Copy(q url.Values) url.Values {
|
|||
return res
|
||||
}
|
||||
|
||||
// Merge copies multiple from url values into to
|
||||
func Merge(to url.Values, from ...url.Values) {
|
||||
for _, vv := range from {
|
||||
for k, v := range vv {
|
||||
to[k] = append(to[k], v...)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Require verifies that url contains the required non-nil values
|
||||
func Require(q url.Values, keys ...string) error {
|
||||
for _, k := range keys {
|
||||
|
|
|
|||
|
|
@ -1,132 +0,0 @@
|
|||
package mb
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/http/cookiejar"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/evcc-io/evcc/util"
|
||||
"github.com/evcc-io/evcc/util/request"
|
||||
"github.com/samber/lo"
|
||||
"golang.org/x/net/publicsuffix"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
// https://github.com/TA2k/ioBroker.smart-eq
|
||||
|
||||
// https://id.mercedes-benz.com/.well-known/openid-configuration
|
||||
const OAuthURI = "https://id.mercedes-benz.com"
|
||||
|
||||
type Identity struct {
|
||||
*request.Helper
|
||||
oc *oauth2.Config
|
||||
oauth2.TokenSource
|
||||
}
|
||||
|
||||
// NewIdentity creates Mercedes Benz identity
|
||||
func NewIdentity(log *util.Logger, oc *oauth2.Config) *Identity {
|
||||
return &Identity{
|
||||
Helper: request.NewHelper(log),
|
||||
oc: oc,
|
||||
}
|
||||
}
|
||||
|
||||
func (v *Identity) Login(user, password string) error {
|
||||
if v.Client.Jar == nil {
|
||||
v.Client.Jar, _ = cookiejar.New(&cookiejar.Options{
|
||||
PublicSuffixList: publicsuffix.List,
|
||||
})
|
||||
}
|
||||
|
||||
var param request.InterceptResult
|
||||
v.Client.CheckRedirect, param = request.InterceptRedirect("resume", false)
|
||||
|
||||
cv := oauth2.GenerateVerifier()
|
||||
|
||||
state := lo.RandomString(16, lo.AlphanumericCharset)
|
||||
uri := v.oc.AuthCodeURL(state, oauth2.AccessTypeOffline, oauth2.S256ChallengeOption(cv))
|
||||
if _, err := v.Get(uri); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
resume, err := param()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
v.Client.CheckRedirect = nil
|
||||
|
||||
data := struct {
|
||||
Username string `json:"username"`
|
||||
Password string `json:"password,omitempty"`
|
||||
RememberMe bool `json:"rememberMe,omitempty"`
|
||||
}{
|
||||
Username: user,
|
||||
}
|
||||
|
||||
var res struct {
|
||||
Result, Token string
|
||||
Errors []struct{ Key string }
|
||||
}
|
||||
|
||||
uri = fmt.Sprintf("%s/ciam/auth/login/user", OAuthURI)
|
||||
req, err := request.New(http.MethodPost, uri, request.MarshalJSON(data), request.JSONEncoding)
|
||||
if err == nil {
|
||||
if err = v.DoJSON(req, &res); err != nil && len(res.Errors) > 0 {
|
||||
err = fmt.Errorf("%s: %w", res.Errors[0].Key, err)
|
||||
}
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
data.Password = password
|
||||
data.RememberMe = true
|
||||
|
||||
uri = fmt.Sprintf("%s/ciam/auth/login/pass", OAuthURI)
|
||||
req, err = request.New(http.MethodPost, uri, request.MarshalJSON(data), request.JSONEncoding)
|
||||
if err == nil {
|
||||
if err = v.DoJSON(req, &res); err != nil && len(res.Errors) > 0 {
|
||||
err = fmt.Errorf("%s: %w", res.Errors[0].Key, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if err == nil && res.Token == "" && res.Result != "" {
|
||||
err = fmt.Errorf("missing token: %s", res.Result)
|
||||
}
|
||||
|
||||
var code string
|
||||
if err == nil {
|
||||
params := url.Values{
|
||||
"token": {res.Token},
|
||||
}
|
||||
|
||||
var param request.InterceptResult
|
||||
v.Client.CheckRedirect, param = request.InterceptRedirect("code", true)
|
||||
|
||||
uri := OAuthURI + resume
|
||||
if _, err = v.Post(uri, request.FormContent, strings.NewReader(params.Encode())); err == nil {
|
||||
code, err = param()
|
||||
}
|
||||
|
||||
v.Client.CheckRedirect = nil
|
||||
}
|
||||
|
||||
var token *oauth2.Token
|
||||
if err == nil {
|
||||
ctx, cancel := context.WithTimeout(
|
||||
context.WithValue(context.Background(), oauth2.HTTPClient, v.Client),
|
||||
request.Timeout)
|
||||
defer cancel()
|
||||
|
||||
token, err = v.oc.Exchange(ctx, code, oauth2.VerifierOption(cv))
|
||||
}
|
||||
|
||||
if err == nil {
|
||||
v.TokenSource = v.oc.TokenSource(context.Background(), token)
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
|
@ -1,8 +1,6 @@
|
|||
package mercedes
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"html"
|
||||
"time"
|
||||
)
|
||||
|
||||
|
|
@ -12,19 +10,6 @@ var Regions = map[string]string{
|
|||
"noram": "North-America",
|
||||
}
|
||||
|
||||
type ErrorInfo struct {
|
||||
ErrorCode int
|
||||
ErrorMessage string
|
||||
ErrorDetails string
|
||||
}
|
||||
|
||||
func (e ErrorInfo) Error() error {
|
||||
if e.ErrorCode == 0 {
|
||||
return nil
|
||||
}
|
||||
return fmt.Errorf("%s: %s", e.ErrorMessage, html.UnescapeString(e.ErrorDetails))
|
||||
}
|
||||
|
||||
type PinRequest struct {
|
||||
EmailOrPhoneNumber string `json:"emailOrPhoneNumber"`
|
||||
CountryCode string `json:"countryCode"`
|
||||
|
|
|
|||
|
|
@ -1,102 +0,0 @@
|
|||
package smart
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/evcc-io/evcc/util"
|
||||
"github.com/evcc-io/evcc/util/request"
|
||||
"github.com/evcc-io/evcc/util/transport"
|
||||
"github.com/evcc-io/evcc/vehicle/mb"
|
||||
"github.com/samber/lo"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
// https://github.com/TA2k/ioBroker.smart-eq
|
||||
|
||||
const ApiURI = "https://oneapp.microservice.smart.mercedes-benz.com/seqc/v0"
|
||||
|
||||
var OAuth2Config = &oauth2.Config{
|
||||
ClientID: "70d89501-938c-4bec-82d0-6abb550b0825",
|
||||
RedirectURL: "https://oneapp.microservice.smart.mercedes-benz.com",
|
||||
Endpoint: oauth2.Endpoint{
|
||||
AuthURL: mb.OAuthURI + "/as/authorization.oauth2",
|
||||
TokenURL: mb.OAuthURI + "/as/token.oauth2",
|
||||
},
|
||||
Scopes: []string{"openid", "profile", "email", "phone", "ciam-uid", "offline_access"},
|
||||
}
|
||||
|
||||
type API struct {
|
||||
*request.Helper
|
||||
}
|
||||
|
||||
func NewAPI(log *util.Logger, identity oauth2.TokenSource) *API {
|
||||
v := &API{
|
||||
Helper: request.NewHelper(log),
|
||||
}
|
||||
|
||||
// replace client transport with authenticated transport
|
||||
v.Client.Transport = &transport.Decorator{
|
||||
Base: &oauth2.Transport{
|
||||
Source: identity,
|
||||
Base: v.Client.Transport,
|
||||
},
|
||||
Decorator: transport.DecorateHeaders(map[string]string{
|
||||
"accept": "*/*",
|
||||
"accept-language": "de-DE;q=1.0",
|
||||
"guid": "280C6B55-F179-4428-88B6-E0CCF5C22A7C",
|
||||
"x-applicationname": OAuth2Config.ClientID,
|
||||
}),
|
||||
}
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func (v *API) Vehicles() ([]string, error) {
|
||||
type vehicle struct {
|
||||
FIN string
|
||||
}
|
||||
|
||||
var res struct {
|
||||
Authorizations, LicensePlates []vehicle
|
||||
Error string
|
||||
ErrorDescription string `json:"error_description"`
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s/users/current", ApiURI)
|
||||
err := v.GetJSON(uri, &res)
|
||||
if err != nil && res.Error != "" {
|
||||
err = fmt.Errorf("%s (%s): %w", res.Error, res.ErrorDescription, err)
|
||||
}
|
||||
|
||||
vehicles := lo.Map(res.LicensePlates, func(v vehicle, _ int) string {
|
||||
return v.FIN
|
||||
})
|
||||
|
||||
return vehicles, err
|
||||
}
|
||||
|
||||
func (v *API) Status(vin string) (StatusResponse, error) {
|
||||
var res StatusResponse
|
||||
|
||||
uri := fmt.Sprintf("%s/vehicles/%s/init-data?requestedData=BOTH&countryCode=DE&locale=de-DE", ApiURI, vin)
|
||||
err := v.GetJSON(uri, &res)
|
||||
|
||||
if err != nil && res.Error != "" {
|
||||
err = fmt.Errorf("%s (%s): %w", res.Error, res.ErrorDescription, err)
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
||||
func (v *API) Refresh(vin string) (StatusResponse, error) {
|
||||
var res StatusResponse
|
||||
|
||||
uri := fmt.Sprintf("%s/vehicles/%s/refresh-data", ApiURI, vin)
|
||||
err := v.GetJSON(uri, &res)
|
||||
|
||||
if err != nil && res.Error != "" {
|
||||
err = fmt.Errorf("%s (%s): %w", res.Error, res.ErrorDescription, err)
|
||||
}
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
|
@ -1,99 +0,0 @@
|
|||
package smart
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
|
||||
"github.com/evcc-io/evcc/api"
|
||||
"github.com/evcc-io/evcc/util"
|
||||
)
|
||||
|
||||
// https://github.com/TA2k/ioBroker.smart-eq
|
||||
|
||||
type Provider struct {
|
||||
statusG func() (StatusResponse, error)
|
||||
expiry time.Duration
|
||||
}
|
||||
|
||||
func NewProvider(log *util.Logger, api *API, vin string, expiry, cache time.Duration) *Provider {
|
||||
v := &Provider{
|
||||
expiry: expiry,
|
||||
}
|
||||
|
||||
v.statusG = util.Cached(func() (StatusResponse, error) {
|
||||
return v.status(
|
||||
func() (StatusResponse, error) { return api.Status(vin) },
|
||||
func() (StatusResponse, error) { return api.Refresh(vin) },
|
||||
)
|
||||
}, cache)
|
||||
|
||||
return v
|
||||
}
|
||||
|
||||
func (v *Provider) status(statusG, refreshG func() (StatusResponse, error)) (StatusResponse, error) {
|
||||
res, err := statusG()
|
||||
|
||||
// if ts := res.Status.Data.Soc.Ts.Time; err == nil && ts.Add(v.expiry).Before(time.Now()) {
|
||||
// fmt.Println("--------------------------", ts)
|
||||
// res, err = refreshG()
|
||||
// ts := res.Status.Data.Soc.Ts.Time
|
||||
// fmt.Println("--------------------------", ts)
|
||||
// }
|
||||
|
||||
return res, err
|
||||
}
|
||||
|
||||
// Soc implements the api.Vehicle interface
|
||||
func (v *Provider) Soc() (float64, error) {
|
||||
res, err := v.statusG()
|
||||
return res.Status.Data.Soc.Value, err
|
||||
}
|
||||
|
||||
var _ api.ChargeState = (*Provider)(nil)
|
||||
|
||||
// Range implements the api.VehicleRange interface
|
||||
func (v *Provider) Status() (api.ChargeStatus, error) {
|
||||
res, err := v.statusG()
|
||||
if err != nil {
|
||||
return api.StatusNone, err
|
||||
}
|
||||
|
||||
cs := res.PreCond.Data.ChargingStatus
|
||||
if cs.Status != 0 {
|
||||
return api.StatusNone, fmt.Errorf("unknown status/value: %d/%d", cs.Status, cs.Value)
|
||||
}
|
||||
|
||||
// confirmed status/value/active combinations (https://github.com/evcc-io/evcc/discussions/5596#discussioncomment-4556035)
|
||||
// 0/0/active: charging
|
||||
// 0/2/*: connected
|
||||
// 0/3/*: disconnected
|
||||
switch cs.Value {
|
||||
case 0:
|
||||
if res.PreCond.Data.ChargingActive.Value {
|
||||
return api.StatusC, nil
|
||||
}
|
||||
return api.StatusB, nil
|
||||
case 1, 2:
|
||||
return api.StatusB, nil
|
||||
case 3:
|
||||
return api.StatusA, nil
|
||||
default:
|
||||
return api.StatusNone, fmt.Errorf("unknown status/value: %d/%d", cs.Status, cs.Value)
|
||||
}
|
||||
}
|
||||
|
||||
var _ api.VehicleRange = (*Provider)(nil)
|
||||
|
||||
// Range implements the api.VehicleRange interface
|
||||
func (v *Provider) Range() (int64, error) {
|
||||
res, err := v.statusG()
|
||||
return int64(res.Status.Data.RangeElectric.Value), err
|
||||
}
|
||||
|
||||
var _ api.VehicleOdometer = (*Provider)(nil)
|
||||
|
||||
// Odometer implements the api.VehicleOdometer interface
|
||||
func (v *Provider) Odometer() (float64, error) {
|
||||
res, err := v.statusG()
|
||||
return res.Status.Data.Odo.Value, err
|
||||
}
|
||||
|
|
@ -1,61 +0,0 @@
|
|||
package smart
|
||||
|
||||
import (
|
||||
"strconv"
|
||||
"time"
|
||||
)
|
||||
|
||||
type StatusResponse struct {
|
||||
PreCond struct {
|
||||
Data struct {
|
||||
ChargingPower FloatValue
|
||||
ChargingActive BoolValue
|
||||
ChargingStatus IntValue
|
||||
} `json:"data"`
|
||||
}
|
||||
Status struct {
|
||||
Data struct {
|
||||
Odo FloatValue
|
||||
RangeElectric FloatValue
|
||||
Soc FloatValue
|
||||
} `json:"data"`
|
||||
}
|
||||
Images []string
|
||||
Error string
|
||||
ErrorDescription string `json:"error_description"`
|
||||
}
|
||||
|
||||
type BoolValue struct {
|
||||
Status int
|
||||
Value bool
|
||||
Ts TimeSecs
|
||||
}
|
||||
|
||||
type IntValue struct {
|
||||
Status int
|
||||
Value int
|
||||
Ts TimeSecs
|
||||
}
|
||||
|
||||
type FloatValue struct {
|
||||
Status int
|
||||
Value float64
|
||||
Ts TimeSecs
|
||||
}
|
||||
|
||||
// TimeSecs implements JSON unmarshal for Unix timestamps in seconds
|
||||
type TimeSecs struct {
|
||||
time.Time
|
||||
}
|
||||
|
||||
// UnmarshalJSON decodes unix timestamps in ms into time.Time
|
||||
func (ct *TimeSecs) UnmarshalJSON(data []byte) error {
|
||||
i, err := strconv.ParseInt(string(data), 10, 64)
|
||||
|
||||
if err == nil {
|
||||
t := time.Unix(i, 0)
|
||||
ct.Time = t
|
||||
}
|
||||
|
||||
return err
|
||||
}
|
||||
|
|
@ -70,10 +70,6 @@ func NewAPI(log *util.Logger, identity *Identity) *API {
|
|||
return v
|
||||
}
|
||||
|
||||
func (v *API) IDToken() string {
|
||||
return v.identity.IDToken()
|
||||
}
|
||||
|
||||
func (v *API) Vehicles() ([]string, error) {
|
||||
uri := fmt.Sprintf("%s/%s", ApiBaseUrl, VehicleGuidPath)
|
||||
|
||||
|
|
|
|||
|
|
@ -67,62 +67,3 @@ func (ts *tokenSource) TokenEx() (*Token, error) {
|
|||
func (ts *tokenSource) mergeToken(t *Token) error {
|
||||
return mergo.Merge(ts.token, t, mergo.WithOverride)
|
||||
}
|
||||
|
||||
type metaTokenSource struct {
|
||||
mu sync.Mutex
|
||||
ts TokenSource
|
||||
newT func() (*Token, error)
|
||||
newTS func(*Token) TokenSource
|
||||
}
|
||||
|
||||
// MetaTokenSource creates a token source that is created using the
|
||||
// `newTS` function or recreated once it fails to return tokens.
|
||||
// The recreation uses a new bootstrap token provided by the `newT` function.
|
||||
func MetaTokenSource(newT func() (*Token, error), newTS func(*Token) TokenSource) *metaTokenSource {
|
||||
return &metaTokenSource{
|
||||
newT: newT,
|
||||
newTS: newTS,
|
||||
}
|
||||
}
|
||||
|
||||
// Token returns an oauth2 token or an error
|
||||
func (ts *metaTokenSource) Token() (*oauth2.Token, error) {
|
||||
token, err := ts.TokenEx()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return &token.Token, err
|
||||
}
|
||||
|
||||
// Token returns a vag token or an error
|
||||
func (ts *metaTokenSource) TokenEx() (*Token, error) {
|
||||
ts.mu.Lock()
|
||||
defer ts.mu.Unlock()
|
||||
|
||||
// use token source
|
||||
if ts.ts != nil {
|
||||
token, err := ts.ts.TokenEx()
|
||||
if err == nil {
|
||||
return token, nil
|
||||
}
|
||||
}
|
||||
|
||||
// create new start token
|
||||
token, err := ts.newT()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// create token source
|
||||
ts.ts = ts.newTS(token)
|
||||
|
||||
// use token source
|
||||
token, err = ts.ts.TokenEx()
|
||||
if err != nil {
|
||||
// token source doesn't work anymore, reset it
|
||||
ts.ts = nil
|
||||
}
|
||||
|
||||
return token, err
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,89 +0,0 @@
|
|||
package vwidentity
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/evcc-io/evcc/util"
|
||||
"github.com/evcc-io/evcc/util/request"
|
||||
"github.com/evcc-io/evcc/util/urlvalues"
|
||||
"github.com/evcc-io/evcc/vehicle/vag"
|
||||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
// Login performs VW identity login with optional code challenge
|
||||
func Oauth2Login(log *util.Logger, oc *oauth2.Config, user, password string) (vag.TokenSource, error) {
|
||||
oc.Endpoint = Config.NewProvider(context.Background()).Endpoint()
|
||||
|
||||
// add code challenge
|
||||
cv := oauth2.GenerateVerifier()
|
||||
q := url.Values{
|
||||
"response_type": {"code id_token"},
|
||||
"client_id": {oc.ClientID},
|
||||
"redirect_uri": {oc.RedirectURL},
|
||||
"code_challenge_method": {"S256"},
|
||||
"code_challenge": {oauth2.S256ChallengeFromVerifier(cv)},
|
||||
"scope": {strings.Join(oc.Scopes, " ")},
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s?%s", oc.Endpoint.AuthURL, q.Encode())
|
||||
|
||||
vwi := New(log)
|
||||
q, err := vwi.Login(uri, user, password)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
if err := urlvalues.Require(q, "id_token", "code"); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
os := &Oauth2Service{Helper: request.NewHelper(log), Config: oc}
|
||||
|
||||
token, err := os.retrieveToken(url.Values{
|
||||
"client_id": {oc.ClientID},
|
||||
"client_secret": {oc.ClientSecret},
|
||||
"redirect_uri": {oc.RedirectURL},
|
||||
"grant_type": {"authorization_code"},
|
||||
"code": {q.Get("code")},
|
||||
"code_verifier": {cv},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
return os.TokenSource(token), nil
|
||||
}
|
||||
|
||||
type Oauth2Service struct {
|
||||
*oauth2.Config
|
||||
*request.Helper
|
||||
}
|
||||
|
||||
func (v *Oauth2Service) retrieveToken(data url.Values) (*vag.Token, error) {
|
||||
var res vag.Token
|
||||
|
||||
req, err := request.New(http.MethodPost, v.Endpoint.TokenURL, strings.NewReader(data.Encode()), request.URLEncoding, request.AcceptJSON)
|
||||
if err == nil {
|
||||
err = v.DoJSON(req, &res)
|
||||
}
|
||||
|
||||
return &res, err
|
||||
}
|
||||
|
||||
func (v *Oauth2Service) refresh(token *vag.Token) (*vag.Token, error) {
|
||||
return v.retrieveToken(url.Values{
|
||||
"client_id": {v.ClientID},
|
||||
"client_secret": {v.ClientSecret},
|
||||
"grant_type": {"refresh_token"},
|
||||
"refresh_token": {token.RefreshToken},
|
||||
})
|
||||
}
|
||||
|
||||
// TokenSource creates token source. Token is refreshed automatically.
|
||||
func (v *Oauth2Service) TokenSource(token *vag.Token) vag.TokenSource {
|
||||
return vag.RefreshTokenSource(token, v.refresh)
|
||||
}
|
||||
|
|
@ -28,11 +28,6 @@ var brands = map[string]brand{
|
|||
"Cupra": {"f85e5b69-e3b2-43aa-9c0d-1b7d0e0b576f@apps_vw-dilab_com", "CUPRA"},
|
||||
}
|
||||
|
||||
// Brands returns the supported brand names
|
||||
func Brands() []string {
|
||||
return []string{"Volkswagen", "Audi", "Skoda", "Seat", "Cupra"}
|
||||
}
|
||||
|
||||
// resolveBrand looks up a brand by name, case-insensitively
|
||||
func resolveBrand(name string) (brand, bool) {
|
||||
for k, b := range brands {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue