Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[full-ci] Sharing jail #6593

Merged
merged 45 commits into from
May 6, 2022
Merged
Show file tree
Hide file tree
Changes from 29 commits
Commits
Show all changes
45 commits
Select commit Hold shift + click to select a range
b30d205
Fix unit tests
kulmann Apr 29, 2022
6ac971f
Code cleanup in folder service and tasks
kulmann Mar 14, 2022
6f1ec79
Rename "isEnabled" to "isActive" in folder loaders
kulmann Mar 14, 2022
eda92c3
make loader tasks context aware (capabilities)
kulmann Mar 14, 2022
fb2d36c
Add share routes in spaces namespace
kulmann Mar 15, 2022
ae7c9f4
Route shares into a new view for spaces-aware backend
kulmann Mar 15, 2022
846501f
Add error logging to folder service task execution
kulmann Mar 16, 2022
3839386
Share loader task
kulmann Mar 16, 2022
871a281
Introduce personal space resource loader
kulmann Mar 17, 2022
b2e8c06
Load share root in new view
kulmann Mar 18, 2022
652b1f7
Fix share view breadcrumb
kulmann Apr 26, 2022
8d070bf
Fix path and selection handling in SharedResource view
kulmann Apr 26, 2022
ddc564d
relative path handling for shares
kulmann Apr 26, 2022
bc7895a
Fix file and folder creation inside share
kulmann Apr 26, 2022
e4ee645
Include SharedResource route in active state of Shares nav item
kulmann Apr 27, 2022
aae1251
Make file actions available on share routes
kulmann Apr 27, 2022
9d68b08
Switch location picker to personal space dav endpoint
kulmann Apr 28, 2022
07bbaa8
Include current route query in breadcrumb items
kulmann Apr 28, 2022
7038b34
Add resourceId to whitelisted query items
kulmann Apr 28, 2022
ba1ff46
Rename resourceId query option to shareId
kulmann Apr 28, 2022
6845b47
Make use of share_jail feature flag in capabilities.spaces
kulmann Apr 29, 2022
95b35b7
Fix sharing quick action availability
kulmann Apr 29, 2022
e054400
Fix navigating into shares immediately after accept
kulmann Apr 29, 2022
5daf152
Fix unit tests
kulmann Apr 29, 2022
30f5d81
Fix showing shares in right sidebar on shared with me page
kulmann Apr 29, 2022
23e03eb
Fix non-share jail shared with me page
kulmann Apr 29, 2022
f3ae561
Capability usage cleanup after rebase
kulmann May 4, 2022
c629c51
Fix SharedResource view after rebase
kulmann May 5, 2022
382b4f4
Remove reportGenerator/cucumber_report.json from repo and ignore
kulmann May 5, 2022
1b5ee19
Fix share name in right sidebar (shared with me page)
kulmann May 5, 2022
775ea4d
Fix uploads in share jail shares
kulmann May 5, 2022
d7cd772
Code cleanup
kulmann May 5, 2022
67ada47
Fix folder uploads in shares
kulmann May 5, 2022
edb9f94
Disable renaming of shares for share jail until fixed in backend
kulmann May 5, 2022
4fcbfc0
Fix Open Folder action for shares
kulmann May 5, 2022
2447847
Exclude pending and declined shares for editor app open actions
kulmann May 5, 2022
91f7696
Fix parent folder links in resource table
kulmann May 5, 2022
5638f69
fix ocis kindergarten e2e test journey
fschade May 5, 2022
584e39b
REVERT: Skip unit&e2e tests
pascalwengerter May 5, 2022
37be2c6
Adjust tests for sharing jail
kulmann May 6, 2022
bc7a917
Use personal space for fetching file info after upload
kulmann May 6, 2022
ed92383
Load newly created files/folders via personal space
kulmann May 6, 2022
87e2199
bring back ci e2e tests
fschade May 6, 2022
9fbab06
fix starlark
fschade May 6, 2022
ba47836
Skip last resharing test in oCIS CI
pascalwengerter May 6, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ dist

