Fix Audi auth endpoint. Hash secret is omitted for legal reasons.

This commit is contained in:
andig 2020-10-25 12:25:30 +01:00
parent 4a7046e475
commit bbe065deae
3 changed files with 38 additions and 7 deletions

View file

@ -15,7 +15,9 @@ notifications:
env:
global:
- PATH=$HOME/gopath/bin:$PATH
- PATH=$HOME/gopath/bin:$PATH
# AUDI_HASH_SECRET
- secure: FLxALYSoDbHOy70ppjP9rjMA7YMrTTiUQz8cBkOM6CnXOOIFk1canfylmb/nKJWz77nLBvLgbt38jZtUWyiG0dRvAz9IGrRy4KIJ4wrLMS8ub6up4JiSiHkwIvWJl3Z3DUWF7WYpwg3agqp8M2eSbNzZQsjsgwBLDlOEpCKvEpqxN7kjMi2hmH93Fb6SbMxrZKpSRhjPE/GLQWgbrTWHhMLDZMtlcoazOeALJp+QPcncOu6wLeJXEmNhd2NDe5nNMkSe3P9J7dbaVVmCctPyBdD5WWrj9aa11ghtzAiuPOkg578VaSIORr1ZOFZKpTPch0ryCvFjBtCWXJIaTW5Vd6Xz1yv3N/lyz4LsPUcUvHstLP+sWkn8A80+Td6oNw5kR1ji14Mfk0ZYCvYkvj8U20QcmS46gehy6BNCSLQe/PXI2IxJGdjc5s5Bz84fk0+nERvXmTEIf/8V76JeT+1sTahEOp9eUkYvfObhr3Tu22BB2kTkpn42jnvdH25Egr10VmQYQcCa3cHSOQXVnw7fo7En/VvbObUVeW3UwcIIqWQO2eW2tSbWGHa5wN1CbPzpbjVylW++TI7Xzk+kjP3BHOZ2ZGSSoSM0s7F4cj6D3vK4+3grW0TqrvC1+mikwlMA5EeMzlPRaEjWBTwqoTZan3R29VadGYui+LQzbaDk+lw=
before_install:
# Install linters and misspell

View file

@ -9,6 +9,8 @@ IMAGE := andig/evcc
ALPINE := 3.12
TARGETS := arm.v6,arm.v8,amd64
AUDI_HASH_SECRET := ${AUDI_HASH_SECRET}
default: clean install assets lint test build
clean:
@ -31,7 +33,7 @@ assets:
build:
@echo Version: $(VERSION) $(BUILD_DATE)
go build -v -tags=release -ldflags '-X "github.com/andig/evcc/server.Version=${VERSION}" -X "github.com/andig/evcc/server.Commit=${SHA}"'
go build -v -tags=release -ldflags '-X "github.com/andig/evcc/server.Version=${VERSION}" -X "github.com/andig/evcc/server.Commit=${SHA}" -X "github.com/andig/evcc/vehicle.AudiHashSecret=${AUDI_HASH_SECRET}"'
release-test:
goreleaser --snapshot --skip-publish --rm-dist

View file

@ -1,10 +1,15 @@
package vehicle
import (
"crypto/hmac"
"crypto/sha256"
"encoding/hex"
"errors"
"fmt"
"net/http"
"net/http/cookiejar"
"net/url"
"strconv"
"strings"
"time"
@ -31,7 +36,10 @@ func init() {
registry.Add("audi", NewAudiFromConfig)
}
const audiClientID = "77869e21-e30a-4a92-b016-48ab7d3db1d8"
// AudiHashSecret is used for obtaining the X-QMauth header hash value from the current timestamp
var AudiHashSecret = "not contained in repo due to legal concerns"
const audiOAuthClientID = "77869e21-e30a-4a92-b016-48ab7d3db1d8"
// NewAudiFromConfig creates a new vehicle
func NewAudiFromConfig(other map[string]interface{}) (api.Vehicle, error) {
@ -90,6 +98,7 @@ func (v *Audi) authFlow() error {
var tokens vw.Tokens
const clientID = "09b6cbec-cd19-4589-82fd-363dfa8c24da@apps_vw-dilab_com"
const clientIDAlias = "934928ef" // "09b6cbec-cd19-4589-82fd-363dfa8c24da@apps_vw-dilab_com"
const redirectURI = "myaudi:///"
query := url.Values(map[string][]string{
@ -123,8 +132,26 @@ func (v *Audi) authFlow() error {
"response_type": {"token id_token"},
})
uri = "https://app-api.my.audi.com/myaudiappidk/v1/token"
req, err = request.New(http.MethodPost, uri, strings.NewReader(data.Encode()), request.URLEncoding)
var hash string
var secret []byte
if secret, err = hex.DecodeString(AudiHashSecret); err == nil {
// timestamp rounded to 100s precision
ts := strconv.FormatInt(time.Now().Unix()/100, 10)
mac := hmac.New(sha256.New, secret)
_, err = mac.Write([]byte(ts))
hash = fmt.Sprintf("v1:%s:%0x", clientIDAlias, mac.Sum(nil))
}
if err == nil {
uri = "https://app-api.my.audi.com/myaudiappidk/v1/emea/token"
req, err = request.New(http.MethodPost, uri, strings.NewReader(data.Encode()), map[string]string{
"Content-Type": "application/x-www-form-urlencoded",
"X-QMAuth": hash,
})
}
if err == nil {
if err = v.DoJSON(req, &tokens); err == nil && tokens.IDToken == "" {
err = errors.New("missing id token (1)")
@ -141,7 +168,7 @@ func (v *Audi) authFlow() error {
req, err = request.New(http.MethodPost, vw.OauthTokenURI, strings.NewReader(data.Encode()), map[string]string{
"Content-Type": "application/x-www-form-urlencoded",
"X-Client-Id": audiClientID,
"X-Client-Id": audiOAuthClientID,
})
if err == nil {
if err = v.DoJSON(req, &v.tokens); err == nil && tokens.IDToken == "" {
@ -158,6 +185,6 @@ func (v *Audi) refreshHeaders() map[string]string {
"Content-Type": "application/x-www-form-urlencoded",
"X-App-Version": "3.14.0",
"X-App-Name": "myAudi",
"X-Client-Id": audiClientID,
"X-Client-Id": audiOAuthClientID,
}
}