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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0b50e72cd40d55893e6df819c563697cee1a9cbc
4
- data.tar.gz: 5b2132715da7cf3b472ec9e71877e6eaac0f74d6
3
+ metadata.gz: cb353f66be2c532cd4844fd2a692110de2102da3
4
+ data.tar.gz: 5fc8432f27dfbee0601990130d913cc686d308bf
5
5
  SHA512:
6
- metadata.gz: 3065baf79181f916f4a4f65b8b1f5fb6ab78e19b56b271d495d68c0fe800f55dbfcf7f0669ebfaac21542d6135b2749dc6a55c95f2d1ab618a731ccbf1f66c96
7
- data.tar.gz: 56671e12ef974a283796eab91c00f90d27d30f33ddf09cbe29caeeb2f484c94bb516a8f1c1862ce1d4cdd58dcba6bd29f5ab1aa7abe02f5c0c6a13cbba383116
6
+ metadata.gz: ffd2c7b597d75e062d91b66433daf438703e8591e103633c77e4cf77b430e1b070547e271ec8966c1600843df0f4f78ccd82a25aa7d63cd7da3c5e61047aa3a4
7
+ data.tar.gz: fd69fbe54505d932427cfbed1f0bc6978abe4e072de79d694580bd3df2f576ca7cfd4dc87702c08bf04580bc9fb29db49522158863d1785902b704fe3401912c
data/README.md CHANGED
@@ -1,6 +1,42 @@
1
1
  # Accession
2
2
 
3
- TODO: Write a gem description
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
- And then execute:
49
+ Use Bundler to install the dependency:
50
+
51
+ ```
52
+ bundle install
53
+ ```
54
+
55
+ ## Usage
14
56
 
15
- $ bundle
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
- Or install it yourself as:
60
+ The two major pieces of API provided by Accession are:
18
61
 
19
- $ gem install accession
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
- ## Usage
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
- TODO: Write usage instructions here
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
- 1. Fork it ( https://github.com/[my-github-username]/accession/fork )
28
- 2. Create your feature branch (`git checkout -b my-new-feature`)
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.
@@ -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
@@ -1,3 +1,3 @@
1
1
  module Accession
2
- VERSION = '0.0.2'
2
+ VERSION = '1.0.0'
3
3
  end
@@ -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.2
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: 2014-11-24 00:00:00.000000000 Z
11
+ date: 2015-01-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: bundler