reports
tests/e2e/cucumber/report/cucumber_report.json
tests/e2e/cucumber/reportGenerator/cucumber_report.json
tests/ocis
tests/testing-app

Expand Down
13 changes: 13 additions & 0 deletions packages/web-app-files/src/components/AppBar/CreateAndUpload.vue
Original file line number Diff line number Diff line change
Expand Up @@ -116,6 +116,7 @@ import ResourceUpload from './Upload/ResourceUpload.vue'
import { defineComponent, getCurrentInstance, onMounted } from '@vue/composition-api'
import { UppyResource, useUpload } from 'web-runtime/src/composables/upload'
import { useUploadHelpers } from '../../composables/upload'
import { SHARE_JAIL_ID } from '../../services/folder'

export default defineComponent({
components: {
Expand Down Expand Up @@ -153,6 +154,7 @@ export default defineComponent({
isPublicLocation: useActiveLocation(isLocationPublicActive, 'files-public-files'),
isSpacesProjectsLocation: useActiveLocation(isLocationSpacesActive, 'files-spaces-projects'),
isSpacesProjectLocation: useActiveLocation(isLocationSpacesActive, 'files-spaces-project'),
isSpacesShareLocation: useActiveLocation(isLocationSpacesActive, 'files-spaces-share'),
...useAppDefaults({
applicationName: 'files'
})
Expand Down Expand Up @@ -386,6 +388,10 @@ export default defineComponent({
path = buildWebDavSpacesPath(this.$route.params.storageId, path)
await this.$client.files.createFolder(path)
resource = await this.$client.files.fileInfo(path, DavProperties.Default)
} else if (this.isSpacesShareLocation) {
path = buildWebDavSpacesPath([SHARE_JAIL_ID, this.$route.query.shareId].join('!'), path)
await this.$client.files.createFolder(path)
resource = await this.$client.files.fileInfo(path, DavProperties.Default)
} else {
await this.$client.publicFiles.createFolder(path, null, this.publicLinkPassword)
resource = await this.$client.publicFiles.getFileInfo(
Expand Down Expand Up @@ -475,6 +481,10 @@ export default defineComponent({
path = buildWebDavSpacesPath(this.$route.params.storageId, path)
await this.$client.files.putFileContents(path, '')
resource = await this.$client.files.fileInfo(path, DavProperties.Default)
} else if (this.isSpacesShareLocation) {
path = buildWebDavSpacesPath([SHARE_JAIL_ID, this.$route.query.shareId].join('!'), path)
await this.$client.files.putFileContents(path, '')
resource = await this.$client.files.fileInfo(path, DavProperties.Default)
} else {
await this.$client.publicFiles.putFileContents('', path, this.publicLinkPassword, '')
resource = await this.$client.publicFiles.getFileInfo(
Expand Down Expand Up @@ -547,6 +557,9 @@ export default defineComponent({
} else if (this.isSpacesProjectLocation) {
path = buildWebDavSpacesPath(this.$route.params.storageId, path)
resource = await this.$client.files.fileInfo(path, DavProperties.Default)
} else if (this.isSpacesShareLocation) {
path = buildWebDavSpacesPath([SHARE_JAIL_ID, this.$route.query.shareId].join('!'), path)
resource = await this.$client.files.fileInfo(path, DavProperties.Default)
} else {
resource = await this.$client.publicFiles.getFileInfo(
path,
Expand Down
72 changes: 56 additions & 16 deletions packages/web-app-files/src/components/FilesList/ResourceTable.vue
Original file line number Diff line number Diff line change
Expand Up @@ -171,13 +171,20 @@ import { EVENT_TROW_MOUNTED, EVENT_FILE_DROPPED } from '../../constants'
import { SortDir } from '../../composables'
import * as path from 'path'
import { determineSortFields } from '../../helpers/ui/resourceTable'
import { useCapabilitySpacesEnabled } from 'web-pkg/src/composables'
import { useCapabilityShareJailEnabled } from 'web-pkg/src/composables'
import Rename from '../../mixins/actions/rename'
import { defineComponent, PropType } from '@vue/composition-api'
import { extractDomSelector, Resource } from '../../helpers/resource'
import { ShareTypes } from '../../helpers/share'
import { createLocationSpaces } from '../../router'

const mapResourceFields = (resource: Resource, mapping = {}) => {
return Object.keys(mapping).reduce((result, resourceKey) => {
result[mapping[resourceKey]] = resource[resourceKey]
return result
}, {})
}

export default defineComponent({
mixins: [Rename],
model: {
Expand Down Expand Up @@ -251,6 +258,33 @@ export default defineComponent({
required: false,
default: null
},
/**
* Maps resource values to route params. Use `{ resourceFieldName: 'routeParamName' }` as format.
*
* An example would be `{ id: 'fileId' }` to map the value of the `id` field of a resource
* to the `fileId` param of the target route.
*
* Defaults to `{ storageId: 'storageId' } to map the value of the `storageId` field of a resource
* to the `storageId` param of the target route.
*/
targetRouteParamMapping: {
type: Object,
required: false,
default: () => ({ storageId: 'storageId' })
},
/**
* Maps resource values to route query options. Use `{ resourceFieldName: 'routeQueryName' }` as format.
*
* An example would be `{ id: 'fileId' }` to map the value of the `id` field of a resource
* to the `fileId` query option of the target route.
*
* Defaults to an empty object because no query options are expected as default.
*/
targetRouteQueryMapping: {
type: Object,
required: false,
default: () => ({})
},
/**
* Asserts whether clicking on the resource name triggers any action
*/
Expand Down Expand Up @@ -342,7 +376,7 @@ export default defineComponent({
},
setup() {
return {
hasSpaces: useCapabilitySpacesEnabled()
hasShareJail: useCapabilityShareJailEnabled()
}
},
data() {
Expand Down Expand Up @@ -532,32 +566,38 @@ export default defineComponent({
this.openWithPanel('sharing-item')
},
folderLink(file) {
return this.createFolderLink(file.path, file.storageId)
return this.createFolderLink(file.path, file)
},
parentFolderLink(file) {
return this.createFolderLink(path.dirname(file.path), file.storageId)
return this.createFolderLink(path.dirname(file.path), file)
},
createFolderLink(path, storageId) {
createFolderLink(path, resource) {
if (this.targetRoute === null) {
return {}
}

const matchingSpace = this.getMatchingSpace(storageId)
const params = {
item: path.replace(/^\//, ''),
...this.targetRoute.params,
...mapResourceFields(resource, this.targetRouteParamMapping)
}
const query = {
...this.targetRoute.query,
...mapResourceFields(resource, this.targetRouteQueryMapping)
}

const matchingSpace = this.getMatchingSpace(resource.storageId)
if (matchingSpace && matchingSpace?.driveType === 'project') {
return createLocationSpaces('files-spaces-project', {
params: { storageId, item: path.replace(/^\//, '') || undefined }
params,
query
})
}

return {
name: this.targetRoute.name,
query: this.targetRoute.query,
params: {
item: path.replace(/^\//, '') || undefined,
...this.targetRoute.params,
...(storageId && { storageId })
}
params,
query
}
},
fileDragged(file) {
Expand Down Expand Up @@ -705,12 +745,12 @@ export default defineComponent({
return this.spaces.find((space) => space.id === storageId)
},
getDefaultParentFolderName(resource) {
if (!this.hasSpaces) {
if (!this.hasShareJail) {
return this.$gettext('All files and folders')
}
const matchingSpace = this.getMatchingSpace(resource.storageId)

if (matchingSpace && matchingSpace?.driveType === 'project') {
const matchingSpace = this.getMatchingSpace(resource.storageId)
if (matchingSpace?.driveType === 'project') {
return matchingSpace.name
}

Expand Down
6 changes: 3 additions & 3 deletions packages/web-app-files/src/components/Search/Preview.vue
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ import Vue from 'vue'
import { mapGetters, mapState } from 'vuex'
import { createLocationSpaces } from '../../router'
import path from 'path'
import { useCapabilitySpacesEnabled } from 'web-pkg/src/composables'
import { useCapabilityShareJailEnabled } from 'web-pkg/src/composables'

const visibilityObserver = new VisibilityObserver()

Expand All @@ -43,7 +43,7 @@ export default {
},
setup() {
return {
hasSpaces: useCapabilitySpacesEnabled(),
hasShareJail: useCapabilityShareJailEnabled(),
resourceTargetLocation: createLocationSpaces('files-spaces-personal-home'),
resourceTargetLocationSpace: createLocationSpaces('files-spaces-project')
}
Expand All @@ -61,7 +61,7 @@ export default {
return this.spaces.find((space) => space.id === this.resource.storageId)
},
defaultParentFolderName() {
if (!this.hasSpaces) {
if (!this.hasShareJail) {
return this.$gettext('All files and folders')
}

Expand Down
3 changes: 3 additions & 0 deletions packages/web-app-files/src/components/SideBar/SideBar.vue
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,9 @@ export default defineComponent({
// root path `/` like for personal home doesn't exist for public links
return pathSegments.length === 1
}
if (isLocationSharesActive(this.$router, 'files-shares-with-me')) {
return !this.highlightedFile
}
return !pathSegments.length
},
highlightedFileThumbnail() {
Expand Down
12 changes: 8 additions & 4 deletions packages/web-app-files/src/helpers/breadcrumbs.ts
Original file line number Diff line number Diff line change
@@ -1,26 +1,30 @@
import { bus } from 'web-pkg/src/instance'
import { Location } from 'vue-router'

export interface BreadcrumbItem {
text: string
to?: string
to?: Location
allowContextActions?: boolean
onClick?: () => void
}

export const breadcrumbsFromPath = (
currentPath: string,
currentRoute: Location,
resourcePath: string
): BreadcrumbItem[] => {
const pathSplit = (p = '') => p.split('/').filter(Boolean)
const current = pathSplit(currentPath)
const current = pathSplit(currentRoute.path)
const resource = pathSplit(resourcePath)

return resource.map(
(text, i) =>
({
allowContextActions: true,
text,
to: '/' + [...current].splice(0, current.length - resource.length + i + 1).join('/')
to: {
path: '/' + [...current].splice(0, current.length - resource.length + i + 1).join('/'),
query: currentRoute.query
}
} as BreadcrumbItem)
)
}
Expand Down
31 changes: 22 additions & 9 deletions packages/web-app-files/src/helpers/resources.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import {
Resource
} from './resource'
import { User } from './user'
import { SHARE_JAIL_ID } from '../services/folder'

export function renameResource(resource, newName, newPath) {
let resourcePath = '/' + newPath + newName
Expand Down Expand Up @@ -259,26 +260,26 @@ export function attachIndicators(resource, sharesTree) {
* @param {Array} shares Shares to be transformed into unique resources
* @param {Boolean} incomingShares Asserts whether the shares are incoming
* @param {Boolean} allowSharePermission Asserts whether the reshare permission is available
* @param {String} server The url of the backend
* @param {String} token The access token of the authenticated user
* @param {Boolean} hasShareJail Asserts whether the share jail is available backend side
*/
export function aggregateResourceShares(
shares,
incomingShares = false,
allowSharePermission,
server,
token
hasShareJail
): Resource[] {
if (incomingShares) {
shares = addSharedWithToShares(shares)
return orderBy(shares, ['file_target', 'permissions'], ['asc', 'desc']).map((share) =>
buildSharedResource(share, incomingShares, allowSharePermission)
buildSharedResource(share, incomingShares, allowSharePermission, hasShareJail)
)
}

shares.sort((a, b) => a.path.localeCompare(b.path))
const resources = addSharedWithToShares(shares)
return resources.map((share) => buildSharedResource(share, incomingShares, allowSharePermission))
return resources.map((share) =>
buildSharedResource(share, incomingShares, allowSharePermission, hasShareJail)
)
}

function addSharedWithToShares(shares) {
Expand Down Expand Up @@ -334,7 +335,12 @@ function addSharedWithToShares(shares) {
return resources
}

export function buildSharedResource(share, incomingShares = false, allowSharePermission): Resource {
export function buildSharedResource(
share,
incomingShares = false,
allowSharePermission = true,
hasShareJail = false
): Resource {
const isFolder = share.item_type === 'folder'
const resource: Resource = {
id: share.id,
Expand Down Expand Up @@ -365,8 +371,15 @@ export function buildSharedResource(share, incomingShares = false, allowSharePer
resource.sharedWith = share.sharedWith || []
resource.status = parseInt(share.state)
resource.name = path.basename(share.file_target)
resource.path = share.file_target
resource.webDavPath = buildWebDavFilesPath(share.share_with, share.file_target)
if (hasShareJail) {
// FIXME, HACK 1: path needs to be '/' because the share has it's own webdav endpoint (we access it's root). should ideally be removed backend side.
// FIXME, HACK 2: webDavPath points to `files/<user>/Shares/xyz` but now needs to point to a shares webdav root. should ideally be changed backend side.
resource.path = '/'
resource.webDavPath = buildWebDavSpacesPath([SHARE_JAIL_ID, resource.id].join('!'), '/')
} else {
resource.path = share.file_target
resource.webDavPath = buildWebDavFilesPath(share.share_with, share.file_target)
}
resource.canDownload = () => share.state === ShareStatus.accepted
resource.canShare = () => SharePermissions.share.enabled(share.permissions)
resource.canRename = () => SharePermissions.update.enabled(share.permissions)
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { buildSharedResource } from '../resources'
import { ShareStatus } from './status'

export async function triggerShareAction(resource, status, allowReSharing, $client) {
export async function triggerShareAction(resource, status, hasReSharing, hasShareJail, $client) {
const method = _getRequestMethod(status)
if (!method) {
throw new Error('invalid new share status')
Expand All @@ -24,7 +24,7 @@ export async function triggerShareAction(resource, status, allowReSharing, $clie
response = await response.json()
if (response.ocs.data.length > 0) {
const share = response.ocs.data[0]
return buildSharedResource(share, true, allowReSharing)
return buildSharedResource(share, true, hasReSharing, hasShareJail)
}
}

Expand Down
7 changes: 5 additions & 2 deletions packages/web-app-files/src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import PrivateLink from './views/PrivateLink.vue'
import PublicFiles from './views/PublicFiles.vue'
import PublicLink from './views/PublicLink.vue'
import Personal from './views/Personal.vue'
import SharedResource from './views/shares/SharedResource.vue'
import SharedWithMe from './views/shares/SharedWithMe.vue'
import SharedWithOthers from './views/shares/SharedWithOthers.vue'
import SharedViaLink from './views/shares/SharedViaLink.vue'
Expand Down Expand Up @@ -65,7 +66,8 @@ const navItems = [
icon: 'share-forward',
route: {
path: `/${appInfo.id}/shares`
}
},
activeFor: [{ path: `/${appInfo.id}/spaces/shares` }]
},
{
name: $gettext('Spaces'),
Expand All @@ -75,7 +77,7 @@ const navItems = [
path: `/${appInfo.id}/spaces/projects`
},
enabled(capabilities) {
return capabilities.spaces && capabilities.spaces.enabled === true
return capabilities.spaces && capabilities.spaces.projects === true
}
},
{
Expand Down Expand Up @@ -103,6 +105,7 @@ export default {
PublicFiles,
PublicLink,
SearchResults,
SharedResource,
SharedViaLink,
SharedWithMe,
SharedWithOthers,
Expand Down
Loading