admission 0.4.5 → 0.4.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (47) hide show
  1. checksums.yaml +4 -4
  2. data/admission.gemspec +7 -7
  3. data/lib/admission/version.rb +1 -1
  4. metadata +5 -48
  5. data/.gitignore +0 -40
  6. data/.rspec +0 -2
  7. data/.ruby-version +0 -1
  8. data/Gemfile +0 -7
  9. data/LICENSE +0 -674
  10. data/README.md +0 -24
  11. data/bin/build +0 -10
  12. data/bin/rspec +0 -8
  13. data/spec/integration/action_arbitrating_spec.rb +0 -119
  14. data/spec/integration/resource_arbitrating_spec.rb +0 -276
  15. data/spec/rspec_config.rb +0 -103
  16. data/spec/spec_helper.rb +0 -28
  17. data/spec/test_context/country.rb +0 -24
  18. data/spec/test_context/index.rb +0 -5
  19. data/spec/test_context/person.rb +0 -31
  20. data/spec/test_context/persons_fixtures.rb +0 -43
  21. data/spec/test_context/privileges_and_rules.rb +0 -119
  22. data/spec/unit/arbitration_spec.rb +0 -33
  23. data/spec/unit/index_spec.rb +0 -144
  24. data/spec/unit/privilege/order_definer_spec.rb +0 -184
  25. data/spec/unit/privilege_spec.rb +0 -178
  26. data/spec/unit/rails/action_admission_spec.rb +0 -188
  27. data/spec/unit/rails/controller_addon_spec.rb +0 -68
  28. data/spec/unit/rails/scope_resolver_spec.rb +0 -72
  29. data/spec/unit/resource_arbitration_spec.rb +0 -76
  30. data/spec/unit/status_spec.rb +0 -79
  31. data/visualisation/.babelrc +0 -7
  32. data/visualisation/actions/index.js +0 -0
  33. data/visualisation/components/app_container.jsx +0 -78
  34. data/visualisation/components/input_with_select.jsx +0 -177
  35. data/visualisation/components/nested_list_row.jsx +0 -48
  36. data/visualisation/components/privilege_select.jsx +0 -70
  37. data/visualisation/components/privileges_panel.jsx +0 -73
  38. data/visualisation/components/rules_panel.jsx +0 -124
  39. data/visualisation/dist/.gitkeep +0 -0
  40. data/visualisation/helpers.js +0 -69
  41. data/visualisation/index.jsx +0 -89
  42. data/visualisation/package.json +0 -27
  43. data/visualisation/reducers/index.js +0 -35
  44. data/visualisation/server.rb +0 -23
  45. data/visualisation/style.scss +0 -248
  46. data/visualisation/webpack.config.js +0 -47
  47. data/visualisation/yarn.lock +0 -3354
