93 lines
2.3 KiB
Go
93 lines
2.3 KiB
Go
package mercedes
|
|
|
|
import (
|
|
"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/transport"
|
|
"github.com/google/uuid"
|
|
"golang.org/x/oauth2"
|
|
)
|
|
|
|
type SetupAPI struct {
|
|
log *util.Logger
|
|
account string
|
|
region string
|
|
*request.Helper
|
|
}
|
|
|
|
func NewSetupAPI(log *util.Logger, account string, region string) *SetupAPI {
|
|
client := request.NewHelper(log)
|
|
|
|
client.Transport = &transport.Decorator{
|
|
Base: client.Transport,
|
|
Decorator: transport.DecorateHeaders(mbheaders(true, region)),
|
|
}
|
|
|
|
return &SetupAPI{
|
|
Helper: client,
|
|
log: log,
|
|
region: region,
|
|
account: account,
|
|
}
|
|
}
|
|
|
|
func (vs *SetupAPI) RequestPin() (bool, *string, error) {
|
|
client := request.NewHelper(vs.log)
|
|
|
|
client.Transport = &transport.Decorator{
|
|
Base: client.Transport,
|
|
Decorator: transport.DecorateHeaders(mbheaders(false, vs.region)),
|
|
}
|
|
|
|
// Preflight request required to get a pin
|
|
uri := fmt.Sprintf("%s/v1/config", getBffUri(vs.region))
|
|
if _, err := client.GetBody(uri); err != nil {
|
|
return false, nil, err
|
|
}
|
|
|
|
nonce := uuid.New().String()
|
|
data := PinRequest{
|
|
EmailOrPhoneNumber: vs.account,
|
|
CountryCode: "EN",
|
|
Nonce: nonce,
|
|
}
|
|
|
|
uri = fmt.Sprintf("%s/v1/login", getBffUri(vs.region))
|
|
req, err := request.New(http.MethodPost, uri, request.MarshalJSON(data))
|
|
if err != nil {
|
|
return false, nil, err
|
|
}
|
|
|
|
var res PinResponse
|
|
if err := client.DoJSON(req, &res); err != nil {
|
|
return false, nil, err
|
|
}
|
|
|
|
// Only if the response field email is the same like the account an email is send by the servers.
|
|
return res.UserName == vs.account, &nonce, nil
|
|
}
|
|
|
|
func (vs *SetupAPI) RequestAccessToken(nonce string, pin string) (*oauth2.Token, error) {
|
|
data := url.Values{
|
|
"client_id": []string{ClientId},
|
|
"grant_type": []string{"password"},
|
|
"password": []string{fmt.Sprintf("%s:%s", nonce, pin)},
|
|
"scope": []string{"openid email phone profile offline_access ciam-uid"},
|
|
"username": []string{vs.account},
|
|
}
|
|
|
|
uri := fmt.Sprintf("%s/as/token.oauth2", IdUri)
|
|
req, _ := request.New(http.MethodPost, uri, strings.NewReader(data.Encode()), mbheaders(true, vs.region))
|
|
|
|
var res oauth2.Token
|
|
if err := vs.DoJSON(req, &res); err != nil {
|
|
return nil, err
|
|
}
|
|
|
|
return util.TokenWithExpiry(&res), nil
|
|
}
|