Ford: fix HTTP 401 errors (#2240)
This commit is contained in:
parent
a0ea0974a3
commit
47c104ec61
2 changed files with 50 additions and 30 deletions
|
|
@ -11,12 +11,7 @@ import (
|
|||
"golang.org/x/oauth2"
|
||||
)
|
||||
|
||||
// https://github.com/ianjwhite99/connected-car-node-sdk
|
||||
|
||||
const (
|
||||
ApiURI = "https://usapi.cv.ford.com"
|
||||
VehicleListURI = "https://api.mps.ford.com/api/users/vehicles"
|
||||
)
|
||||
const ApiURI = "https://usapi.cv.ford.com"
|
||||
|
||||
// API is the VW api client
|
||||
type API struct {
|
||||
|
|
@ -34,8 +29,8 @@ func NewAPI(log *util.Logger, ts oauth2.TokenSource) *API {
|
|||
token, err := ts.Token()
|
||||
if err == nil {
|
||||
for k, v := range map[string]string{
|
||||
"Content-type": "application/json",
|
||||
"Application-Id": "71A3AD0A-CF46-4CCF-B473-FC7FE5BC4592",
|
||||
"Content-type": request.JSONContent,
|
||||
"Application-Id": ApplicationID,
|
||||
"Auth-Token": token.AccessToken,
|
||||
} {
|
||||
req.Header.Set(k, v)
|
||||
|
|
@ -54,7 +49,9 @@ func (v *API) Vehicles() ([]string, error) {
|
|||
var resp VehiclesResponse
|
||||
var vehicles []string
|
||||
|
||||
err := v.GetJSON(VehicleListURI, &resp)
|
||||
uri := fmt.Sprintf("%s/api/users/vehicles", TokenURI)
|
||||
|
||||
err := v.GetJSON(uri, &resp)
|
||||
if err == nil {
|
||||
for _, v := range resp.Vehicles.Values {
|
||||
vehicles = append(vehicles, v.VIN)
|
||||
|
|
|
|||
|
|
@ -1,9 +1,9 @@
|
|||
package ford
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
|
||||
"github.com/evcc-io/evcc/util"
|
||||
"github.com/evcc-io/evcc/util/oauth"
|
||||
|
|
@ -12,10 +12,19 @@ import (
|
|||
)
|
||||
|
||||
const (
|
||||
AuthURI = "https://sso.ci.ford.ca" // fcis.ice.ibmcloud.com
|
||||
ClientID = "9fb503e0-715b-47e8-adfd-ad4b7770f73b"
|
||||
AuthURI = "https://sso.ci.ford.com"
|
||||
TokenURI = "https://api.mps.ford.com"
|
||||
ClientID = "9fb503e0-715b-47e8-adfd-ad4b7770f73b"
|
||||
ApplicationID = "1E8C7794-FF5F-49BC-9596-A1E0C86C5B19"
|
||||
)
|
||||
|
||||
var OAuth2Config = &oauth2.Config{
|
||||
ClientID: ClientID,
|
||||
Endpoint: oauth2.Endpoint{
|
||||
TokenURL: fmt.Sprintf("%s/oidc/endpoint/default/token", AuthURI),
|
||||
},
|
||||
}
|
||||
|
||||
type Identity struct {
|
||||
*request.Helper
|
||||
user, password string
|
||||
|
|
@ -42,34 +51,48 @@ func (v *Identity) Login() error {
|
|||
|
||||
// login authenticates with username/password to get new token
|
||||
func (v *Identity) login() (oauth.Token, error) {
|
||||
data := url.Values{
|
||||
"client_id": []string{ClientID},
|
||||
"grant_type": []string{"password"},
|
||||
"username": []string{v.user},
|
||||
"password": []string{v.password},
|
||||
}
|
||||
ctx, cancel := context.WithTimeout(
|
||||
context.WithValue(context.Background(), oauth2.HTTPClient, v.Client),
|
||||
request.Timeout,
|
||||
)
|
||||
defer cancel()
|
||||
|
||||
uri := AuthURI + "/v1.0/endpoint/default/token"
|
||||
req, err := request.New(http.MethodPost, uri, strings.NewReader(data.Encode()), request.URLEncoding)
|
||||
tok, err := OAuth2Config.PasswordCredentialsToken(ctx, v.user, v.password)
|
||||
|
||||
var res oauth.Token
|
||||
// exchange code for api token
|
||||
var token oauth.Token
|
||||
if err == nil {
|
||||
err = v.DoJSON(req, &res)
|
||||
data := map[string]string{
|
||||
"code": tok.AccessToken,
|
||||
}
|
||||
|
||||
uri := fmt.Sprintf("%s/api/oauth2/v1/token", TokenURI)
|
||||
|
||||
var req *http.Request
|
||||
req, err = request.New(http.MethodPut, uri, request.MarshalJSON(data), map[string]string{
|
||||
"Content-type": request.JSONContent,
|
||||
"Application-Id": ApplicationID,
|
||||
})
|
||||
|
||||
if err == nil {
|
||||
err = v.DoJSON(req, &token)
|
||||
}
|
||||
}
|
||||
|
||||
return res, err
|
||||
return token, err
|
||||
}
|
||||
|
||||
// Refresh implements oauth.TokenRefresher
|
||||
func (v *Identity) RefreshToken(token *oauth2.Token) (*oauth2.Token, error) {
|
||||
data := url.Values{
|
||||
"client_id": []string{ClientID},
|
||||
"grant_type": []string{"refresh_token"},
|
||||
"refresh_token": []string{token.RefreshToken},
|
||||
data := map[string]string{
|
||||
"refresh_token": token.RefreshToken,
|
||||
}
|
||||
|
||||
uri := AuthURI + "/v1.0/endpoint/default/token"
|
||||
req, err := request.New(http.MethodPost, uri, strings.NewReader(data.Encode()), request.URLEncoding)
|
||||
uri := fmt.Sprintf("%s/api/oauth2/v1/refresh", TokenURI)
|
||||
req, err := request.New(http.MethodPut, uri, request.MarshalJSON(data), map[string]string{
|
||||
"Content-type": request.JSONContent,
|
||||
"Application-Id": ApplicationID,
|
||||
})
|
||||
|
||||
var res oauth.Token
|
||||
if err == nil {
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue