VW: fix login (#2430)

This commit is contained in:
andig 2022-01-29 12:14:14 +01:00 • committed by GitHub
parent ff559e4456
commit a47fbfd4d7
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 57 additions and 5 deletions

View file

@ -1,8 +1,12 @@
package vw
import (
"encoding/json"
"errors"
"fmt"
"io"
"regexp"
"strings"
"github.com/PuerkitoBio/goquery"
)
@ -53,3 +57,38 @@ func FormValues(reader io.Reader, id string) (FormVars, error) {
return vars, err
}
type CredentialParams struct {
TemplateModel struct {
Hmac string `json:"hmac"`
RelayState string `json:"relayState"`
PostAction string `json:"postAction"`
IdentifierUrl string `json:"identifierUrl"`
Error string `json:"error"`
} `json:"templateModel"`
CurrentLocale string `json:"currentLocale"`
CsrfParameterName string `json:"csrf_parameterName"`
CsrfToken string `json:"csrf_token"`
}
func ParseCredentialsPage(r io.ReadCloser) (CredentialParams, error) {
var res CredentialParams
buf := new(strings.Builder)
if _, err := io.Copy(buf, r); err != nil {
return res, err
}
re := regexp.MustCompile(`(?s)window._IDK\s*=\s*(.*?);`)
match := re.FindAllStringSubmatch(buf.String(), -1)
tmpl := strings.ReplaceAll(match[0][1], `'`, `"`)
for _, v := range []string{`templateModel`, `currentLocale`, `csrf_parameterName`, `csrf_token`} {
tmpl = strings.Replace(tmpl, v, fmt.Sprintf(`"%s"`, v), 1)
}
err := json.Unmarshal([]byte(tmpl), &res)
fmt.Printf("%+v\n", res)
return res, err
}

View file

@ -13,6 +13,8 @@ import (
"golang.org/x/oauth2"
)
// https://identity.vwgroup.io/.well-known/openid-configuration
const (
// IdentityURI is the VW OIDC identity provider uri
IdentityURI = "https://identity.vwgroup.io"

View file

@ -1,6 +1,7 @@
package vw
import (
"errors"
"fmt"
"net/http"
"net/http/cookiejar"
@ -70,6 +71,8 @@ func (v *IDTokenProvider) Login() (url.Values, error) {
resp.Body.Close()
}
var params CredentialParams
// POST identity.vwgroup.io/signin-service/v1/b7a5bb47-f875-47cf-ab83-2ba3bf6bb738@apps_vw-dilab_com/login/identifier
if err == nil {
data := url.Values(map[string][]string{
@ -81,7 +84,7 @@ func (v *IDTokenProvider) Login() (url.Values, error) {
uri = IdentityURI + vars.Action
if resp, err = v.PostForm(uri, data); err == nil {
vars, err = FormValues(resp.Body, "form#credentialsForm")
params, err = ParseCredentialsPage(resp.Body)
resp.Body.Close()
}
}
@ -89,17 +92,25 @@ func (v *IDTokenProvider) Login() (url.Values, error) {
// POST identity.vwgroup.io/signin-service/v1/b7a5bb47-f875-47cf-ab83-2ba3bf6bb738@apps_vw-dilab_com/login/authenticate
if err == nil {
data := url.Values(map[string][]string{
"_csrf": {vars.Inputs["_csrf"]},
"relayState": {vars.Inputs["relayState"]},
"hmac": {vars.Inputs["hmac"]},
"_csrf": {params.CsrfToken},
"relayState": {params.TemplateModel.RelayState},
"hmac": {params.TemplateModel.Hmac},
"email": {v.user},
"password": {v.password},
})
uri = IdentityURI + vars.Action
// reuse url from identifier step before
uri = strings.ReplaceAll(uri, params.TemplateModel.IdentifierUrl, params.TemplateModel.PostAction)
if resp, err = v.PostForm(uri, data); err == nil {
resp.Body.Close()
if resp.StatusCode >= http.StatusBadRequest {
err = errors.New(resp.Status)
}
}
if err == nil {
if e := resp.Request.URL.Query().Get("error"); e != "" {
err = fmt.Errorf(e)
}