Skip to content

Commit 996ceb5

Browse files
committed
COMPASS-251 COMPASS-252 COMPASS-253: Guarding Write Operations (#581)
* Guard against write operations: COMPASS-251, COMPASS-252, COMPASS-253: Doesn't allow user to perform CRUD or DDL operations when the server is not writable or the view is readonly. * Fix tests
1 parent c4cef98 commit 996ceb5

File tree

14 files changed

+90
-29
lines changed

14 files changed

+90
-29
lines changed

src/internal-packages/app/lib/stores/collection-store.js

Lines changed: 31 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
const app = require('ampersand-app');
12
const Reflux = require('reflux');
23
const { NamespaceStore } = require('hadron-reflux-store');
34

@@ -10,8 +11,7 @@ const CollectionStore = Reflux.createStore({
1011
* Initialize the store.
1112
*/
1213
init() {
13-
this.ns = null;
14-
this.readonly = null;
14+
this.collection = {};
1515
},
1616

1717
/**
@@ -20,11 +20,37 @@ const CollectionStore = Reflux.createStore({
2020
* @param {Object} collection - The collection info.
2121
*/
2222
setCollection(collection) {
23-
this.ns = collection._id;
24-
this.readonly = collection.readonly;
23+
this.collection = collection;
2524
if (collection._id) {
26-
NamespaceStore.ns = this.ns;
25+
NamespaceStore.ns = collection._id;
2726
}
27+
},
28+
29+
/**
30+
* Get the collection ns.
31+
*
32+
* @returns {String} The collection ns.
33+
*/
34+
ns() {
35+
return this.collection._id;
36+
},
37+
38+
/**
39+
* Is the collection readonly?
40+
*
41+
* @returns {Boolean} If the collection is readonly.
42+
*/
43+
isReadonly() {
44+
return this.collection.readonly;
45+
},
46+
47+
/**
48+
* Is the collection writable?
49+
*
50+
* @returns {Boolean} If the collection is writable.
51+
*/
52+
isWritable() {
53+
return !this.isReadonly() && app.dataService.isWritable();
2854
}
2955
});
3056

src/internal-packages/collection-stats/lib/store/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ const CollectionStatsStore = Reflux.createStore({
3030
*/
3131
loadCollectionStats: function(ns) {
3232
if (toNS(ns || '').collection) {
33-
if (this.CollectionStore.readonly) {
33+
if (this.CollectionStore.isReadonly()) {
3434
this.trigger();
3535
} else {
3636
app.dataService.collection(ns, { readPreference: READ }, (err, result) => {

src/internal-packages/crud/lib/component/document-list.jsx

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -220,11 +220,10 @@ class DocumentList extends React.Component {
220220
* @return {Array} The document list item components.
221221
*/
222222
renderDocuments(docs) {
223-
const editable = app.dataService.isWritable() && !this.CollectionStore.readonly;
224223
return _.map(docs, (doc) => {
225224
return (
226225
<li className="document-list-item" key={this._key()}>
227-
<Document doc={doc} key={this._key(doc)} editable={editable} />
226+
<Document doc={doc} key={this._key(doc)} editable={this.CollectionStore.isWritable()} />
228227
</li>
229228
);
230229
});

src/internal-packages/database/lib/components/collections-table.jsx

Lines changed: 8 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,16 @@ class CollectionsTable extends React.Component {
3838
});
3939
});
4040

41+
const writable = app.dataService.isWritable();
42+
4143
return (
4244
<div className="collections-table">
4345
<div className="collections-table-create-button">
44-
<TextButton
45-
text="Create Collection"
46-
className="btn btn-default btn-sm"
47-
clickHandler={this.onCreateCollectionButtonClicked.bind(this)} />
46+
{writable ?
47+
<TextButton
48+
text="Create Collection"
49+
className="btn btn-default btn-sm"
50+
clickHandler={this.onCreateCollectionButtonClicked.bind(this)} /> : null}
4851
</div>
4952
<this.SortableTable
5053
theme="light"
@@ -54,7 +57,7 @@ class CollectionsTable extends React.Component {
5457
sortOrder={this.props.sortOrder}
5558
sortColumn={this.props.sortColumn}
5659
valueIndex={0}
57-
removable
60+
removable={writable}
5861
onColumnHeaderClicked={this.onColumnHeaderClicked.bind(this)}
5962
onRowDeleteButtonClicked={this.onRowDeleteButtonClicked.bind(this)}
6063
/>

src/internal-packages/explain/lib/components/compass-explain.jsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ class CompassExplain extends React.Component {
7373
return (
7474
<div className="compass-explain header-margin">
7575
<div className="flexbox-fix"></div>
76-
{this.CollectionStore.readonly ? this.renderReadonly() : this.renderComponent()}
76+
{this.CollectionStore.isReadonly() ? this.renderReadonly() : this.renderComponent()}
7777
</div>
7878
);
7979
}

src/internal-packages/explain/lib/stores/index.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -123,7 +123,7 @@ const CompassExplainStore = Reflux.createStore({
123123
if (!ns.database || !ns.collection) {
124124
return;
125125
}
126-
if (this.CollectionStore.readonly) {
126+
if (this.CollectionStore.isReadonly()) {
127127
this.setState(this.getInitialState());
128128
} else {
129129
app.dataService.explain(ns.ns, filter, options, (err, explain) => {

src/internal-packages/indexes/lib/component/index-header.jsx

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ class IndexHeader extends React.Component {
1818
constructor(props) {
1919
super(props);
2020
this.state = { sortOrder: ASC };
21+
this.CollectionStore = app.appRegistry.getStore('App.CollectionStore');
2122
}
2223

2324
/**
@@ -59,7 +60,7 @@ class IndexHeader extends React.Component {
5960
<IndexHeaderColumn hook="th-size" name="Size" sortOrder={this.state.sortOrder} />
6061
<IndexHeaderColumn hook="th-usage" name="Usage" sortOrder={this.state.sortOrder} />
6162
<IndexHeaderColumn hook="th-properties" name="Properties" sortOrder={this.state.sortOrder} />
62-
{app.dataService.isWritable() ?
63+
{this.CollectionStore.isWritable() ?
6364
<IndexHeaderColumn hook="th-drop" name="Drop" sortOrder={this.state.sortOrder}/>
6465
: null}
6566
</tr>

src/internal-packages/indexes/lib/component/index.jsx

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,11 @@ const app = require('ampersand-app');
1212
*/
1313
class Index extends React.Component {
1414

15+
constructor(props) {
16+
super(props);
17+
this.CollectionStore = app.appRegistry.getStore('App.CollectionStore');
18+
}
19+
1520
/**
1621
* Render the index.
1722
*
@@ -27,7 +32,7 @@ class Index extends React.Component {
2732
relativeSize={this.props.index.relativeSize} />
2833
<UsageColumn usage={this.props.index.usageCount} since={this.props.index.usageSince} />
2934
<PropertyColumn index={this.props.index} />
30-
{app.dataService.isWritable() ?
35+
{this.CollectionStore.isWritable() ?
3136
<DropColumn indexName={this.props.index.name} />
3237
: null}
3338
</tr>

src/internal-packages/indexes/lib/component/indexes.jsx

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,10 @@ class Indexes extends React.Component {
3636
}
3737

3838
determineState() {
39-
const writable = app.dataService.isWritable() && !this.CollectionStore.readonly;
40-
return { writable: writable, readonly: this.CollectionStore.readonly };
39+
return {
40+
writable: this.CollectionStore.isWritable(),
41+
readonly: this.CollectionStore.isReadonly()
42+
};
4143
}
4244

4345
handleLoad() {

src/internal-packages/indexes/lib/store/load-indexes-store.js

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ const LoadIndexesStore = Reflux.createStore({
2929
*/
3030
loadIndexes: function() {
3131
if (NamespaceStore.ns) {
32-
if (this.CollectionStore.readonly) {
32+
if (this.CollectionStore.isReadonly()) {
3333
this.trigger([]);
3434
} else {
3535
app.dataService.indexes(NamespaceStore.ns, { readPreference: READ }, (err, indexes) => {

0 commit comments

Comments
 (0)