can_i 0.1
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.
- data/.gitignore +4 -0
- data/Gemfile +4 -0
- data/Gemfile.lock +12 -0
- data/README.md +80 -0
- data/Rakefile +14 -0
- data/app/app_delegate.rb +5 -0
- data/can_i.gemspec +19 -0
- data/lib/can_i.rb +9 -0
- data/lib/can_i/authorization.rb +61 -0
- data/lib/can_i/authorization_role.rb +38 -0
- data/lib/can_i/helper_method.rb +18 -0
- data/lib/can_i/version.rb +3 -0
- data/spec/authorization_roles_spec.rb +35 -0
- data/spec/helper_method_spec.rb +13 -0
- data/spec/helpers/helper_methods.rb +3 -0
- data/spec/main_spec.rb +32 -0
- metadata +85 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
data/README.md
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
# Can I?
|
2
|
+
Provides a simple DSL to define actions as roles in your [RubyMotion](http://www.rubymotion.com) app. Requires [BubbleWrap](https://github.com/rubymotion/BubbleWrap) as a dependency.
|
3
|
+
|
4
|
+
## Installation
|
5
|
+
|
6
|
+
Add the following to your project's `Rakefile` to work with bundler.
|
7
|
+
|
8
|
+
```ruby
|
9
|
+
gem "can_i"
|
10
|
+
```
|
11
|
+
|
12
|
+
Install with bundler:
|
13
|
+
|
14
|
+
```ruby
|
15
|
+
bundle install
|
16
|
+
```
|
17
|
+
|
18
|
+
## Using the Authorization class
|
19
|
+
I recommend you create an instance and store it in your application delegate.
|
20
|
+
|
21
|
+
```ruby
|
22
|
+
class AppDelegate
|
23
|
+
attr_accessor :authorization
|
24
|
+
def application(application, didFinishLaunchingWithOptions:launchOptions)
|
25
|
+
self.authorization = CanI::Authorization.new :admin
|
26
|
+
true
|
27
|
+
end
|
28
|
+
end
|
29
|
+
```
|
30
|
+
|
31
|
+
Now, wherever you want to request access:
|
32
|
+
|
33
|
+
```ruby
|
34
|
+
puts "can do that thing" if App.delegate.authorization.can? :perform_action
|
35
|
+
```
|
36
|
+
### Helper Methods
|
37
|
+
You'll be doing that so much, that there are included shortcut methods. This expects you to have an `CanI::Authorization` or subclass of, accessible at `App.delegate.authorization`.
|
38
|
+
|
39
|
+
You'll need to first include a module, like so:
|
40
|
+
|
41
|
+
```ruby
|
42
|
+
class SomeView < UIview
|
43
|
+
include CanI::HelperMethods
|
44
|
+
def initWithFrame(f)
|
45
|
+
super
|
46
|
+
self << my_custom_button if can? :can_push_button
|
47
|
+
self
|
48
|
+
end
|
49
|
+
end
|
50
|
+
```
|
51
|
+
|
52
|
+
## Custom Authorization Roles
|
53
|
+
You can easily create custom authorization roles to easily define sets of roles.
|
54
|
+
|
55
|
+
Let's create a base role that everyone will use in our app.
|
56
|
+
|
57
|
+
```ruby
|
58
|
+
class BaseRole < CanI::AuthorizationRole
|
59
|
+
authorization_roles do
|
60
|
+
can :view_help
|
61
|
+
end
|
62
|
+
end
|
63
|
+
```
|
64
|
+
|
65
|
+
Now, let's let admin users do something different:
|
66
|
+
|
67
|
+
```ruby
|
68
|
+
class AdminRole < BaseRole
|
69
|
+
authorization_roles do
|
70
|
+
cannot :view_help
|
71
|
+
can :fire_people
|
72
|
+
end
|
73
|
+
end
|
74
|
+
```
|
75
|
+
|
76
|
+
You associate a role with the authorization system when you create your authorization instance. Pass a symbol, which will have "Role" tacked on before looking up the class at runtime.
|
77
|
+
|
78
|
+
```ruby
|
79
|
+
App.delegate.authorization = CanI::Authorization.new :admin
|
80
|
+
```
|
data/Rakefile
ADDED
@@ -0,0 +1,14 @@
|
|
1
|
+
require "bundler/gem_tasks"
|
2
|
+
|
3
|
+
$:.unshift('/Library/RubyMotion/lib')
|
4
|
+
require 'motion/project'
|
5
|
+
require 'bundler'
|
6
|
+
|
7
|
+
Bundler.require
|
8
|
+
|
9
|
+
Dir[File.expand_path('../lib/**/*', __FILE__)].each { |f| require f }
|
10
|
+
|
11
|
+
Motion::Project::App.setup do |app|
|
12
|
+
# Use `rake config' to see complete project settings.
|
13
|
+
app.name = 'CanI'
|
14
|
+
end
|
data/app/app_delegate.rb
ADDED
data/can_i.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
require File.expand_path('../lib/can_i/version.rb', __FILE__)
|
2
|
+
|
3
|
+
Gem::Specification.new do |s|
|
4
|
+
s.name = 'can_i'
|
5
|
+
s.version = CanI::Version
|
6
|
+
s.authors = ["Matt Brewer"]
|
7
|
+
s.email = 'matt.brewer@me.com'
|
8
|
+
|
9
|
+
s.summary = "Provides an easy way to define roles for performing actions in your RubyMotion app."
|
10
|
+
s.description = "Provides an easy way to define roles for performing actions in your RubyMotion app."
|
11
|
+
|
12
|
+
s.homepage = "https://github.com/macfanatic/rubymotion_roles"
|
13
|
+
s.files = `git ls-files`.split($\)
|
14
|
+
s.test_files = s.files.grep(%r{^spec/})
|
15
|
+
s.require_paths = ['lib']
|
16
|
+
|
17
|
+
s.add_dependency "bubble-wrap"
|
18
|
+
|
19
|
+
end
|
data/lib/can_i.rb
ADDED
@@ -0,0 +1,9 @@
|
|
1
|
+
unless defined?(Motion::Project::Config)
|
2
|
+
raise "This file must be required within a RubyMotion project Rakefile."
|
3
|
+
end
|
4
|
+
|
5
|
+
Motion::Project::App.setup do |app|
|
6
|
+
Dir.glob(File.join(File.dirname(__FILE__), 'can_i/**/*.rb')).each do |file|
|
7
|
+
app.files.unshift(file)
|
8
|
+
end
|
9
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
module CanI
|
2
|
+
class Authorization
|
3
|
+
|
4
|
+
#
|
5
|
+
# This is the main class to interact with to determine if
|
6
|
+
# an action is permitted, or to define permissions
|
7
|
+
#
|
8
|
+
# Usage:
|
9
|
+
#
|
10
|
+
# class AppDelegate
|
11
|
+
# attr_accessor :authorization
|
12
|
+
# def application(application, didFinishLaunchingWithOptions:launchOptions)
|
13
|
+
# self.authorization = CanI::Authorization.new :admin
|
14
|
+
# true
|
15
|
+
# end
|
16
|
+
# end
|
17
|
+
#
|
18
|
+
# class MyController < UIViewController
|
19
|
+
# def viewDidLoad
|
20
|
+
# if App.delegate.authorization.can? :get_drunk
|
21
|
+
# App.alert "Let's get drunk!"
|
22
|
+
# else
|
23
|
+
# App.alert "I'm married"
|
24
|
+
# end
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
#
|
28
|
+
|
29
|
+
attr_reader :auth_role
|
30
|
+
|
31
|
+
def initialize(role=:authorization)
|
32
|
+
|
33
|
+
klass = CanI.const_defined?("#{role}_role".camelize) ? CanI.const_get("#{role}_role".camelize) : Kernel.const_get("#{role}_role".camelize)
|
34
|
+
|
35
|
+
@auth_role = klass.new
|
36
|
+
auth_role.class.registration_blocks.each do |more_roles|
|
37
|
+
instance_eval &more_roles
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def can(action)
|
42
|
+
approved_actions << action.to_sym unless approved_actions.include?(action.to_sym)
|
43
|
+
end
|
44
|
+
|
45
|
+
def can?(action)
|
46
|
+
approved_actions.include? action.to_sym
|
47
|
+
end
|
48
|
+
|
49
|
+
def cannot(action)
|
50
|
+
approved_actions.delete action.to_sym
|
51
|
+
end
|
52
|
+
|
53
|
+
|
54
|
+
private
|
55
|
+
|
56
|
+
def approved_actions
|
57
|
+
@approved_actions ||= []
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
61
|
+
end
|
@@ -0,0 +1,38 @@
|
|
1
|
+
module CanI
|
2
|
+
class AuthorizationRole
|
3
|
+
|
4
|
+
#
|
5
|
+
# Create your own subclass to use with the Authorization class
|
6
|
+
# You can define and undefine roles with a class method, as shown below
|
7
|
+
#
|
8
|
+
# Usage:
|
9
|
+
# class AdminRole < CanI::AuthorizationRole
|
10
|
+
# authorization_roles do
|
11
|
+
# can :fire_people
|
12
|
+
# cannot :sleep_in_cubicle
|
13
|
+
# end
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# @auth = CanI::Authorization.new :admin
|
17
|
+
# @auth.can? :fire_people
|
18
|
+
# => true
|
19
|
+
#
|
20
|
+
|
21
|
+
class << self
|
22
|
+
|
23
|
+
def authorization_roles(&block)
|
24
|
+
registration_blocks << block
|
25
|
+
end
|
26
|
+
|
27
|
+
def registration_blocks
|
28
|
+
@@registration_blocks ||= []
|
29
|
+
end
|
30
|
+
|
31
|
+
end
|
32
|
+
|
33
|
+
# use to define additional rules in your subclass
|
34
|
+
authorization_roles do
|
35
|
+
end
|
36
|
+
|
37
|
+
end
|
38
|
+
end
|
@@ -0,0 +1,18 @@
|
|
1
|
+
module CanI
|
2
|
+
module HelperMethods
|
3
|
+
|
4
|
+
def can(action)
|
5
|
+
App.delegate.authorization.can action
|
6
|
+
end
|
7
|
+
|
8
|
+
def cannot(action)
|
9
|
+
App.delegate.authorization.cannot action
|
10
|
+
end
|
11
|
+
|
12
|
+
def can?(action)
|
13
|
+
App.delegate.authorization.can? action
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
@@ -0,0 +1,35 @@
|
|
1
|
+
describe "auth roles" do
|
2
|
+
|
3
|
+
before do
|
4
|
+
@auth = CanI::Authorization.new
|
5
|
+
end
|
6
|
+
|
7
|
+
it "should have a default role" do
|
8
|
+
@auth.auth_role.should.be.instance_of CanI::AuthorizationRole
|
9
|
+
end
|
10
|
+
|
11
|
+
describe "custom auth roles" do
|
12
|
+
|
13
|
+
before do
|
14
|
+
|
15
|
+
class CustomRole < CanI::AuthorizationRole
|
16
|
+
authorization_roles do
|
17
|
+
can :my_role
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
@auth = CanI::Authorization.new :custom
|
22
|
+
|
23
|
+
end
|
24
|
+
|
25
|
+
it "should respect my custom auth role" do
|
26
|
+
@auth.auth_role.should.be.instance_of CustomRole
|
27
|
+
end
|
28
|
+
|
29
|
+
it "should allow custom roles to add definitions" do
|
30
|
+
@auth.can?(:my_role).should == true
|
31
|
+
end
|
32
|
+
|
33
|
+
end
|
34
|
+
|
35
|
+
end
|
@@ -0,0 +1,13 @@
|
|
1
|
+
describe "should provide helper methods to all objects" do
|
2
|
+
|
3
|
+
before do
|
4
|
+
@tester = HelperMethodsTestObject.new
|
5
|
+
end
|
6
|
+
|
7
|
+
it "should let me shortcut the DSL methods" do
|
8
|
+
@tester.should.respond_to :can
|
9
|
+
@tester.should.respond_to :cannot
|
10
|
+
@tester.should.respond_to :can?
|
11
|
+
end
|
12
|
+
|
13
|
+
end
|
data/spec/main_spec.rb
ADDED
@@ -0,0 +1,32 @@
|
|
1
|
+
describe "authorization functionality" do
|
2
|
+
|
3
|
+
before do
|
4
|
+
@auth = CanI::Authorization.new
|
5
|
+
end
|
6
|
+
|
7
|
+
it "should not allow duplicates" do
|
8
|
+
before_adding_new_role = @auth.send(:approved_actions).count
|
9
|
+
@auth.can :some_action
|
10
|
+
@auth.can :some_action
|
11
|
+
@auth.send(:approved_actions).count.should.equal (before_adding_new_role+1)
|
12
|
+
end
|
13
|
+
|
14
|
+
it "should allow you to define access rules" do
|
15
|
+
@auth.can?(:my_action).should == false
|
16
|
+
@auth.can :my_action
|
17
|
+
@auth.can?(:my_action).should == true
|
18
|
+
end
|
19
|
+
|
20
|
+
it "should allow strings or symbols" do
|
21
|
+
@auth.can(:some_action)
|
22
|
+
@auth.can?('some_action').should == true
|
23
|
+
@auth.can('my_action')
|
24
|
+
@auth.can?(:my_action).should == true
|
25
|
+
end
|
26
|
+
|
27
|
+
it "should allow you to remove access" do
|
28
|
+
@auth.cannot :some_action
|
29
|
+
@auth.can?(:some_action).should == false
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
metadata
ADDED
@@ -0,0 +1,85 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: can_i
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: '0.1'
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Matt Brewer
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-03-14 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bubble-wrap
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :runtime
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
30
|
+
description: Provides an easy way to define roles for performing actions in your RubyMotion
|
31
|
+
app.
|
32
|
+
email: matt.brewer@me.com
|
33
|
+
executables: []
|
34
|
+
extensions: []
|
35
|
+
extra_rdoc_files: []
|
36
|
+
files:
|
37
|
+
- .gitignore
|
38
|
+
- Gemfile
|
39
|
+
- Gemfile.lock
|
40
|
+
- README.md
|
41
|
+
- Rakefile
|
42
|
+
- app/app_delegate.rb
|
43
|
+
- can_i.gemspec
|
44
|
+
- lib/can_i.rb
|
45
|
+
- lib/can_i/authorization.rb
|
46
|
+
- lib/can_i/authorization_role.rb
|
47
|
+
- lib/can_i/helper_method.rb
|
48
|
+
- lib/can_i/version.rb
|
49
|
+
- spec/authorization_roles_spec.rb
|
50
|
+
- spec/helper_method_spec.rb
|
51
|
+
- spec/helpers/helper_methods.rb
|
52
|
+
- spec/main_spec.rb
|
53
|
+
homepage: https://github.com/macfanatic/rubymotion_roles
|
54
|
+
licenses: []
|
55
|
+
post_install_message:
|
56
|
+
rdoc_options: []
|
57
|
+
require_paths:
|
58
|
+
- lib
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
60
|
+
none: false
|
61
|
+
requirements:
|
62
|
+
- - ! '>='
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '0'
|
65
|
+
segments:
|
66
|
+
- 0
|
67
|
+
hash: 3259127327991234335
|
68
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
69
|
+
none: false
|
70
|
+
requirements:
|
71
|
+
- - ! '>='
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
74
|
+
requirements: []
|
75
|
+
rubyforge_project:
|
76
|
+
rubygems_version: 1.8.24
|
77
|
+
signing_key:
|
78
|
+
specification_version: 3
|
79
|
+
summary: Provides an easy way to define roles for performing actions in your RubyMotion
|
80
|
+
app.
|
81
|
+
test_files:
|
82
|
+
- spec/authorization_roles_spec.rb
|
83
|
+
- spec/helper_method_spec.rb
|
84
|
+
- spec/helpers/helper_methods.rb
|
85
|
+
- spec/main_spec.rb
|