forked from TrueCloudLab/rclone
parent
15b1feea9d
commit
eff11b44cf
1 changed files with 39 additions and 11 deletions
|
@ -5,6 +5,7 @@ import (
|
||||||
"bytes"
|
"bytes"
|
||||||
"context"
|
"context"
|
||||||
"encoding/xml"
|
"encoding/xml"
|
||||||
|
"fmt"
|
||||||
"html/template"
|
"html/template"
|
||||||
"net/http"
|
"net/http"
|
||||||
"net/http/cookiejar"
|
"net/http/cookiejar"
|
||||||
|
@ -32,13 +33,13 @@ type CookieResponse struct {
|
||||||
FedAuth http.Cookie
|
FedAuth http.Cookie
|
||||||
}
|
}
|
||||||
|
|
||||||
// SuccessResponse hold a response from the sharepoint webdav
|
// SharepointSuccessResponse holds a response from a successful microsoft login
|
||||||
type SuccessResponse struct {
|
type SharepointSuccessResponse struct {
|
||||||
XMLName xml.Name `xml:"Envelope"`
|
XMLName xml.Name `xml:"Envelope"`
|
||||||
Succ SuccessResponseBody `xml:"Body"`
|
Body SuccessResponseBody `xml:"Body"`
|
||||||
}
|
}
|
||||||
|
|
||||||
// SuccessResponseBody is the body of a success response, it holds the token
|
// SuccessResponseBody is the body of a successful response, it holds the token
|
||||||
type SuccessResponseBody struct {
|
type SuccessResponseBody struct {
|
||||||
XMLName xml.Name
|
XMLName xml.Name
|
||||||
Type string `xml:"RequestSecurityTokenResponse>TokenType"`
|
Type string `xml:"RequestSecurityTokenResponse>TokenType"`
|
||||||
|
@ -47,6 +48,24 @@ type SuccessResponseBody struct {
|
||||||
Token string `xml:"RequestSecurityTokenResponse>RequestedSecurityToken>BinarySecurityToken"`
|
Token string `xml:"RequestSecurityTokenResponse>RequestedSecurityToken>BinarySecurityToken"`
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// SharepointError holds a error response microsoft login
|
||||||
|
type SharepointError struct {
|
||||||
|
XMLName xml.Name `xml:"Envelope"`
|
||||||
|
Body ErrorResponseBody `xml:"Body"`
|
||||||
|
}
|
||||||
|
|
||||||
|
func (e *SharepointError) Error() string {
|
||||||
|
return fmt.Sprintf("%s: %s (%s)", e.Body.FaultCode, e.Body.Reason, e.Body.Detail)
|
||||||
|
}
|
||||||
|
|
||||||
|
// ErrorResponseBody contains the body of a erroneous repsonse
|
||||||
|
type ErrorResponseBody struct {
|
||||||
|
XMLName xml.Name
|
||||||
|
FaultCode string `xml:"Fault>Code>Subcode>Value"`
|
||||||
|
Reason string `xml:"Fault>Reason>Text"`
|
||||||
|
Detail string `xml:"Fault>Detail>error>internalerror>text"`
|
||||||
|
}
|
||||||
|
|
||||||
// reqString is a template that gets populated with the user data in order to retrieve a "BinarySecurityToken"
|
// reqString is a template that gets populated with the user data in order to retrieve a "BinarySecurityToken"
|
||||||
const reqString = `<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
|
const reqString = `<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
|
||||||
xmlns:a="http://www.w3.org/2005/08/addressing"
|
xmlns:a="http://www.w3.org/2005/08/addressing"
|
||||||
|
@ -100,7 +119,7 @@ func (ca *CookieAuth) Cookies(ctx context.Context) (*CookieResponse, error) {
|
||||||
return ca.getSPCookie(tokenResp)
|
return ca.getSPCookie(tokenResp)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ca *CookieAuth) getSPCookie(conf *SuccessResponse) (*CookieResponse, error) {
|
func (ca *CookieAuth) getSPCookie(conf *SharepointSuccessResponse) (*CookieResponse, error) {
|
||||||
spRoot, err := url.Parse(ca.endpoint)
|
spRoot, err := url.Parse(ca.endpoint)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, errors.Wrap(err, "Error while constructing endpoint URL")
|
return nil, errors.Wrap(err, "Error while constructing endpoint URL")
|
||||||
|
@ -123,7 +142,7 @@ func (ca *CookieAuth) getSPCookie(conf *SuccessResponse) (*CookieResponse, error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Send the previously acquired Token as a Post parameter
|
// Send the previously acquired Token as a Post parameter
|
||||||
if _, err = client.Post(u.String(), "text/xml", strings.NewReader(conf.Succ.Token)); err != nil {
|
if _, err = client.Post(u.String(), "text/xml", strings.NewReader(conf.Body.Token)); err != nil {
|
||||||
return nil, errors.Wrap(err, "Error while grabbing cookies from endpoint: %v")
|
return nil, errors.Wrap(err, "Error while grabbing cookies from endpoint: %v")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -141,7 +160,7 @@ func (ca *CookieAuth) getSPCookie(conf *SuccessResponse) (*CookieResponse, error
|
||||||
return &cookieResponse, nil
|
return &cookieResponse, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (ca *CookieAuth) getSPToken(ctx context.Context) (conf *SuccessResponse, err error) {
|
func (ca *CookieAuth) getSPToken(ctx context.Context) (conf *SharepointSuccessResponse, err error) {
|
||||||
reqData := map[string]interface{}{
|
reqData := map[string]interface{}{
|
||||||
"Username": ca.user,
|
"Username": ca.user,
|
||||||
"Password": ca.pass,
|
"Password": ca.pass,
|
||||||
|
@ -177,12 +196,21 @@ func (ca *CookieAuth) getSPToken(ctx context.Context) (conf *SuccessResponse, er
|
||||||
}
|
}
|
||||||
s := respBuf.Bytes()
|
s := respBuf.Bytes()
|
||||||
|
|
||||||
conf = &SuccessResponse{}
|
conf = &SharepointSuccessResponse{}
|
||||||
err = xml.Unmarshal(s, conf)
|
err = xml.Unmarshal(s, conf)
|
||||||
if err != nil {
|
if conf.Body.Token == "" {
|
||||||
// FIXME: Try to parse with FailedResponse struct (check for server error code)
|
// xml Unmarshal won't fail if the response doesn't contain a token
|
||||||
return nil, errors.Wrap(err, "Error while reading endpoint response")
|
// However, the token will be empty
|
||||||
|
sErr := &SharepointError{}
|
||||||
|
|
||||||
|
errSErr := xml.Unmarshal(s, sErr)
|
||||||
|
if errSErr == nil {
|
||||||
|
return nil, sErr
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err != nil {
|
||||||
|
return nil, errors.Wrap(err, "Error while reading endpoint response")
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue