mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-10-09 20:33:25 -04:00
88 lines
3.2 KiB
Go
88 lines
3.2 KiB
Go
package middleware
|
|
|
|
import (
|
|
"encoding/json"
|
|
"encoding/xml"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
)
|
|
|
|
// hostileShareID would break out of an XML/JSON document if it were not escaped.
|
|
const hostileShareID = `<script>alert("x")</script>&'`
|
|
|
|
func TestRenderTerminalFailure_Generic(t *testing.T) {
|
|
t.Run("non-dav request", func(t *testing.T) {
|
|
rr := httptest.NewRecorder()
|
|
req := httptest.NewRequest(http.MethodGet, "/graph/v1beta1/me/drive/sharedWithMe", nil)
|
|
|
|
require.NoError(t, renderTerminalFailure(rr, req, TerminalFailed()))
|
|
|
|
assert.Equal(t, http.StatusUnauthorized, rr.Code)
|
|
assert.Empty(t, rr.Body.String())
|
|
})
|
|
|
|
t.Run("dav request", func(t *testing.T) {
|
|
rr := httptest.NewRecorder()
|
|
req := httptest.NewRequest("PROPFIND", "/dav/spaces/abc", nil)
|
|
|
|
require.NoError(t, renderTerminalFailure(rr, req, TerminalFailed()))
|
|
|
|
assert.Equal(t, http.StatusUnauthorized, rr.Code)
|
|
assert.Equal(t, "application/xml; charset=utf-8", rr.Header().Get("Content-Type"))
|
|
assert.True(t, strings.HasPrefix(rr.Body.String(), xml.Header))
|
|
assert.Contains(t, rr.Body.String(), "Sabre\\DAV\\Exception\\NotAuthenticated")
|
|
})
|
|
}
|
|
|
|
func TestRenderTerminalFailure_GuestSessionExpiredJSON(t *testing.T) {
|
|
rr := httptest.NewRecorder()
|
|
req := httptest.NewRequest(http.MethodGet, "/graph/v1beta1/me/drive/sharedWithMe", nil)
|
|
|
|
require.NoError(t, renderTerminalFailure(rr, req, AuthenticationResult{
|
|
State: AuthenticationFailed,
|
|
Terminal: true,
|
|
ErrorDetails: GuestSessionExpiredDetails{PermissionID: hostileShareID},
|
|
}))
|
|
|
|
assert.Equal(t, http.StatusUnauthorized, rr.Code)
|
|
assert.Equal(t, "application/json", rr.Header().Get("Content-Type"))
|
|
|
|
var body struct {
|
|
ErrorType string `json:"error_type"`
|
|
PermissionID string `json:"permissionId"`
|
|
}
|
|
require.NoError(t, json.Unmarshal(rr.Body.Bytes(), &body))
|
|
assert.Equal(t, "session_expired", body.ErrorType)
|
|
assert.Equal(t, hostileShareID, body.PermissionID)
|
|
// json.Encoder escapes <, > and & so the body is safe even if it were rendered as HTML
|
|
assert.NotContains(t, rr.Body.String(), "<script>")
|
|
}
|
|
|
|
func TestRenderTerminalFailure_GuestSessionExpiredDAV(t *testing.T) {
|
|
rr := httptest.NewRecorder()
|
|
req := httptest.NewRequest("PROPFIND", "/dav/spaces/abc", nil)
|
|
|
|
require.NoError(t, renderTerminalFailure(rr, req, AuthenticationResult{
|
|
State: AuthenticationFailed,
|
|
Terminal: true,
|
|
ErrorDetails: GuestSessionExpiredDetails{PermissionID: hostileShareID, IsDAV: true},
|
|
}))
|
|
|
|
assert.Equal(t, http.StatusUnauthorized, rr.Code)
|
|
assert.Equal(t, "application/xml; charset=utf-8", rr.Header().Get("Content-Type"))
|
|
assert.True(t, strings.HasPrefix(rr.Body.String(), xml.Header))
|
|
|
|
// encoding/xml cannot unmarshal prefixed element names such as d:error, so
|
|
// inspect the document directly.
|
|
body := rr.Body.String()
|
|
assert.Contains(t, body, "<s:Exception>Sabre\\DAV\\Exception\\NotAuthenticated</s:Exception>")
|
|
assert.Contains(t, body, "<opencloud:error_type>session_expired</opencloud:error_type>")
|
|
assert.Contains(t, body, "<opencloud:share_id><script>alert("x")</script>&'</opencloud:share_id>")
|
|
assert.NotContains(t, body, "<script>")
|
|
}
|