accession 0.0.2 → 1.0.0

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.
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