Seat: deprecate tokenrefreshservice (#19094)

This commit is contained in:
andig 2025-02-23 14:03:06 +01:00 • committed by GitHub
parent e73b72774f
commit 58200dc936
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 99 additions and 15 deletions

View file

@ -9,7 +9,6 @@ import (
"github.com/evcc-io/evcc/util"
"github.com/evcc-io/evcc/util/request"
"github.com/evcc-io/evcc/vehicle/seat/cupra"
"github.com/evcc-io/evcc/vehicle/vag/service"
"github.com/evcc-io/evcc/vehicle/vag/vwidentity"
"golang.org/x/oauth2"
)
@ -50,7 +49,7 @@ func NewCupraFromConfig(other map[string]interface{}) (api.Vehicle, error) {
log := util.NewLogger("cupra").Redact(cc.User, cc.Password, cc.VIN)
ts, err := service.TokenRefreshServiceTokenSource(log, cupra.TRSParams, cupra.AuthParams, cc.User, cc.Password)
ts, err := vwidentity.Oauth2Login(log, cupra.OAuth2Config, cc.User, cc.Password)
if err != nil {
return nil, err
}

View file

@ -58,7 +58,7 @@ func NewSeatFromConfig(other map[string]interface{}) (api.Vehicle, error) {
log := util.NewLogger("seat").Redact(cc.User, cc.Password, cc.VIN)
trs, err := service.TokenRefreshServiceTokenSource(log, cupra.TRSParams, cupra.AuthParams, cc.User, cc.Password)
trs, err := vwidentity.Oauth2Login(log, cupra.OAuth2Config, cc.User, cc.Password)
if err != nil {
return nil, err
}

View file

@ -1,16 +1,12 @@
package cupra
import "net/url"
import (
"golang.org/x/oauth2"
)
// Authorization parameters
var AuthParams = url.Values{
"response_type": {"code id_token"}, // token
"client_id": {"30e33736-c537-4c72-ab60-74a7b92cfe83@apps_vw-dilab_com"},
"redirect_uri": {"cupraconnect://identity-kit/login"},
"scope": {"openid profile mbb"}, // cars birthdate nickname address phone
}
// TokenRefreshService parameters
var TRSParams = url.Values{
"brand": {"cupra"},
var OAuth2Config = &oauth2.Config{
ClientID: "3c756d46-f1ba-4d78-9f9a-cff0d5292d51@apps_vw-dilab_com",
ClientSecret: "eb8814e641c81a2640ad62eeccec11c98effc9bccd4269ab7af338b50a94b3a2",
RedirectURL: "cupra://oauth-callback",
Scopes: []string{"openid", "profile", "mbb"},
}

View file

@ -0,0 +1,89 @@
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)
}