@@ -1,76 +0,0 @@
1
- require_relative '../spec_helper'
2
-
3
- RSpec.describe Admission::ResourceArbitration do
4
-
5
- describe '#new' do
6
-
7
- it 'parses simple Symbol scope' do
8
- arbitration = Admission::ResourceArbitration.new nil, {scope: -1}, :req, :scope
9
- expect(arbitration).to have_inst_vars(
10
- person: nil,
11
- rules_index: -1,
12
- request: :req,
13
- resource: nil
14
- )
15
- end
16
-
17
- it 'parses type scope' do
18
- resource = Object.new
19
- arbitration = Admission::ResourceArbitration.new nil, {objects: -1}, :req, resource
20
- expect(arbitration).to have_inst_vars(
21
- person: nil,
22
- rules_index: -1,
23
- request: :req,
24
- resource: resource
25
- )
26
- end
27
-
28
- it 'parses nested type scope' do
29
- resource = Object.new
30
- arbitration = Admission::ResourceArbitration.new nil, {:'objects:vars' => -1}, :req, [resource, :vars]
31
- expect(arbitration).to have_inst_vars(
32
- person: nil,
33
- rules_index: -1,
34
- request: :req,
35
- resource: resource
36
- )
37
- end
38
-
39
- end
40
-
41
- describe 'RulesBuilder' do
42
-
43
- describe 'fails when given reserved action name' do
44
-
45
- let(:builder){
46
- builder = Admission::ResourceArbitration::RulesBuilder.new nil
47
- builder.instance_variable_set '@privilege', 'privilege'
48
- builder
49
- }
50
-
51
- it '#allow' do
52
- expect{ builder.allow '', :allow }.not_to raise_exception
53
- expect{ builder.allow '', Admission::ALL_ACTION }.to(
54
- raise_exception("reserved action name #{Admission::ALL_ACTION}")
55
- )
56
- end
57
-
58
- it '#forbid' do
59
- expect{ builder.forbid '', :forbid }.not_to raise_exception
60
- expect{ builder.forbid '', Admission::ALL_ACTION }.to(
61
- raise_exception("reserved action name #{Admission::ALL_ACTION}")
62
- )
63
- end
64
-
65
- it '#allow_resource' do
66
- expect{ builder.allow_resource :'', :allow_resource, &->{} }.not_to raise_exception
67
- expect{ builder.allow_resource :'', Admission::ALL_ACTION, &->{} }.to(
68
- raise_exception("reserved action name #{Admission::ALL_ACTION}")
69
- )
70
- end
71
-
72
- end
73
-
74
- end
75
-
76
- end
@@ -1,79 +0,0 @@
1
- require_relative '../spec_helper'
2
-
3
- RSpec.describe Admission::Status do
4
-
5
- def privilege context
6
- @fake_privilege_klass ||= Struct.new(:context, :inherited)
7
- @fake_privilege_klass.new context
8
- end
9
-
10
- describe '#new' do
11
-
12
- it 'sets privileges to nil' do
13
- instance = Admission::Status.new :person, nil, :rules, :arbiter
14
- expect(instance).to have_inst_vars(
15
- person: :person,
16
- privileges: nil,
17
- rules: :rules,
18
- arbiter: :arbiter
19
- )
20
-
21
- instance = Admission::Status.new :person, [], :rules, :arbiter
22
- expect(instance).to have_inst_vars(
23
- person: :person,
24
- privileges: nil,
25
- rules: :rules,
26
- arbiter: :arbiter
27
- )
28
- end
29
-
30
- it 'sets privileges and freezes them' do
31
- instance = Admission::Status.new :person, [:czech], :rules, :arbiter
32
- expect(instance).to have_inst_vars(
33
- person: :person,
34
- privileges: [:czech],
35
- rules: :rules,
36
- arbiter: :arbiter
37
- )
38
- expect(instance.privileges).to be_frozen
39
- end
40
-
41
- it 'sorts privileges by context' do
42
- instance = Admission::Status.new :person, [
43
- privilege(nil),
44
- privilege(:czech),
45
- privilege(15),
46
- privilege(:czech),
47
- privilege({a: 15}),
48
- privilege({a: {f: 1}}),
49
- privilege(nil),
50
- privilege({a: 15}),
51
- ], :rules, :arbiter
52
- expect(instance.privileges.map(&:context)).to eq([
53
- nil, nil, :czech, :czech, 15, {:a=>15}, {:a=>15}, {:a=>{:f=>1}}
54
- ])
55
- expect(instance.privileges).to be_frozen
56
- end
57
-
58
- end
59
-
60
- describe '#allowed_in_contexts' do
61
-
62
- it 'returns empty list for blank privileges' do
63
- instance = Admission::Status.new :person, nil, :rules, :arbiter
64
- expect(instance.allowed_in_contexts).to eq([])
65
- end
66
-
67
- it 'lists only context for which any privilege allows it' do
68
- priv1 = privilege text: '1'
69
- priv2 = privilege text: '2'
70
- rules = {can: {priv1 => true}}
71
- instance = Admission::Status.new nil, [priv1, priv2], rules, Admission::Arbitration
72
-
73
- list = instance.allowed_in_contexts :can
74
- expect(list).to eq([priv1.context])
75
- end
76
-
77
- end
78
-
79
- end
@@ -1,7 +0,0 @@
1
- {
2
- // "sourceMaps": true,
3
- "presets": ["es2015"],
4
- "plugins": [
5
- ["transform-react-jsx", { "pragma": "preact.h" }]
6
- ]
7
- }
File without changes
@@ -1,78 +0,0 @@
1
- import preact from 'preact';
2
- import classnames from 'classnames';
3
-
4
- import PrivilegesPanel from './privileges_panel';
5
- import RulesPanel from "./rules_panel";
6
-
7
- export default class AppContainer extends preact.Component {
8
-
9
- constructor (props) {
10
- super(props);
11
-
12
- this.switchToPrivileges = this.changePanel.bind(this, 'privileges');
13
- this.switchToRules = this.changePanel.bind(this, 'rules');
14
- }
15
-
16
- render ({app}, {loaded, load_fail, panel}) {
17
- if (!loaded) return <div className="splash-message">
18
- <code>... loading admission data ...</code>
19
- </div>;
20
-
21
- if (load_fail) return <div className="splash-message">
22
- <h4>failed to load admission data</h4>
23
- <code>{load_fail}</code>
24
- </div>;
25
-
26
- return <div className="admission-app-container">
27
- <ul className="panels-list">
28
-
29
- <li
30
- onClick={this.switchToPrivileges}
31
- className={classnames({'active': panel === 'privileges'})}>
32
- Privileges Order
33
- </li>
34
-
35
- <li
36
- onClick={this.switchToRules}
37
- className={classnames({'active': panel === 'rules'})}>
38
- Rules Listing
39
- </li>
40
-
41
- </ul>
42
-
43
- {this.renderPanel()}
44
- </div>;
45
- }
46
-
47
- componentDidMount () {
48
- const store = this.props.app.store;
49
-
50
- this.store_unsibscribe = store.subscribe(() => {
51
- const state = store.getState();
52
- this.setState({loaded: state.loaded, panel: state.panel});
53
- });
54
-
55
- setTimeout(this.props.onMounted, 0);
56
- }
57
-
58
- componentWillUnmount () {
59
- this.store_unsibscribe();
60
- }
61
-
62
- changePanel(panel) {
63
- this.props.app.store.dispatch({type: 'PANEL_CHANGE', panel: panel});
64
- }
65
-
66
- renderPanel () {
67
- const app = this.props.app;
68
- switch (this.state.panel) {
69
- case 'privileges':
70
- return <PrivilegesPanel app={app} />;
71
- break;
72
-
73
- case 'rules':
74
- return <RulesPanel app={app}/>;
75
- break;
76
- }
77
- }
78
- }
@@ -1,177 +0,0 @@
1
- import preact from 'preact';
2
- import classnames from 'classnames';
3
- import helpers from '../helpers';
4
-
5
- export default class InputWithSelect extends preact.Component {
6
-
7
- constructor (props) {
8
- super(props);
9
-
10
- this.state = {
11
- text: props.defaultText || '',
12
- matching: null,
13
- };
14
-
15
- this.setParentRef = ref => this.element = ref;
16
- this.setListRef = ref => this.list = ref;
17
- this.onKeyDown = this.onKeyDown.bind(this);
18
- this.onTextChange = helpers.debounce(this.onTextChange.bind(this), 400);
19
- this.toggleList = helpers.debounce(this.toggleList.bind(this), 400, true);
20
- this.closeList = this.closeList.bind(this);
21
- this.onSelected = this.onSelected.bind(this);
22
- }
23
-
24
- render ({placeholder}, {text, matching}) {
25
- if (!matching) this.list = null;
26
-
27
- return <div
28
- ref={this.setParentRef}
29
- className="select_box">
30
-
31
- <div className="_inputs">
32
- <input
33
- type="text"
34
- className="input_text"
35
- placeholder={placeholder}
36
- onKeyDown={this.onKeyDown}
37
- value={text}/>
38
-
39
- <button
40
- type="button"
41
- tabIndex="-1"
42
- className="button"
43
- onClick={this.toggleList}>
44
- &#8964;
45
- </button>
46
- </div>
47
-
48
- {matching && <DropdownList
49
- ref={this.setListRef}
50
- items={matching}
51
- toSelect={this.onSelected}
52
- toClose={this.closeList}
53
- />}
54
-
55
- </div>;
56
- }
57
-
58
- componentDidMount () {
59
- this._outside_click_listener = e => {
60
- if (!this.element.contains(e.target) && this.list) {
61
- this.closeList();
62
- }
63
- };
64
- document.addEventListener('click', this._outside_click_listener);
65
- }
66
-
67
- componentWillUnmount () {
68
- document.removeEventListener('click', this._outside_click_listener);
69
- }
70
-
71
- componentWillReceiveProps (new_props) {
72
- if (new_props.defaultText !== this.props.defaultText) this.setState({text: new_props.defaultText});
73
- }
74
-
75
- onKeyDown (e) {
76
- if (this.list && this.list.onKeyDown(e)) return;
77
- if (e.keyCode === 13 && this.props.enterable) {
78
- this.onSelected(e.target.value.trim());
79
- return;
80
- }
81
- this.onTextChange(e);
82
- }
83
-
84
- onTextChange (e) {
85
- const text = e.target.value.trim();
86
- let matching = null;
87
- if ((text && text !==this.state.text) || e.keyCode === 40) {
88
- matching = this.filtered_items(text);
89
- }
90
- this.setState({matching, text});
91
- }
92
-
93
- toggleList () {
94
- if (this.list) {
95
- this.closeList();
96
-
97
- } else {
98
- this.setState({matching: this.filtered_items()});
99
- }
100
- }
101
-
102
- closeList () {
103
- this.setState({matching: null});
104
- }
105
-
106
- onSelected (value) {
107
- this.setState({text: value, matching: null});
108
- this.props.onSelect(value);
109
- }
110
-
111
- filtered_items (text) {
112
- let items = this.props.all_items;
113
- if (text) items = items.filter(value => value.startsWith(text));
114
- if (this.props.nullable) items.unshift(null);
115
-
116
- return items.length === 0 ? null : items;
117
- }
118
-
119
- }
120
-
121
- class DropdownList extends preact.Component {
122
-
123
- constructor (props) {
124
- super(props);
125
- this.state = {selected: -1};
126
- }
127
-
128
- render ({items, toSelect}, {selected}) {
129
- return <div
130
- className="_dropdown">
131
- <ul>
132
- {items.map((name, i) => <li
133
- className={classnames({'selected': selected === i})}
134
- onClick={() => toSelect(name)}>
135
- {name === null ? '\u00A0' : name}
136
- </li>)}
137
- </ul>
138
- </div>;
139
- }
140
-
141
- onKeyDown (e) {
142
- switch (e.keyCode) {
143
- case 40: // down
144
- this.changeSelection(1);
145
- return true;
146
- break;
147
-
148
- case 38: // up
149
- this.changeSelection(-1);
150
- return true;
151
- break;
152
-
153
- case 13: // enter
154
- const selected = this.state.selected;
155
- if (selected !== -1) {
156
- this.props.toSelect(this.props.items[selected]);
157
- return true;
158
- }
159
- break;
160
-
161
- case 27: // escape
162
- this.props.toClose();
163
- return true;
164
- break;
165
-
166
- }
167
- return false;
168
- }
169
-
170
- changeSelection (value) {
171
- let selected = this.state.selected;
172
- selected += value;
173
- if (selected < 0) selected = 0;
174
- if (selected >= this.props.items.length) selected = this.props.items.length -1;
175
- this.setState({selected});
176
- }
177
- }
@@ -1,48 +0,0 @@
1
- import preact from 'preact';
2
-
3
- export default class NestedListRow extends preact.Component {
4
-
5
- constructor (props) {
6
- super(props);
7
-
8
- this.state = {
9
- unrolled: !!props.defaultUnrolled
10
- };
11
-
12
- this.toggleRollOut = this.toggleRollOut.bind(this);
13
- }
14
-
15
- render ({app, content, nestedRows}, {unrolled}) {
16
- return <li>
17
- <div onClick={this.toggleRollOut} className="nested-list-content">
18
- {nestedRows && <span className="icon">
19
- {unrolled ? '\u25B6' : '\u25BC'}
20
- </span>
21
- }
22
- <span className="content">{content}</span>
23
- </div>
24
- {unrolled && nestedRows && <ul className="nested-list">{
25
- nestedRows.map(row =>
26
- <NestedListRow
27
- app={app}
28
- content={row.content}
29
- nestedRows={row.nested_rows}
30
- defaultUnrolled={this.props.defaultUnrolled}
31
- />
32
- )
33
- }</ul>}
34
- </li>;
35
- }
36
-
37
- componentWillReceiveProps ({defaultUnrolled}) {
38
- if (defaultUnrolled !== this.props.defaultUnrolled) {
39
- this.setState({unrolled: !!defaultUnrolled});
40
- }
41
- }
42
-
43
- toggleRollOut () {
44
- this.setState({unrolled: !this.state.unrolled});
45
- }
46
-
47
- }
48
-