Skip to content

Commit

Permalink
fix sharing, some cleanups
Browse files Browse the repository at this point in the history
Signed-off-by: Jörn Friedrich Dreyer <jfd@butonic.de>
  • Loading branch information
butonic committed Aug 14, 2019
1 parent 61dc9d6 commit a2d101c
Show file tree
Hide file tree
Showing 16 changed files with 137 additions and 107 deletions.
6 changes: 5 additions & 1 deletion cmd/reva/gen/gen.go
Original file line number Diff line number Diff line change
Expand Up @@ -375,12 +375,16 @@ func WriteConfig(p string, cs string, dd string, dp string) {

var usersTemplate = `[{{range $i, $e := .}}{{if $i}},{{end}}
{
"id": {
"idp": "{{$e.Iss}}",
"opaque_id": "{{$e.Sub}}",
},
"sub": "{{$e.Sub}}",
"iss": "{{$e.Iss}}",
"username": "{{$e.Username}}",
"secret": "{{$e.Secret}}",
"mail": "{{$e.Mail}}",
"displayname": "{{$e.Displayname}}"
"display_name": "{{$e.Displayname}}"
}{{end}}
]
`
Expand Down
1 change: 0 additions & 1 deletion cmd/revad/gateway.toml
Original file line number Diff line number Diff line change
Expand Up @@ -41,5 +41,4 @@ secret = "Pive-Fumkiu4"
prefix = "owncloud"
chunk_folder = "/var/tmp/revad/chunks"
gatewaysvc = "localhost:10000"
enable_cors = true

1 change: 0 additions & 1 deletion cmd/revad/revad.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,6 @@ prefix = "ui"
prefix = "owncloud"
chunk_folder = "/var/tmp/revad/chunks"
gatewaysvc = "localhost:9999"
enable_cors = true

[http.services.datasvc]
driver = "local"
Expand Down
2 changes: 1 addition & 1 deletion cmd/revad/svcs/grpcsvcs/authsvc/authsvc.go
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ func (s *service) GenerateAccessToken(ctx context.Context, req *authv0alphapb.Ge

ctx, err := s.authmgr.Authenticate(ctx, username, password)
if err != nil {
log.Error().Err(err).Msg("error authentication user")
log.Error().Err(err).Msg("error authenticating user")
status := &rpcpb.Status{Code: rpcpb.Code_CODE_UNAUTHENTICATED}
res := &authv0alphapb.GenerateAccessTokenResponse{Status: status}
return res, nil
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -426,7 +426,7 @@ func (s *service) ListContainer(ctx context.Context, req *storageproviderv0alpha
return res, nil
}

var infos = make([]*storageproviderv0alphapb.ResourceInfo, len(mds))
infos := []*storageproviderv0alphapb.ResourceInfo{}
for _, md := range mds {

md.Path = s.wrap(ctx, md.Path, fctx)
Expand Down
10 changes: 5 additions & 5 deletions cmd/revad/svcs/httpsvcs/ocdavsvc/files.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ func (h *FilesHandler) Handler(s *svc) http.Handler {
switch r.Method {
case "PROPFIND":
s.doPropfind(w, r)
case "OPTIONS":
case http.MethodOptions:
s.doOptions(w, r)
case "HEAD":
case http.MethodHead:
s.doHead(w, r)
case "GET":
case http.MethodGet:
s.doGet(w, r)
case "LOCK":
s.doLock(w, r)
Expand All @@ -63,9 +63,9 @@ func (h *FilesHandler) Handler(s *svc) http.Handler {
s.doMove(w, r)
case "COPY":
s.doCopy(w, r)
case "PUT":
case http.MethodPut:
s.doPut(w, r)
case "DELETE":
case http.MethodDelete:
s.doDelete(w, r)
case "REPORT":
s.doReport(w, r)
Expand Down
9 changes: 8 additions & 1 deletion cmd/revad/svcs/httpsvcs/ocdavsvc/meta.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
package ocdavsvc

import (
"encoding/base64"
"net/http"

"github.com/cs3org/reva/cmd/revad/svcs/httpsvcs"
Expand Down Expand Up @@ -46,12 +47,18 @@ func (h *MetaHandler) Handler(s *svc) http.Handler {
return
}

decodedID, err := base64.StdEncoding.DecodeString(id)
if err != nil {
http.Error(w, "400 Bad Request", http.StatusBadRequest)
return
}

var head string
head, r.URL.Path = httpsvcs.ShiftPath(r.URL.Path)

switch head {
case "v":
h.VersionsHandler.Handler(s, id).ServeHTTP(w, r)
h.VersionsHandler.Handler(s, string(decodedID)).ServeHTTP(w, r)
default:
w.WriteHeader(http.StatusNotFound)
}
Expand Down
16 changes: 10 additions & 6 deletions cmd/revad/svcs/httpsvcs/ocdavsvc/propfind.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
package ocdavsvc

import (
"bytes"
"context"
"encoding/base64"
"encoding/xml"
"fmt"
"io"
Expand Down Expand Up @@ -216,11 +216,15 @@ func (s *svc) mdToPropResponse(ctx context.Context, md *storageproviderv0alphapb
// the fileID must be xml-escaped as there are cases like public links
// that contains a path as the file id. This path can contain &, for example,
// which if it is not encoded properly, will result in an empty view for the user
var fileIDEscaped bytes.Buffer
if err := xml.EscapeText(&fileIDEscaped, []byte(fmt.Sprintf("%s:%s", md.Id.StorageId, md.Id.OpaqueId))); err != nil {
return nil, err
}
ocID := s.newProp("oc:id", fileIDEscaped.String())
//var fileIDEscaped bytes.Buffer
//if err := xml.EscapeText(&fileIDEscaped, []byte(fmt.Sprintf("%s:%s", md.Id.StorageId, md.Id.OpaqueId))); err != nil {
// return nil, err
//}
//ocID := s.newProp("oc:fileid", fileIDEscaped.String())
// TODO(jfd) xmlencoding still contains slashes, but the fileid might be used in the url as well.
// for the versions endpoint we need to either also urlencode ... or just base64 encode ... it should be opaque anyway.
base64id := base64.StdEncoding.EncodeToString([]byte(fmt.Sprintf("%s:%s", md.Id.StorageId, md.Id.OpaqueId)))
ocID := s.newProp("oc:fileid", base64id)
propList = append(propList, ocID)

// PropStat, only HTTP/1.1 200 is sent.
Expand Down
8 changes: 6 additions & 2 deletions cmd/revad/svcs/httpsvcs/ocdavsvc/versions.go
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,10 @@ func (h *VersionsHandler) Handler(s *svc, fileid string) http.Handler {

var timestamp string
timestamp, r.URL.Path = httpsvcs.ShiftPath(r.URL.Path)
if r.Method == http.MethodOptions {
s.doOptions(w, r)
return
}
if timestamp == "" && r.Method == "PROPFIND" {
// TODO(jfd) list versions
h.doPropfind(w, r, s, fileid)
Expand All @@ -59,11 +63,11 @@ func (h *VersionsHandler) Handler(s *svc, fileid string) http.Handler {
h.doPropfind(w, r, s, fileid)
//case "HEAD": // TODO(jfd) since we cant GET ... there is no HEAD
// s.doHead(w, r)
case "GET": // TODO(jfd) it seems we cannot directly GET version content with cs3 ...
case http.MethodGet: // TODO(jfd) it seems we cannot directly GET version content with cs3 ...
s.doGet(w, r)
case "COPY": // TODO(jfd) restore version to Destination, but cs3api has no destination
s.doCopy(w, r)
case "DELETE": // TODO(jfd) cs3api has no delete file version call
case http.MethodDelete: // TODO(jfd) cs3api has no delete file version call
s.doDelete(w, r)
default:
http.Error(w, "403 Forbidden", http.StatusForbidden)
Expand Down
10 changes: 5 additions & 5 deletions cmd/revad/svcs/httpsvcs/ocdavsvc/webdav.go
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ func (h *WebDavHandler) Handler(s *svc) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
log := appctx.GetLogger(r.Context())

if r.Method == "OPTIONS" {
if r.Method == http.MethodOptions {
// no need for the user, and we need to be able
// to answer preflight checks, which have no auth headers
s.doOptions(w, r)
Expand Down Expand Up @@ -87,9 +87,9 @@ func (h *WebDavHandler) Handler(s *svc) http.Handler {
switch r.Method {
case "PROPFIND":
s.doPropfind(w, r)
case "HEAD":
case http.MethodHead:
s.doHead(w, r)
case "GET":
case http.MethodGet:
s.doGet(w, r)
case "LOCK":
s.doLock(w, r)
Expand All @@ -103,9 +103,9 @@ func (h *WebDavHandler) Handler(s *svc) http.Handler {
s.doMove(w, r)
case "COPY":
s.doCopy(w, r)
case "PUT":
case http.MethodPut:
s.doPut(w, r)
case "DELETE":
case http.MethodDelete:
s.doDelete(w, r)
case "REPORT":
s.doReport(w, r)
Expand Down
109 changes: 51 additions & 58 deletions cmd/revad/svcs/httpsvcs/ocssvc/shares.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@
package ocssvc

import (
"encoding/json"
"context"
"encoding/json"
"fmt"
"net/http"
"path"
Expand Down Expand Up @@ -68,18 +68,6 @@ func getUserManager(manager string, m map[string]map[string]interface{}) (user.M
return nil, fmt.Errorf("driver %s not found for user manager", manager)
}

func (h *SharesHandler) getSClient() (storageproviderv0alphapb.StorageProviderServiceClient, error) {
return pool.GetStorageProviderServiceClient(h.gatewaySvc)
}

func (h *SharesHandler) getUClient() (usershareproviderv0alphapb.UserShareProviderServiceClient, error) {
return pool.GetUserShareProviderClient(h.gatewaySvc)
}

func (h *SharesHandler) getPClient() (publicshareproviderv0alphapb.PublicShareProviderServiceClient, error) {
return pool.GetPublicShareProviderClient(h.gatewaySvc)
}

func (h *SharesHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
log := appctx.GetLogger(r.Context())

Expand Down Expand Up @@ -153,6 +141,8 @@ func (h *SharesHandler) userAsMatch(u *authv0alphapb.User) *MatchData {
Label: u.DisplayName,
Value: &MatchValueData{
ShareType: int(shareTypeUser),
// TODO(jfd) find more robust userid
// username might be ok as it is uniqe at a given point in time
ShareWith: u.Username,
},
}
Expand Down Expand Up @@ -182,6 +172,20 @@ func (h *SharesHandler) createShare(w http.ResponseWriter, r *http.Request) {
return
}

// find recipient based on username
users, err := h.userManager.FindUsers(ctx, shareWith)
if err != nil {
WriteOCSError(w, r, MetaServerError.StatusCode, "error searching recipient", err)
return
}
var recipient *authv0alphapb.User
for _, user := range users {
if user.Username == shareWith {
recipient = user
break
}
}

// we need to prefix the path with the user id
u, ok := user.ContextGetUser(ctx)
if !ok {
Expand Down Expand Up @@ -215,13 +219,13 @@ func (h *SharesHandler) createShare(w http.ResponseWriter, r *http.Request) {
// map role to permissions

var permissions *storageproviderv0alphapb.ResourcePermissions
permissions, err := h.role2CS3Permissions(role)
permissions, err = h.role2CS3Permissions(role)
if err != nil {
log.Warn().Err(err).Msg("unknown role, mapping legacy permissions")
permissions = asCS3Permissions(pint, nil)
}

uClient, err := h.getUClient()
uClient, err := pool.GetUserShareProviderClient(h.gatewaySvc)
if err != nil {
WriteOCSError(w, r, MetaServerError.StatusCode, "error getting grpc client", err)
return
Expand All @@ -241,7 +245,7 @@ func (h *SharesHandler) createShare(w http.ResponseWriter, r *http.Request) {
},
}

sClient, err := h.getSClient()
sClient, err := pool.GetStorageProviderServiceClient(h.gatewaySvc)
if err != nil {
WriteOCSError(w, r, MetaServerError.StatusCode, "error getting storage grpc client", err)
return
Expand Down Expand Up @@ -275,10 +279,7 @@ func (h *SharesHandler) createShare(w http.ResponseWriter, r *http.Request) {
Grant: &usershareproviderv0alphapb.ShareGrant{
Grantee: &storageproviderv0alphapb.Grantee{
Type: storageproviderv0alphapb.GranteeType_GRANTEE_TYPE_USER,
Id: &typespb.UserId{
// Idp: TODO get from where?
OpaqueId: shareWith,
},
Id: recipient.Id,
},
Permissions: &usershareproviderv0alphapb.SharePermissions{
Permissions: permissions,
Expand Down Expand Up @@ -469,7 +470,7 @@ func (h *SharesHandler) updateShare(w http.ResponseWriter, r *http.Request) {
shareID := strings.TrimLeft(r.URL.Path, "/")
// TODO we need to lookup the storage that is responsible for this share

uClient, err := h.getUClient()
uClient, err := pool.GetUserShareProviderClient(h.gatewaySvc)
if err != nil {
WriteOCSError(w, r, MetaServerError.StatusCode, "error getting grpc client", err)
return
Expand Down Expand Up @@ -562,7 +563,7 @@ func (h *SharesHandler) listShares(w http.ResponseWriter, r *http.Request) {
log.Debug().Str("path", p).Str("fn", fn).Interface("user", u).Msg("resolved path for user")

// first check if the file exists
sClient, err := h.getSClient()
sClient, err := pool.GetStorageProviderServiceClient(h.gatewaySvc)
if err != nil {
WriteOCSError(w, r, MetaServerError.StatusCode, "error getting grpc storage provider client", err)
return
Expand Down Expand Up @@ -603,7 +604,7 @@ func (h *SharesHandler) listShares(w http.ResponseWriter, r *http.Request) {

// fetch user shares if configured
if h.gatewaySvc != "" {
uClient, err := h.getUClient()
uClient, err := pool.GetUserShareProviderClient(h.gatewaySvc)
if err != nil {
WriteOCSError(w, r, MetaServerError.StatusCode, "error getting grpc user share handler client", err)
return
Expand Down Expand Up @@ -642,53 +643,45 @@ func (h *SharesHandler) listShares(w http.ResponseWriter, r *http.Request) {
// TODO fetch federated shares

// fetch public link shares if configured
if h.gatewaySvc != "" {
pClient, err := h.getPClient()
if err != nil {
WriteOCSError(w, r, MetaServerError.StatusCode, "error getting grpc public share provider client", err)
return
}
req := &publicshareproviderv0alphapb.ListPublicSharesRequest{}
res, err := pClient.ListPublicShares(ctx, req)
if err != nil {
WriteOCSError(w, r, MetaServerError.StatusCode, "error sending a grpc list shares request", err)
return
}
if res.Status.Code != rpcpb.Code_CODE_OK {
if res.Status.Code == rpcpb.Code_CODE_NOT_FOUND {
WriteOCSError(w, r, MetaNotFound.StatusCode, "not found", nil)
/*
if h.gatewaySvc != "" {
pClient, err := pool.GetPublicShareProviderClient(h.gatewaySvc)
if err != nil {
WriteOCSError(w, r, MetaServerError.StatusCode, "error getting grpc public share provider client", err)
return
}
WriteOCSError(w, r, MetaServerError.StatusCode, "grpc list shares request failed", err)
return
}
for _, s := range res.Share {
share := h.publicShare2ShareData(s)
err := h.addFileInfo(ctx, share, info)
req := &publicshareproviderv0alphapb.ListPublicSharesRequest{}
res, err := pClient.ListPublicShares(ctx, req)
if err != nil {
WriteOCSError(w, r, MetaServerError.StatusCode, "error adding file info", err)
WriteOCSError(w, r, MetaServerError.StatusCode, "error sending a grpc list shares request", err)
return
}
log.Debug().Interface("share", s).Interface("info", info).Interface("shareData", share).Msg("mapped")
shares = append(shares, share)
if res.Status.Code != rpcpb.Code_CODE_OK {
if res.Status.Code == rpcpb.Code_CODE_NOT_FOUND {
WriteOCSError(w, r, MetaNotFound.StatusCode, "not found", nil)
return
}
WriteOCSError(w, r, MetaServerError.StatusCode, "grpc list shares request failed", err)
return
}
for _, s := range res.Share {
share := h.publicShare2ShareData(s)
err := h.addFileInfo(ctx, share, info)
if err != nil {
WriteOCSError(w, r, MetaServerError.StatusCode, "error adding file info", err)
return
}
log.Debug().Interface("share", s).Interface("info", info).Interface("shareData", share).Msg("mapped")
shares = append(shares, share)
}
}
}
*/

WriteOCSSuccess(w, r, &SharesData{
Shares: shares,
})
}

/* TODO implement caching here?
func (h *SharesHandler) lookupUser(ctx context.Context, uid *typespb.UserId) (*authv0alphapb.User, error) {
user, err := h.userManager.GetUser(ctx, uid)
if err != nil {
return nil, err
}
return user
}
*/

func (h *SharesHandler) addFileInfo(ctx context.Context, s *ShareData, info *storageproviderv0alphapb.ResourceInfo) error {
if info != nil {
// TODO The owner is not set in the storage stat metadata ...
Expand Down
Loading

0 comments on commit a2d101c

Please sign in to comment.