1
- Shuttler . SelectorFunctionSchema = new SimpleSchema ( {
1
+ Shuttler . SelectorSelectAllowSchema = new SimpleSchema ( {
2
2
field : {
3
3
type : String ,
4
4
allowedValues : [ "source" , "target" ]
@@ -15,6 +15,12 @@ Shuttler.SelectorFunctionSchema = new SimpleSchema({
15
15
}
16
16
}
17
17
} ) ;
18
+ Shuttler . SelectorSelectDenySchema = new SimpleSchema ( {
19
+ field : {
20
+ type : String ,
21
+ allowedValues : [ "source" , "target" ]
22
+ }
23
+ } ) ;
18
24
Shuttler . SelectedDocumentSchema = new SimpleSchema ( {
19
25
from : {
20
26
type : Shuttler . Ref . Schema ,
@@ -61,9 +67,67 @@ Mongo.Collection.prototype.attachSelect = function() {
61
67
this . select = { }
62
68
63
69
this . select . _allowed = [ ] ;
70
+ this . select . _allowedField = { source : false , target : false } ;
71
+
72
+ var generateShortNamesSelectAllow = function ( selector ) {
73
+ return {
74
+ So : selector . field , // selected changes field
75
+ Ta : selector . field == 'source' ?'target' :'source' , // target of selection
76
+ Fr : selector . from , // path from
77
+ To : selector . to // path to
78
+ } ;
79
+ } ;
80
+
81
+ var isipv = {
82
+ fromLink : function ( short , paths , selected , path ) {
83
+ insertSelectedIntoPathCore ( short , paths , selected , path , path [ '_' + short . To ] , path . Ref ( ) , selected . _id ) ;
84
+ } ,
85
+ toLink : function ( short , paths , selected , path ) {
86
+ insertSelectedIntoPathCore ( short , paths , selected , path , path . Ref ( ) , path [ '_' + short . Fr ] , selected . _id ) ;
87
+ } ,
88
+ else : function ( short , paths , selected , path ) {
89
+ insertSelectedIntoPathCore ( short , paths , selected , path , path [ '_' + short . To ] , path [ '_' + short . Fr ] , selected . _id ) ;
90
+ }
91
+ } ;
92
+
93
+ // from -> to
94
+ var insertSelectedIntoPathVariantsHash = {
95
+ 'link' : { 'source' : isipv . fromLink , 'target' : isipv . fromLink } ,
96
+ 'source' : { 'target' : isipv . else , 'link' : isipv . toLink } ,
97
+ 'target' : { 'source' : isipv . else , 'link' : isipv . toLink } ,
98
+ } ;
99
+
100
+ var insertSelectedIntoPathCore = function ( short , paths , selected , path , so , from , prev ) {
101
+ for ( var d in collection . select . _denied ) {
102
+ if ( collection . select . _denied [ d ] . find ( {
103
+ $or : [
104
+ { '_source.id' : so . id , '_source.collection' : so . collection } ,
105
+ { '_target.id' : so . id , '_target.collection' : so . collection }
106
+ ]
107
+ } ) . count ( ) ) return undefined ;
108
+ }
109
+ if ( ! collection . find ( {
110
+ [ '_' + short . Ta + '.id' ] : selected [ '_' + short . Ta ] . id , [ '_' + short . Ta + '.collection' ] : selected [ '_' + short . Ta ] . collection ,
111
+ [ '_' + short . So + '.id' ] : so . id , [ '_' + short . So + '.collection' ] : so . collection ,
112
+ '_selected.path.id' : path ?path . _id :undefined , '_selected.path.collection' : path ?paths . _name :undefined ,
113
+ '_selected.from.id' : from ?from . id :undefined , '_selected.from.collection' : from ?from . collection :undefined ,
114
+ '_selected.prev' : prev ?prev :undefined ,
115
+ '_selected.root' : selected . root ( )
116
+ } ) . count ( ) ) {
117
+ collection . insert ( {
118
+ [ '_' + short . Ta ] : selected [ '_' + short . Ta ] , [ '_' + short . So ] : so ,
119
+ '_selected' : {
120
+ path : path ?path . Ref ( ) :undefined ,
121
+ from : from ?from :undefined ,
122
+ prev : prev ?prev :undefined ,
123
+ root : selected . root ( )
124
+ }
125
+ } ) ;
126
+ }
127
+ } ;
64
128
65
129
this . select . allow = function ( graph , selector ) {
66
- var context = Shuttler . SelectorFunctionSchema . newContext ( ) ;
130
+ var context = Shuttler . SelectorSelectAllowSchema . newContext ( ) ;
67
131
if ( ! context . validate ( selector ) ) {
68
132
throw new Meteor . Error ( context . keyErrorMessage ( context . invalidKeys ( ) [ 0 ] . name ) ) ;
69
133
}
@@ -73,46 +137,12 @@ Mongo.Collection.prototype.attachSelect = function() {
73
137
var selects = collection ;
74
138
75
139
collection . select . _allowed . push ( { graph : graph , selector : selector } ) ;
140
+ collection . select . _allowedField [ selector . field ] = true ;
76
141
77
- var So = selector . field ; // selected changes field
78
- var Ta = selector . field == 'source' ?'target' :'source' ; // target of selection
79
- var Fr = selector . from ; // path from
80
- var To = selector . to ; // path to
81
-
82
- var insertSelectedIntoPathCore = function ( selected , path , so , from , prev ) {
83
- if ( ! selects . find ( {
84
- [ '_' + Ta + '.id' ] : selected [ '_' + Ta ] . id , [ '_' + Ta + '.collection' ] : selected [ '_' + Ta ] . collection ,
85
- [ '_' + So + '.id' ] : so . id , [ '_' + So + '.collection' ] : so . collection ,
86
- '_selected.path.id' : path ?path . _id :undefined , '_selected.path.collection' : path ?paths . _name :undefined ,
87
- '_selected.from.id' : from ?from . id :undefined , '_selected.from.collection' : from ?from . collection :undefined ,
88
- '_selected.prev' : prev ?prev :undefined ,
89
- '_selected.root' : selected . root ( )
90
- } ) . count ( ) ) {
91
- selects . insert ( {
92
- [ '_' + Ta ] : selected [ '_' + Ta ] , [ '_' + So ] : so ,
93
- '_selected' : {
94
- path : path ?path . Ref ( ) :undefined ,
95
- from : from ?from :undefined ,
96
- prev : prev ?prev :undefined ,
97
- root : selected . root ( )
98
- }
99
- } ) ;
100
- }
101
- } ;
142
+ var short = generateShortNamesSelectAllow ( selector ) ;
143
+ let { So, Ta, Fr, To } = short ;
102
144
103
- if ( Fr == 'link' ) {
104
- var insertSelectedIntoPath = function ( selected , path ) {
105
- insertSelectedIntoPathCore ( selected , path , path [ '_' + To ] , path . Ref ( ) , selected . _id ) ;
106
- } ;
107
- } else if ( To == 'link' ) {
108
- var insertSelectedIntoPath = function ( selected , path ) {
109
- insertSelectedIntoPathCore ( selected , path , path . Ref ( ) , path [ '_' + Fr ] , selected . _id ) ;
110
- } ;
111
- } else {
112
- var insertSelectedIntoPath = function ( selected , path ) {
113
- insertSelectedIntoPathCore ( selected , path , path [ '_' + To ] , path [ '_' + Fr ] , selected . _id ) ;
114
- } ;
115
- }
145
+ var insertSelectedIntoPath = insertSelectedIntoPathVariantsHash [ Fr ] [ To ] ;
116
146
117
147
if ( Fr == 'link' ) {
118
148
var findEachPaths = function ( selected , handler ) {
@@ -139,10 +169,10 @@ Mongo.Collection.prototype.attachSelect = function() {
139
169
selects . after . link [ So ] ( function ( userId , selected , fieldNames , modifier , options ) {
140
170
var selected = selects . _transform ( selected ) ;
141
171
if ( selected . root ( ) == selected . _id ) {
142
- insertSelectedIntoPathCore ( selected , undefined , selected [ '_' + So ] , undefined , undefined ) ;
172
+ insertSelectedIntoPathCore ( short , paths , selected , undefined , selected [ '_' + So ] , undefined , undefined ) ;
143
173
} else {
144
174
findEachPaths ( selected , function ( path ) {
145
- insertSelectedIntoPath ( selected , path ) ;
175
+ insertSelectedIntoPath ( short , paths , selected , path ) ;
146
176
} ) ;
147
177
}
148
178
} ) ;
@@ -191,8 +221,89 @@ Mongo.Collection.prototype.attachSelect = function() {
191
221
paths . after . link ( function ( userId , path , fieldNames , modifier , options ) {
192
222
var path = paths . _transform ( path ) ;
193
223
findEachSelected ( path , function ( selected ) {
194
- insertSelectedIntoPath ( selected , path ) ;
224
+ insertSelectedIntoPath ( short , paths , selected , path ) ;
195
225
} ) ;
196
226
} ) ;
197
227
} ;
228
+
229
+ this . select . _denied = [ ] ;
230
+
231
+ var generateShortNamesSelectDeny = function ( selector ) {
232
+ return {
233
+ So : selector . field , // selected changes field
234
+ Ta : selector . field == 'source' ?'target' :'source' // target of selection
235
+ } ;
236
+ } ;
237
+
238
+ this . select . deny = function ( graph , selector ) {
239
+ var context = Shuttler . SelectorSelectDenySchema . newContext ( ) ;
240
+ if ( ! context . validate ( selector ) ) {
241
+ throw new Meteor . Error ( context . keyErrorMessage ( context . invalidKeys ( ) [ 0 ] . name ) ) ;
242
+ }
243
+
244
+ if ( ! ( graph instanceof Mongo . Collection ) ) throw new Meteor . Error ( 'Graph must be a Mongo.Collection' ) ;
245
+ collection . select . _denied . push ( graph ) ;
246
+
247
+ var dShort = generateShortNamesSelectDeny ( selector ) ;
248
+
249
+ var deny = graph ;
250
+ var allow = collection ;
251
+
252
+ deny . after . unlink [ dShort . So ] ( function ( userId , denied , fieldNames , modifier , options ) {
253
+ var denied = deny . _transform ( denied ) ;
254
+
255
+ lodash . each ( collection . select . _allowed , function ( _a ) {
256
+ var _aShort = generateShortNamesSelectAllow ( _a . selector ) ;
257
+
258
+ if ( _aShort . To == 'link' ) {
259
+ _a . graph . find ( {
260
+ _id : denied [ '_' + dShort . So ] . id
261
+ } ) . forEach ( function ( path ) {
262
+ allow . links . find [ _aShort . So ] ( path [ '_' + _aShort . Fr ] , { '_selected' : { $exists : true } } ) . forEach ( function ( a ) {
263
+ insertSelectedIntoPathVariantsHash [ _aShort . Fr ] [ _aShort . To ] ( _aShort , _a . graph , a , path ) ;
264
+ } ) ;
265
+ } ) ;
266
+ } else {
267
+ _a . graph . find ( {
268
+ [ '_' + _aShort . To + '.id' ] : denied [ '_' + dShort . So ] . id ,
269
+ [ '_' + _aShort . To + '.collection' ] : denied [ '_' + dShort . So ] . collection
270
+ } ) . forEach ( function ( path ) {
271
+ if ( _aShort . Fr == 'link' ) {
272
+ allow . links . find [ _aShort . So ] ( path , { '_selected' : { $exists : true } } ) . forEach ( function ( a ) {
273
+ insertSelectedIntoPathVariantsHash [ _aShort . Fr ] [ _aShort . To ] ( _aShort , _a . graph , a , path ) ;
274
+ } ) ;
275
+ } else {
276
+ allow . links . find [ _aShort . So ] ( path [ '_' + _aShort . Fr ] , { '_selected' : { $exists : true } } ) . forEach ( function ( a ) {
277
+ insertSelectedIntoPathVariantsHash [ _aShort . Fr ] [ _aShort . To ] ( _aShort , _a . graph , a , path ) ;
278
+ } ) ;
279
+ }
280
+ } ) ;
281
+ }
282
+
283
+
284
+ allow . links . find [ _aShort . So ] ( denied [ '_' + dShort . So ] , { '_selected' : { $exists : false } } ) . forEach ( function ( allowed ) {
285
+ insertSelectedIntoPathCore ( _aShort , _a . graph , allowed , undefined , allowed [ '_' + _aShort . So ] , undefined , undefined ) ;
286
+ } ) ;
287
+ } ) ;
288
+ } ) ;
289
+
290
+ deny . after . link [ dShort . So ] ( function ( userId , denied , fieldNames , modifier , options ) {
291
+ var denied = deny . _transform ( denied ) ;
292
+
293
+ if ( collection . select . _allowedField . source ) {
294
+ allow . remove ( {
295
+ '_selected' : { $exists : true } ,
296
+ [ '_source.id' ] : denied [ '_' + dShort . So ] . id ,
297
+ [ '_source.collection' ] : denied [ '_' + dShort . So ] . collection
298
+ } ) ;
299
+ }
300
+ if ( collection . select . _allowedField . target ) {
301
+ allow . remove ( {
302
+ '_selected' : { $exists : true } ,
303
+ [ '_target.id' ] : denied [ '_' + dShort . So ] . id ,
304
+ [ '_target.collection' ] : denied [ '_' + dShort . So ] . collection
305
+ } ) ;
306
+ }
307
+ } ) ;
308
+ }
198
309
} ;
0 commit comments