Skip to content

Commit

Permalink
Seat: fix retrieving list of vehicles (#9703)
Browse files Browse the repository at this point in the history
  • Loading branch information
andig authored Sep 7, 2023
1 parent cec3de4 commit a42affd
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 15 deletions.
3 changes: 1 addition & 2 deletions vehicle/seat-cupra.go
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@ import (
"github.com/evcc-io/evcc/api"
"github.com/evcc-io/evcc/util"
"github.com/evcc-io/evcc/util/request"
"github.com/evcc-io/evcc/vehicle/seat"
"github.com/evcc-io/evcc/vehicle/seat/cupra"
"github.com/evcc-io/evcc/vehicle/vag/service"
"github.com/evcc-io/evcc/vehicle/vag/vwidentity"
Expand Down Expand Up @@ -51,7 +50,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, seat.TRSParams, seat.AuthParams, cc.User, cc.Password)
ts, err := service.TokenRefreshServiceTokenSource(log, cupra.TRSParams, cupra.AuthParams, cc.User, cc.Password)
if err != nil {
return nil, err
}
Expand Down
59 changes: 55 additions & 4 deletions vehicle/seat.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,22 @@
package vehicle

import (
"context"
"fmt"
"net/http"
"net/url"
"strings"
"time"

"github.com/evcc-io/evcc/api"
"github.com/evcc-io/evcc/util"
"github.com/evcc-io/evcc/util/request"
"github.com/evcc-io/evcc/vehicle/seat"
"github.com/evcc-io/evcc/vehicle/seat/cupra"
"github.com/evcc-io/evcc/vehicle/vag/service"
"github.com/evcc-io/evcc/vehicle/vag/vwidentity"
"github.com/evcc-io/evcc/vehicle/vw"
"golang.org/x/oauth2"
)

// https://github.com/trocotronic/weconnect
Expand Down Expand Up @@ -50,22 +58,65 @@ 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, seat.TRSParams, seat.AuthParams, cc.User, cc.Password)
trs, err := service.TokenRefreshServiceTokenSource(log, cupra.TRSParams, cupra.AuthParams, cc.User, cc.Password)
if err != nil {
return nil, err
}

// get OIDC user information
ctx := context.WithValue(context.Background(), oauth2.HTTPClient, request.NewClient(log))
ui, err := vwidentity.Config.NewProvider(ctx).UserInfo(ctx, trs)
if err != nil {
return nil, fmt.Errorf("failed getting user information: %w", err)
}

mbbId, err := mbbUserId(log, trs, ui.Subject)
if err != nil {
return nil, fmt.Errorf("failed getting mbbUserId: %w", err)
}

ts := service.MbbTokenSource(log, trs, seat.AuthClientID)
api := vw.NewAPI(log, ts, seat.Brand, seat.Country)
api.Client.Timeout = cc.Timeout
api := seat.NewAPI(log, ts)

cc.VIN, err = ensureVehicle(cc.VIN, api.Vehicles)
cc.VIN, err = ensureVehicle(
cc.VIN, func() ([]string, error) {
return api.Vehicles(mbbId)
},
)

if err == nil {
api := vw.NewAPI(log, ts, seat.Brand, seat.Country)
api.Client.Timeout = cc.Timeout

if err = api.HomeRegion(cc.VIN); err == nil {
v.Provider = vw.NewProvider(api, cc.VIN, cc.Cache)
}
}

return v, err
}

func mbbUserId(log *util.Logger, ts oauth2.TokenSource, uid string) (string, error) {
client := request.NewHelper(log)
client.Transport = &oauth2.Transport{
Source: ts,
Base: client.Transport,
}

data := url.Values{
"scopeId": []string{"commonMandatoryFields"},
}

var mandatoryConsentInfo struct {
MbbUserId string `json:"mbbUserId"`
}

uri := fmt.Sprintf("https://profileintegrityservice.apps.emea.vwapps.io/iaa/pic/v1/users/%s/check-profile", uid)
req, err := request.New(http.MethodPost, uri, strings.NewReader(data.Encode()), request.URLEncoding)

if err == nil {
err = client.DoJSON(req, &mandatoryConsentInfo)
}

return mandatoryConsentInfo.MbbUserId, err
}
53 changes: 53 additions & 0 deletions vehicle/seat/api.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package seat

import (
"fmt"

"github.com/evcc-io/evcc/util"
"github.com/evcc-io/evcc/util/request"
"golang.org/x/oauth2"
)

// BaseURL is the API base url
const BaseURL = "https://mal-3a.prd.eu.dp.vwg-connect.com/api"

// API provides list of vehicles for Seat cars
type API struct {
*request.Helper
}

// NewAPI creates a new vehicle
func NewAPI(log *util.Logger, ts oauth2.TokenSource) *API {
v := &API{
Helper: request.NewHelper(log),
}

v.Client.Transport = &oauth2.Transport{
Source: ts,
Base: v.Client.Transport,
}

return v
}

// Vehicles implements the /vehicles response
func (v *API) Vehicles(userID string) ([]string, error) {
var res struct {
UserVehicles struct {
UserId string
Vehicle []struct {
Content string
}
}
}

uri := fmt.Sprintf("%s/usermanagement/users/v2/users/%s/vehicles", BaseURL, userID)
err := v.GetJSON(uri, &res)

var vehicles []string
for _, v := range res.UserVehicles.Vehicle {
vehicles = append(vehicles, v.Content)
}

return vehicles, err
}
16 changes: 16 additions & 0 deletions vehicle/seat/cupra/params.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
package cupra

import "net/url"

// 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"},
}
13 changes: 4 additions & 9 deletions vehicle/seat/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,18 +7,13 @@ const (
Country = "ES"

// Authorization ClientID
AuthClientID = "9d183b70-d129-424f-9a26-c3778edf95e1"
AuthClientID = "9dcc70f0-8e79-423a-a3fa-4065d99088b4"
)

// 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"},
"client_id": {"3c8e98bc-3ae9-4277-a563-d5ee65ddebba@apps_vw-dilab_com"},
"redirect_uri": {"seatconnect://identity-kit/login"},
"scope": {"openid profile"}, // address phone email birthdate nationalIdentifier cars mbb dealers badge nationality
}

0 comments on commit a42affd

Please sign in to comment.