Skip to content

Commit

Permalink
webdav: parse and return sharepoint error response
Browse files Browse the repository at this point in the history
fixes #3176
  • Loading branch information
hensur authored and ncw committed Oct 6, 2019
1 parent 15b1fee commit eff11b4
Showing 1 changed file with 38 additions and 10 deletions.
48 changes: 38 additions & 10 deletions backend/webdav/odrvcookie/fetch.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"bytes"
"context"
"encoding/xml"
"fmt"
"html/template"
"net/http"
"net/http/cookiejar"
Expand Down Expand Up @@ -32,13 +33,13 @@ type CookieResponse struct {
FedAuth http.Cookie
}

// SuccessResponse hold a response from the sharepoint webdav
type SuccessResponse struct {
// SharepointSuccessResponse holds a response from a successful microsoft login
type SharepointSuccessResponse struct {
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 {
XMLName xml.Name
Type string `xml:"RequestSecurityTokenResponse>TokenType"`
Expand All @@ -47,6 +48,24 @@ type SuccessResponseBody struct {
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"
const reqString = `<s:Envelope xmlns:s="http://www.w3.org/2003/05/soap-envelope"
xmlns:a="http://www.w3.org/2005/08/addressing"
Expand Down Expand Up @@ -100,7 +119,7 @@ func (ca *CookieAuth) Cookies(ctx context.Context) (*CookieResponse, error) {
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)
if err != nil {
return nil, errors.Wrap(err, "Error while constructing endpoint URL")
Expand All @@ -123,7 +142,7 @@ func (ca *CookieAuth) getSPCookie(conf *SuccessResponse) (*CookieResponse, error
}

// 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")
}

Expand All @@ -141,7 +160,7 @@ func (ca *CookieAuth) getSPCookie(conf *SuccessResponse) (*CookieResponse, error
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{}{
"Username": ca.user,
"Password": ca.pass,
Expand Down Expand Up @@ -177,12 +196,21 @@ func (ca *CookieAuth) getSPToken(ctx context.Context) (conf *SuccessResponse, er
}
s := respBuf.Bytes()

conf = &SuccessResponse{}
conf = &SharepointSuccessResponse{}
err = xml.Unmarshal(s, conf)
if conf.Body.Token == "" {
// xml Unmarshal won't fail if the response doesn't contain a token
// However, the token will be empty
sErr := &SharepointError{}

errSErr := xml.Unmarshal(s, sErr)
if errSErr == nil {
return nil, sErr
}
}

if err != nil {
// FIXME: Try to parse with FailedResponse struct (check for server error code)
return nil, errors.Wrap(err, "Error while reading endpoint response")
}

return
}

0 comments on commit eff11b4

Please sign in to comment.