accession 0.0.2 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +118 -12
- data/lib/accession/permission.rb +9 -0
- data/lib/accession/version.rb +1 -1
- data/spec/lib/accession/permission_spec.rb +16 -0
- metadata +2 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: cb353f66be2c532cd4844fd2a692110de2102da3
|
4
|
+
data.tar.gz: 5fc8432f27dfbee0601990130d913cc686d308bf
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ffd2c7b597d75e062d91b66433daf438703e8591e103633c77e4cf77b430e1b070547e271ec8966c1600843df0f4f78ccd82a25aa7d63cd7da3c5e61047aa3a4
|
7
|
+
data.tar.gz: fd69fbe54505d932427cfbed1f0bc6978abe4e072de79d694580bd3df2f576ca7cfd4dc87702c08bf04580bc9fb29db49522158863d1785902b704fe3401912c
|
data/README.md
CHANGED
@@ -1,6 +1,42 @@
|
|
1
1
|
# Accession
|
2
2
|
|
3
|
-
|
3
|
+
[![Gem Version][GV img]][Gem Version]
|
4
|
+
[![Build Status][BS img]][Build Status]
|
5
|
+
[![Dependency Status][DS img]][Dependency Status]
|
6
|
+
[![Code Climate][CC img]][Code Climate]
|
7
|
+
[![Coverage Status][CS img]][Coverage Status]
|
8
|
+
|
9
|
+
[Gem Version]: https://rubygems.org/gems/accession
|
10
|
+
[Build Status]: https://travis-ci.org/ausaccessfed/accession
|
11
|
+
[Dependency Status]: https://gemnasium.com/ausaccessfed/accession
|
12
|
+
[Code Climate]: https://codeclimate.com/github/ausaccessfed/accession
|
13
|
+
[Coverage Status]: https://coveralls.io/r/ausaccessfed/accession
|
14
|
+
|
15
|
+
[GV img]: https://img.shields.io/gem/v/accession.svg
|
16
|
+
[BS img]: https://img.shields.io/travis/ausaccessfed/accession/develop.svg
|
17
|
+
[DS img]: https://img.shields.io/gemnasium/ausaccessfed/accession.svg
|
18
|
+
[CC img]: https://img.shields.io/codeclimate/github/ausaccessfed/accession.svg
|
19
|
+
[CS img]: https://img.shields.io/coveralls/ausaccessfed/accession.svg
|
20
|
+
|
21
|
+
Extremely lightweight permissions for Ruby applications.
|
22
|
+
|
23
|
+
Author: Shaun Mangelsdorf
|
24
|
+
|
25
|
+
```
|
26
|
+
Copyright 2014-2015, Australian Access Federation
|
27
|
+
|
28
|
+
Licensed under the Apache License, Version 2.0 (the "License");
|
29
|
+
you may not use this file except in compliance with the License.
|
30
|
+
You may obtain a copy of the License at
|
31
|
+
|
32
|
+
http://www.apache.org/licenses/LICENSE-2.0
|
33
|
+
|
34
|
+
Unless required by applicable law or agreed to in writing, software
|
35
|
+
distributed under the License is distributed on an "AS IS" BASIS,
|
36
|
+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
37
|
+
See the License for the specific language governing permissions and
|
38
|
+
limitations under the License.
|
39
|
+
```
|
4
40
|
|
5
41
|
## Installation
|
6
42
|
|
@@ -10,22 +46,92 @@ Add this line to your application's Gemfile:
|
|
10
46
|
gem 'accession'
|
11
47
|
```
|
12
48
|
|
13
|
-
|
49
|
+
Use Bundler to install the dependency:
|
50
|
+
|
51
|
+
```
|
52
|
+
bundle install
|
53
|
+
```
|
54
|
+
|
55
|
+
## Usage
|
14
56
|
|
15
|
-
|
57
|
+
Accession is intended to be a lightweight and flexible way to add permissions to
|
58
|
+
your model classes. It imposes very few requirements on your application.
|
16
59
|
|
17
|
-
|
60
|
+
The two major pieces of API provided by Accession are:
|
18
61
|
|
19
|
-
|
62
|
+
* The `Accession::Principal` module, which consumes a list of permission strings
|
63
|
+
returned by the `permissions` method in a class and gives a `permits?` method
|
64
|
+
for performing a permission check.
|
65
|
+
* The `Accession::Permission.regexp` pattern, which can be used to validate an
|
66
|
+
Accession permission string.
|
20
67
|
|
21
|
-
|
68
|
+
To get started add a `permission` method to your class that represents an
|
69
|
+
authenticated user. This method returns permissions strings associated with that
|
70
|
+
user. Once you have this method, include the `Accession::Principal` module in
|
71
|
+
your class to add the `permits?` method.
|
72
|
+
|
73
|
+
An example implementation is:
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
# app/models/permission.rb
|
77
|
+
class Permission < ActiveRecord::Base
|
78
|
+
validates :value, format: Accession::Permission.regexp
|
79
|
+
end
|
80
|
+
|
81
|
+
# app/models/role.rb
|
82
|
+
class Role < ActiveRecord::Base
|
83
|
+
has_many :permissions
|
84
|
+
end
|
85
|
+
|
86
|
+
# app/models/subject.rb
|
87
|
+
class Subject < ActiveRecord::Base
|
88
|
+
include Accession::Principal
|
89
|
+
|
90
|
+
has_and_belongs_to_many :roles
|
91
|
+
|
92
|
+
def permissions
|
93
|
+
roles.flat_map { |role| role.permissions.map(&:value) }
|
94
|
+
end
|
95
|
+
end
|
96
|
+
```
|
97
|
+
|
98
|
+
With this in place, a `Subject` can have a permission check performed, for
|
99
|
+
example:
|
100
|
+
|
101
|
+
```ruby
|
102
|
+
class ProjectsController < ApplicationController
|
103
|
+
before_action { @subject = Subject.find(session[:subject_id]) }
|
104
|
+
|
105
|
+
def index
|
106
|
+
fail('Not allowed') unless @subject.permits?('projects:list')
|
107
|
+
end
|
108
|
+
end
|
109
|
+
```
|
110
|
+
|
111
|
+
## Permission Strings
|
112
|
+
|
113
|
+
A permission string is comprised of one or more colon-separated parts that
|
114
|
+
describe the action being permitted. Each part of the permission string can be
|
115
|
+
either a wildcard (`*`), or a "word" of characters `a-z A-Z 0-9 _ -`
|
116
|
+
|
117
|
+
A wildcard in any position will match a single word in that position. A wildcard
|
118
|
+
in the last position will match any number of words in the action string.
|
22
119
|
|
23
|
-
|
120
|
+
| permission | action | result |
|
121
|
+
|------------|---------|--------|
|
122
|
+
| `a` | `a` | permit |
|
123
|
+
| `a` | `b` | deny |
|
124
|
+
| `a:b:c` | `a:b:c` | permit |
|
125
|
+
| `a:b:c` | `a:b:d` | deny |
|
126
|
+
| `*:b:c` | `a:b:c` | permit |
|
127
|
+
| `a:b:*` | `a:b:c` | permit |
|
128
|
+
| `a:*` | `a:b:c` | permit |
|
129
|
+
| `*:c` | `a:b:c` | deny |
|
130
|
+
| `*` | `a:b:c` | permit |
|
131
|
+
| `a:b:*` | `a:b` | deny |
|
132
|
+
| `a:*:*` | `a:b` | deny |
|
24
133
|
|
25
134
|
## Contributing
|
26
135
|
|
27
|
-
|
28
|
-
|
29
|
-
3. Commit your changes (`git commit -am 'Add some feature'`)
|
30
|
-
4. Push to the branch (`git push origin my-new-feature`)
|
31
|
-
5. Create a new Pull Request
|
136
|
+
Refer to [GitHub Flow](https://guides.github.com/introduction/flow/) for
|
137
|
+
help contributing to this project.
|
data/lib/accession/permission.rb
CHANGED
@@ -1,5 +1,14 @@
|
|
1
1
|
module Accession
|
2
2
|
class Permission
|
3
|
+
# A segment is a "word" in the url-safe base64 alphabet, or single '*'
|
4
|
+
SEGMENT = /([\w-]+|\*)/.freeze
|
5
|
+
REGEXP = /\A(#{SEGMENT}:)*#{SEGMENT}\z/.freeze
|
6
|
+
private_constant :SEGMENT, :REGEXP
|
7
|
+
|
8
|
+
def self.regexp
|
9
|
+
REGEXP
|
10
|
+
end
|
11
|
+
|
3
12
|
def initialize(value)
|
4
13
|
@parts = value.split(':')
|
5
14
|
end
|
data/lib/accession/version.rb
CHANGED
@@ -58,5 +58,21 @@ module Accession
|
|
58
58
|
denies('a:b:c:e:d')
|
59
59
|
denies('a:b:d:c')
|
60
60
|
end
|
61
|
+
|
62
|
+
context '::regexp' do
|
63
|
+
subject { Accession::Permission.regexp }
|
64
|
+
|
65
|
+
it { is_expected.to match('*') }
|
66
|
+
it { is_expected.to match('a:b:c:d') }
|
67
|
+
it { is_expected.to match('a:b:c:*') }
|
68
|
+
it { is_expected.to match('a:b:*:d') }
|
69
|
+
it { is_expected.to match('word:word:word:__________') }
|
70
|
+
it { is_expected.to match('*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*:*') }
|
71
|
+
it { is_expected.not_to match('a:b:%') }
|
72
|
+
it { is_expected.not_to match('a:b:%:*') }
|
73
|
+
it { is_expected.not_to match('%') }
|
74
|
+
it { is_expected.not_to match('') }
|
75
|
+
it { is_expected.not_to match("*:*:*:*\n:*:*") }
|
76
|
+
end
|
61
77
|
end
|
62
78
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: accession
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.0
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Shaun Mangelsdorf
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date:
|
11
|
+
date: 2015-01-27 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: bundler
|