Skip to content

Commit 565948b

Browse files
fabmizadlius
andcommitted
[HOTFIX][ENG-2716] Fix node permission error
Make it so the draft page doesn't break when a contributor on the draft doesn't have access to the `branched_from` node. Also updated files widget language to handle that situation. - Modified the `loadDraftAndNodeTask` returned by the route model hook to not load `branchedFrom` node. Insteand, load the node in the `initializePageManager` task. - Various other fixes to make sure things don't break. - Disabled the files widget for contributors who doesn't have access to the node and show appropriate language. Co-Authored-By: Yuhuai Liu <[email protected]>
1 parent 9a42661 commit 565948b

File tree

8 files changed

+64
-55
lines changed

8 files changed

+64
-55
lines changed

lib/osf-components/addon/components/files/manager/component.ts

Lines changed: 13 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import { tagName } from '@ember-decorators/component';
22
import Component from '@ember/component';
3-
import { assert } from '@ember/debug';
43
import { action, computed } from '@ember/object';
54
import { alias, or } from '@ember/object/computed';
65
import { inject as service } from '@ember/service';
@@ -130,19 +129,19 @@ export default class FilesManagerComponent extends Component {
130129

131130
@task({ withTestWaiter: true, restartable: true, on: 'didReceiveAttrs' })
132131
getRootItems = task(function *(this: FilesManagerComponent) {
133-
assert('@node is required', Boolean(this.node));
134-
135-
const fileProviders = yield this.node.files;
136-
const fileProvider = fileProviders.findBy('name', 'osfstorage') as FileProvider;
137-
const rootFolder = yield fileProvider.rootFolder;
138-
139-
yield rootFolder.files;
140-
141-
this.setProperties({
142-
fileProvider,
143-
rootFolder,
144-
currentFolder: rootFolder,
145-
});
132+
if (this.node) {
133+
const fileProviders = yield this.node.files;
134+
const fileProvider = fileProviders.findBy('name', 'osfstorage') as FileProvider;
135+
const rootFolder = yield fileProvider.rootFolder;
136+
137+
yield rootFolder.files;
138+
139+
this.setProperties({
140+
fileProvider,
141+
rootFolder,
142+
currentFolder: rootFolder,
143+
});
144+
}
146145
});
147146

148147
@task({ withTestWaiter: true })

lib/osf-components/addon/components/registries/schema-block-renderer/editable/files/component.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ export default class Files extends Component {
4242

4343
@computed('node')
4444
get nodeUrl() {
45-
return this.node && pathJoin(baseURL, this.node.id);
45+
return pathJoin(baseURL, this.draftRegistration.belongsTo('branchedFrom').id());
4646
}
4747

4848
didReceiveAttrs() {

lib/osf-components/addon/components/registries/schema-block-renderer/editable/files/styles.scss

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,4 +14,9 @@
1414

1515
.FilesWidget {
1616
composes: Element from '../../styles';
17+
18+
&[disabled] {
19+
opacity: 0.5;
20+
pointer-events: none;
21+
}
1722
}

lib/osf-components/addon/components/registries/schema-block-renderer/editable/files/template.hbs

Lines changed: 14 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,11 +3,18 @@
33
local-class='FilesInstructions'
44
>
55
{{#if @draftRegistration.hasProject}}
6-
{{t 'osf-components.registries.schema-block-renderer/editable/files.instructions'
7-
projectOrComponent=(if this.node.isRoot 'project' 'component')
8-
nodeUrl=this.nodeUrl
9-
htmlSafe=true
10-
}}
6+
{{#if this.node}}
7+
{{t 'osf-components.registries.schema-block-renderer/editable/files.instructions'
8+
projectOrComponent=(if this.node.isRoot 'project' 'component')
9+
nodeUrl=this.nodeUrl
10+
htmlSafe=true
11+
}}
12+
{{else}}
13+
{{t 'osf-components.registries.schema-block-renderer/editable/files.instructionsNoPermissions'
14+
nodeUrl=this.nodeUrl
15+
htmlSafe=true
16+
}}
17+
{{/if}}
1118
{{else}}
1219
{{t 'osf-components.registries.schema-block-renderer/editable/files.instructionsNoProject'
1320
htmlSafe=true
@@ -32,6 +39,7 @@
3239
@onSelectFile={{action this.onSelectFile}}
3340
@onAddFile={{action this.onAddFile}}
3441
@onDeleteFile={{this.onDeleteFile}}
35-
@canEdit={{not this.currentUserIsReadOnly}}
42+
@canEdit={{and this.node (not this.currentUserIsReadOnly)}}
43+
disabled={{not this.node}}
3644
...attributes
3745
/>

lib/registries/addon/drafts/draft/draft-registration-manager.ts

Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -25,13 +25,12 @@ import buildChangeset from 'ember-osf-web/utils/build-changeset';
2525

2626
type LoadDraftModelTask = TaskInstance<{
2727
draftRegistration: DraftRegistration,
28-
node?: NodeModel,
2928
provider: ProviderModel,
3029
}>;
3130

3231
export default class DraftRegistrationManager {
3332
// Required
34-
draftRegistrationAndNodeTask!: LoadDraftModelTask;
33+
draftRegistrationTask!: LoadDraftModelTask;
3534

3635
// Private
3736
@service intl!: Intl;
@@ -79,10 +78,16 @@ export default class DraftRegistrationManager {
7978

8079
@task({ withTestWaiter: true })
8180
initializePageManagers = task(function *(this: DraftRegistrationManager) {
82-
const { draftRegistration, node, provider } = yield this.draftRegistrationAndNodeTask;
81+
const { draftRegistration, provider } = yield this.draftRegistrationTask;
8382
set(this, 'draftRegistration', draftRegistration);
84-
set(this, 'node', node);
8583
set(this, 'provider', provider);
84+
try {
85+
const node = yield this.draftRegistration.branchedFrom;
86+
set(this, 'node', node);
87+
} catch (e) {
88+
captureException(e);
89+
set(this, 'node', undefined);
90+
}
8691
const registrationSchema = yield this.draftRegistration.registrationSchema;
8792
const schemaBlocks: SchemaBlock[] = yield registrationSchema.loadAll('schemaBlocks');
8893
set(this, 'schemaBlocks', schemaBlocks);
@@ -104,7 +109,7 @@ export default class DraftRegistrationManager {
104109

105110
@task({ withTestWaiter: true })
106111
initializeMetadataChangeset = task(function *(this: DraftRegistrationManager) {
107-
const { draftRegistration } = yield this.draftRegistrationAndNodeTask;
112+
const { draftRegistration } = yield this.draftRegistrationTask;
108113
const metadataValidations = buildMetadataValidations();
109114
const metadataChangeset = buildChangeset(draftRegistration, metadataValidations);
110115
set(this, 'metadataChangeset', metadataChangeset);
@@ -167,8 +172,8 @@ export default class DraftRegistrationManager {
167172
}
168173
});
169174

170-
constructor(draftRegistrationAndNodeTask: LoadDraftModelTask) {
171-
set(this, 'draftRegistrationAndNodeTask', draftRegistrationAndNodeTask);
175+
constructor(draftRegistrationTask: LoadDraftModelTask) {
176+
set(this, 'draftRegistrationTask', draftRegistrationTask);
172177
this.initializePageManagers.perform();
173178
this.initializeMetadataChangeset.perform();
174179
}

lib/registries/addon/drafts/draft/route.ts

Lines changed: 17 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,7 @@ import { task } from 'ember-concurrency-decorators';
66
import DS from 'ember-data';
77

88
import requireAuth from 'ember-osf-web/decorators/require-auth';
9-
import DraftNode from 'ember-osf-web/models/draft-node';
109
import DraftRegistration from 'ember-osf-web/models/draft-registration';
11-
import NodeModel from 'ember-osf-web/models/node';
1210
import ProviderModel from 'ember-osf-web/models/provider';
1311
import SubjectModel from 'ember-osf-web/models/subject';
1412
import Analytics from 'ember-osf-web/services/analytics';
@@ -27,35 +25,28 @@ export default class DraftRegistrationRoute extends Route {
2725
@service router!: RouterService;
2826

2927
@task({ withTestWaiter: true })
30-
loadDraftRegistrationAndNode = task(function *(this: DraftRegistrationRoute, draftId: string) {
31-
try {
32-
const draftRegistration: DraftRegistration = yield this.store.findRecord(
33-
'draft-registration',
34-
draftId,
35-
{ adapterOptions: { include: 'branched_from' } },
36-
);
37-
const [subjects, node, provider]:
38-
[SubjectModel[], NodeModel | DraftNode, ProviderModel] = yield Promise.all([
39-
draftRegistration.loadAll('subjects'),
40-
draftRegistration.branchedFrom as NodeModel | DraftNode,
41-
draftRegistration.provider,
42-
]);
43-
44-
draftRegistration.setProperties({ subjects });
45-
if (draftRegistration.currentUserIsReadOnly) {
46-
this.replaceWith('drafts.draft.review', draftId);
47-
}
48-
return { draftRegistration, node, provider };
49-
} catch (error) {
50-
this.transitionTo('page-not-found', this.router.currentURL.slice(1));
51-
return undefined;
28+
loadDraftRegistration = task(function *(this: DraftRegistrationRoute, draftId: string) {
29+
const draftRegistration: DraftRegistration = yield this.store.findRecord(
30+
'draft-registration',
31+
draftId,
32+
{ adapterOptions: { include: 'branched_from' } },
33+
);
34+
const [subjects, provider]:
35+
[SubjectModel[], ProviderModel] = yield Promise.all([
36+
draftRegistration.loadAll('subjects'),
37+
draftRegistration.provider,
38+
]);
39+
draftRegistration.setProperties({ subjects });
40+
if (draftRegistration.currentUserIsReadOnly) {
41+
this.replaceWith('drafts.draft.review', draftId);
5242
}
43+
return { draftRegistration, provider };
5344
});
5445

5546
model(params: { id: string }): DraftRouteModel {
5647
const { id: draftId } = params;
57-
const draftRegistrationAndNodeTask = this.loadDraftRegistrationAndNode.perform(draftId);
58-
const draftRegistrationManager = new DraftRegistrationManager(draftRegistrationAndNodeTask);
48+
const draftRegistrationTask = this.loadDraftRegistration.perform(draftId);
49+
const draftRegistrationManager = new DraftRegistrationManager(draftRegistrationTask);
5950
const navigationManager = new NavigationManager(draftRegistrationManager);
6051
return {
6152
navigationManager,

lib/registries/addon/drafts/draft/template.hbs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
<layout.heading>
1717
<HeroOverlay @align='left' local-class='DraftHeroOverlay'>
1818
<div local-class='Title'>
19-
{{#if draftManager.hasProject}}
19+
{{#if (and draftManager.hasProject draftManager.node)}}
2020
<OsfLink
2121
data-test-link-back-to-project
2222
data-analytics-name='Go to project'

translations/en-us.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1592,6 +1592,7 @@ osf-components:
15921592
schema-block-renderer/editable/files:
15931593
instructions: 'You may attach up to 5 file(s) to this question. You may attach files that you already have in OSF Storage in this <a href={nodeUrl}>{projectOrComponent}</a> or upload (drag and drop) a new file from your computer. Uploaded files will automatically be added to this <a href={nodeUrl}>{projectOrComponent}</a> so that they can be registered. To attach files from other components or an add-on, first add them to this <a href={nodeUrl}>{projectOrComponent}</a>.'
15941594
instructionsNoProject: 'You may attach up to 5 file(s) to this question. Files cannot total over 5GB in size.<br><br>Uploaded files will automatically be archived in this registration. They will also be added to a related project that will be created for this registration.'
1595+
instructionsNoPermissions: 'This registration is branched from <a href={nodeUrl}>an OSF Project</a>, and only contributors added to it can upload and edit files. Contact one of the registration''s administrative contributors to be added to the project. Learn more about OSF Projects by visiting our <a href="https://help.osf.io/hc/en-us/categories/360001495973-Creating-and-Managing-Projects">help guides</a>.'
15951596
schema-block-renderer/read-only/response:
15961597
noResponse: 'No response'
15971598
schema-block-renderer/read-only/files:

0 commit comments

Comments
 (0)