mirror of
https://github.com/opencloud-eu/opencloud.git
synced 2026-02-22 05:29:01 -06:00
291 lines
9.1 KiB
Go
291 lines
9.1 KiB
Go
package middleware_test
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"net/url"
|
|
"path"
|
|
"strconv"
|
|
|
|
appprovider "github.com/cs3org/go-cs3apis/cs3/app/provider/v1beta1"
|
|
userv1beta1 "github.com/cs3org/go-cs3apis/cs3/identity/user/v1beta1"
|
|
providerv1beta1 "github.com/cs3org/go-cs3apis/cs3/storage/provider/v1beta1"
|
|
"github.com/cs3org/reva/v2/pkg/token"
|
|
rjwt "github.com/cs3org/reva/v2/pkg/token/manager/jwt"
|
|
. "github.com/onsi/ginkgo/v2"
|
|
. "github.com/onsi/gomega"
|
|
"github.com/owncloud/ocis/v2/services/collaboration/pkg/config"
|
|
"github.com/owncloud/ocis/v2/services/collaboration/pkg/helpers"
|
|
"github.com/owncloud/ocis/v2/services/collaboration/pkg/middleware"
|
|
"github.com/owncloud/ocis/v2/services/collaboration/pkg/wopisrc"
|
|
)
|
|
|
|
var _ = Describe("Wopi Context Middleware", func() {
|
|
var (
|
|
cfg *config.Config
|
|
ctx context.Context
|
|
mw http.Handler
|
|
rid *providerv1beta1.ResourceId
|
|
tknMngr token.Manager
|
|
user *userv1beta1.User
|
|
src *url.URL
|
|
)
|
|
|
|
BeforeEach(func() {
|
|
var err error
|
|
cfg = &config.Config{
|
|
TokenManager: &config.TokenManager{JWTSecret: "jwtSecret"},
|
|
Wopi: config.Wopi{
|
|
Secret: "wopiSecret",
|
|
WopiSrc: "https://localhost:9300",
|
|
},
|
|
}
|
|
|
|
ctx = context.Background()
|
|
|
|
next := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
w.WriteHeader(http.StatusOK)
|
|
})
|
|
mw = middleware.WopiContextAuthMiddleware(cfg, nil, next)
|
|
|
|
tknMngr, err = rjwt.New(map[string]interface{}{
|
|
"secret": cfg.TokenManager.JWTSecret,
|
|
"expires": int64(24 * 60 * 60),
|
|
})
|
|
Expect(err).ToNot(HaveOccurred())
|
|
|
|
user = &userv1beta1.User{
|
|
Id: &userv1beta1.UserId{
|
|
Idp: "example.com",
|
|
OpaqueId: "12345",
|
|
Type: userv1beta1.UserType_USER_TYPE_PRIMARY,
|
|
},
|
|
Username: "admin",
|
|
Mail: "admin@example.com",
|
|
}
|
|
|
|
rid = &providerv1beta1.ResourceId{
|
|
StorageId: "storageID",
|
|
OpaqueId: "opaqueID",
|
|
SpaceId: "spaceID",
|
|
}
|
|
|
|
src, err = url.Parse(cfg.Wopi.WopiSrc)
|
|
src.Path = path.Join("wopi", "files", helpers.HashResourceId(rid))
|
|
Expect(err).ToNot(HaveOccurred())
|
|
})
|
|
It("Should not authorize with empty access token", func() {
|
|
req := httptest.NewRequest("GET", src.String(), nil).WithContext(ctx)
|
|
resp := httptest.NewRecorder()
|
|
|
|
mw.ServeHTTP(resp, req)
|
|
Expect(resp.Code).To(Equal(http.StatusUnauthorized))
|
|
})
|
|
It("Should not authorize with malformed access token", func() {
|
|
req := httptest.NewRequest("GET", src.String(), nil).WithContext(ctx)
|
|
q := req.URL.Query()
|
|
q.Add("access_token", "token")
|
|
req.URL.RawQuery = q.Encode()
|
|
|
|
resp := httptest.NewRecorder()
|
|
|
|
mw.ServeHTTP(resp, req)
|
|
Expect(resp.Code).To(Equal(http.StatusUnauthorized))
|
|
})
|
|
It("Should not authorize when fileID mismatches", func() {
|
|
req := httptest.NewRequest("GET", src.String(), nil).WithContext(ctx)
|
|
// create request with different fileID in the wopi context
|
|
token, err := tknMngr.MintToken(ctx, user, nil)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
wopiContext := middleware.WopiContext{
|
|
AccessToken: token,
|
|
ViewMode: appprovider.ViewMode_VIEW_MODE_READ_WRITE,
|
|
FileReference: &providerv1beta1.Reference{
|
|
ResourceId: &providerv1beta1.ResourceId{
|
|
StorageId: "storageID",
|
|
OpaqueId: "opaqueID2",
|
|
SpaceId: "spaceID",
|
|
},
|
|
Path: ".",
|
|
},
|
|
}
|
|
wopiToken, ttl, err := middleware.GenerateWopiToken(wopiContext, cfg, nil)
|
|
q := req.URL.Query()
|
|
q.Add("access_token", wopiToken)
|
|
q.Add("access_token_ttl", strconv.FormatInt(ttl, 10))
|
|
req.URL.RawQuery = q.Encode()
|
|
resp := httptest.NewRecorder()
|
|
|
|
mw.ServeHTTP(resp, req)
|
|
Expect(resp.Code).To(Equal(http.StatusUnauthorized))
|
|
})
|
|
It("Should not authorize with wrong wopi secret", func() {
|
|
src.Path = path.Join("wopi", "files", helpers.HashResourceId(rid))
|
|
req := httptest.NewRequest("GET", src.String(), nil).WithContext(ctx)
|
|
token, err := tknMngr.MintToken(ctx, user, nil)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
|
|
wopiContext := middleware.WopiContext{
|
|
AccessToken: token,
|
|
}
|
|
// use wrong wopi secret when generating the wopi token
|
|
wopiToken, ttl, err := middleware.GenerateWopiToken(wopiContext, &config.Config{Wopi: config.Wopi{
|
|
Secret: "wrongSecret",
|
|
}}, nil)
|
|
q := req.URL.Query()
|
|
q.Add("access_token", wopiToken)
|
|
q.Add("access_token_ttl", strconv.FormatInt(ttl, 10))
|
|
req.URL.RawQuery = q.Encode()
|
|
resp := httptest.NewRecorder()
|
|
|
|
mw.ServeHTTP(resp, req)
|
|
Expect(resp.Code).To(Equal(http.StatusUnauthorized))
|
|
})
|
|
It("Should authorize successful", func() {
|
|
req := httptest.NewRequest("GET", src.String(), nil).WithContext(ctx)
|
|
token, err := tknMngr.MintToken(ctx, user, nil)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
|
|
wopiContext := middleware.WopiContext{
|
|
AccessToken: token,
|
|
ViewMode: appprovider.ViewMode_VIEW_MODE_READ_WRITE,
|
|
FileReference: &providerv1beta1.Reference{
|
|
ResourceId: rid,
|
|
Path: ".",
|
|
},
|
|
}
|
|
wopiToken, ttl, err := middleware.GenerateWopiToken(wopiContext, cfg, nil)
|
|
q := req.URL.Query()
|
|
q.Add("access_token", wopiToken)
|
|
q.Add("access_token_ttl", strconv.FormatInt(ttl, 10))
|
|
req.URL.RawQuery = q.Encode()
|
|
resp := httptest.NewRecorder()
|
|
|
|
mw.ServeHTTP(resp, req)
|
|
Expect(resp.Code).To(Equal(http.StatusOK))
|
|
})
|
|
It("Should authorize successful with template reference", func() {
|
|
req := httptest.NewRequest("GET", src.String(), nil).WithContext(ctx)
|
|
token, err := tknMngr.MintToken(ctx, user, nil)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
|
|
wopiContext := middleware.WopiContext{
|
|
AccessToken: token,
|
|
ViewMode: appprovider.ViewMode_VIEW_MODE_READ_WRITE,
|
|
TemplateReference: &providerv1beta1.Reference{
|
|
ResourceId: rid,
|
|
Path: ".",
|
|
},
|
|
FileReference: &providerv1beta1.Reference{
|
|
ResourceId: &providerv1beta1.ResourceId{
|
|
StorageId: "storageID",
|
|
OpaqueId: "opaqueID2",
|
|
SpaceId: "spaceID",
|
|
},
|
|
},
|
|
}
|
|
wopiToken, ttl, err := middleware.GenerateWopiToken(wopiContext, cfg, nil)
|
|
q := req.URL.Query()
|
|
q.Add("access_token", wopiToken)
|
|
q.Add("access_token_ttl", strconv.FormatInt(ttl, 10))
|
|
req.URL.RawQuery = q.Encode()
|
|
resp := httptest.NewRecorder()
|
|
|
|
mw.ServeHTTP(resp, req)
|
|
Expect(resp.Code).To(Equal(http.StatusOK))
|
|
})
|
|
It("Should not authorize when no reference matches", func() {
|
|
req := httptest.NewRequest("GET", src.String(), nil).WithContext(ctx)
|
|
token, err := tknMngr.MintToken(ctx, user, nil)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
|
|
wopiContext := middleware.WopiContext{
|
|
AccessToken: token,
|
|
ViewMode: appprovider.ViewMode_VIEW_MODE_READ_WRITE,
|
|
TemplateReference: &providerv1beta1.Reference{
|
|
ResourceId: &providerv1beta1.ResourceId{
|
|
StorageId: "storageID",
|
|
OpaqueId: "opaqueID3",
|
|
SpaceId: "spaceID",
|
|
},
|
|
Path: ".",
|
|
},
|
|
FileReference: &providerv1beta1.Reference{
|
|
ResourceId: &providerv1beta1.ResourceId{
|
|
StorageId: "storageID",
|
|
OpaqueId: "opaqueID2",
|
|
SpaceId: "spaceID",
|
|
},
|
|
},
|
|
}
|
|
wopiToken, ttl, err := middleware.GenerateWopiToken(wopiContext, cfg, nil)
|
|
q := req.URL.Query()
|
|
q.Add("access_token", wopiToken)
|
|
q.Add("access_token_ttl", strconv.FormatInt(ttl, 10))
|
|
req.URL.RawQuery = q.Encode()
|
|
resp := httptest.NewRecorder()
|
|
|
|
mw.ServeHTTP(resp, req)
|
|
Expect(resp.Code).To(Equal(http.StatusUnauthorized))
|
|
})
|
|
It("Should not authorize with proxy when fileID mismatches", func() {
|
|
cfg.Wopi.ProxySecret = "proxySecret"
|
|
cfg.Wopi.ProxyURL = "https://proxy"
|
|
src, err := wopisrc.GenerateWopiSrc(helpers.HashResourceId(rid), cfg)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
|
|
req := httptest.NewRequest("GET", src.String(), nil).WithContext(ctx)
|
|
token, err := tknMngr.MintToken(ctx, user, nil)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
wopiContext := middleware.WopiContext{
|
|
AccessToken: token,
|
|
ViewMode: appprovider.ViewMode_VIEW_MODE_READ_WRITE,
|
|
FileReference: &providerv1beta1.Reference{
|
|
ResourceId: &providerv1beta1.ResourceId{
|
|
StorageId: "storageID",
|
|
OpaqueId: "opaqueID3",
|
|
SpaceId: "spaceID",
|
|
},
|
|
Path: ".",
|
|
},
|
|
}
|
|
wopiToken, ttl, err := middleware.GenerateWopiToken(wopiContext, cfg, nil)
|
|
q := req.URL.Query()
|
|
q.Add("access_token", wopiToken)
|
|
q.Add("access_token_ttl", strconv.FormatInt(ttl, 10))
|
|
req.URL.RawQuery = q.Encode()
|
|
|
|
resp := httptest.NewRecorder()
|
|
mw.ServeHTTP(resp, req)
|
|
Expect(resp.Code).To(Equal(http.StatusUnauthorized))
|
|
})
|
|
It("Should authorize successful with proxy", func() {
|
|
cfg.Wopi.ProxySecret = "proxySecret"
|
|
cfg.Wopi.ProxyURL = "https://proxy"
|
|
src, err := wopisrc.GenerateWopiSrc(helpers.HashResourceId(rid), cfg)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
|
|
req := httptest.NewRequest("GET", src.String(), nil).WithContext(ctx)
|
|
token, err := tknMngr.MintToken(ctx, user, nil)
|
|
Expect(err).ToNot(HaveOccurred())
|
|
wopiContext := middleware.WopiContext{
|
|
AccessToken: token,
|
|
ViewMode: appprovider.ViewMode_VIEW_MODE_READ_WRITE,
|
|
FileReference: &providerv1beta1.Reference{
|
|
ResourceId: rid,
|
|
Path: ".",
|
|
},
|
|
}
|
|
wopiToken, ttl, err := middleware.GenerateWopiToken(wopiContext, cfg, nil)
|
|
q := req.URL.Query()
|
|
q.Add("access_token", wopiToken)
|
|
q.Add("access_token_ttl", strconv.FormatInt(ttl, 10))
|
|
req.URL.RawQuery = q.Encode()
|
|
|
|
resp := httptest.NewRecorder()
|
|
mw.ServeHTTP(resp, req)
|
|
Expect(resp.Code).To(Equal(http.StatusOK))
|
|
})
|
|
})
|