wooster 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA1:
3
+ metadata.gz: c67594f1e124e91d4bf4e27d11752497a43008cc
4
+ data.tar.gz: 3a61548556af1d4125a650cd8e1f75ee524d8530
5
+ SHA512:
6
+ metadata.gz: 2ebac097166bb9d7ce21391b55718365855d25380b055a97087ceacb4eb171b22c42cf26fcd208492910e4950dfeec8c6291a4af084502087152cafe4e509631
7
+ data.tar.gz: fd36e781d61745bfb19f7a4832d997f02659474416580543bcd9cd4e12fd936938ee1c6667100e6c4d72391aaf4847ceb6bdd42560edcfb4e155500f9a40e7b7
@@ -0,0 +1,15 @@
1
+ /.bundle/
2
+ /.yardoc
3
+ /Gemfile.lock
4
+ /_yardoc/
5
+ /coverage/
6
+ /doc/
7
+ /pkg/
8
+ /spec/reports/
9
+ /tmp/
10
+ *.bundle
11
+ *.so
12
+ *.o
13
+ *.a
14
+ mkmf.log
15
+ *.gem
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in wooster.gemspec
4
+ gemspec
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2014 Julian Bangert, Alexander J. Lin, Julia Huang
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
@@ -0,0 +1,31 @@
1
+ # Wooster
2
+
3
+ TODO: Write a gem description
4
+
5
+ ## Installation
6
+
7
+ Add this line to your application's Gemfile:
8
+
9
+ ```ruby
10
+ gem 'wooster'
11
+ ```
12
+
13
+ And then execute:
14
+
15
+ $ bundle
16
+
17
+ Or install it yourself as:
18
+
19
+ $ gem install wooster
20
+
21
+ ## Usage
22
+
23
+ TODO: Write usage instructions here
24
+
25
+ ## Contributing
26
+
27
+ 1. Fork it ( https://github.com/[my-github-username]/wooster/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
@@ -0,0 +1,2 @@
1
+ require "bundler/gem_tasks"
2
+
@@ -0,0 +1,4 @@
1
+ require 'wooster/version'
2
+ require 'wooster/base'
3
+ require 'wooster/policy_builder'
4
+
@@ -0,0 +1,117 @@
1
+ module Wooster
2
+ RecordPermissions = Struct.new(:read,:write,:create,:delete)
3
+ FieldPermissions = Struct.new(:read, :write)
4
+ def self.init_policy(klass)
5
+ if klass.class_variable_defined? :@@wooster_field
6
+ raise RuntimeError
7
+ end
8
+ klass.cattr_accessor :wooster_records
9
+ klass.cattr_accessor :wooster_field
10
+ x = Hash.new
11
+ x.default_proc = Proc.new do |hash, key|
12
+ hash[key] = FieldPermissions.new([],[])
13
+ end
14
+ klass.wooster_records = RecordPermissions.new([],[],[],[])
15
+ klass.wooster_field = x
16
+ end
17
+
18
+ def self.controller_exec(block, *args)
19
+ Thread.current[:wooster_controller].instance_exec *args,&block
20
+ end
21
+ def self.any_permission?(permissions, object)
22
+ permissions.any?{|func| Wooster.controller_exec(func,object)}
23
+ end
24
+
25
+ class InvalidFieldWriteError < RuntimeError
26
+ end
27
+ class InvalidCreateError < RuntimeError
28
+ end
29
+ class InvalidUpdateError < RuntimeError
30
+ end
31
+ class InvalidDeleteError < RuntimeError
32
+ end
33
+ end
34
+ ActiveRecord::Base.class_eval do
35
+
36
+ class << self
37
+ alias_method :old_inherited, :inherited
38
+ def inherited(subclass)
39
+ Wooster::init_policy(subclass)
40
+ old_inherited(subclass)
41
+ end
42
+ end
43
+ alias_method :old_bracket, :[]
44
+
45
+ def [](key)
46
+ self.send key
47
+ end
48
+ end
49
+
50
+ ActionController::Base.class_eval do
51
+ around_filter :wooster_wrap
52
+ def wooster_wrap
53
+ Thread.current[:wooster_controller] = self
54
+ begin
55
+ yield
56
+ ensure
57
+ Thread.current[:wooster_controller] = nil
58
+ end
59
+ end
60
+ end
61
+ ActiveModel::AttributeMethods::ClassMethods.class_eval do
62
+ alias_method :define_attribute_methods_old, :define_attribute_methods
63
+
64
+ def define_attribute_methods(*attrs)
65
+ define_attribute_methods_old(*attrs)
66
+
67
+ after_find do
68
+ new_attr = Hash[]
69
+ attributes.each {|k,v|
70
+ #if all rules return false and more than one rule returns false -> reject
71
+ succ = true
72
+ default = nil
73
+ self.class.wooster_field[k].read.each{|func|
74
+ succ, value = Wooster.controller_exec(func,self)
75
+ default ||= value
76
+ if(succ)
77
+ break
78
+ end
79
+ }
80
+ if(!succ)
81
+ new_attr[k] = default || self.class.column_defaults[k.to_s]
82
+ end
83
+ }
84
+ attributes.merge! new_attr
85
+ end
86
+ before_create do
87
+ unless Wooster.any_permission?(self.class.wooster_records.create,self)
88
+ raise InvalidCreateError
89
+ end
90
+ end
91
+ before_update do
92
+ unless Wooster.any_permission?(self.class.wooster_records.update,self)
93
+ raise InvalidCreateError
94
+ end
95
+ end
96
+ before_destroy do
97
+ ## XXXX: Hook destroy?
98
+ unless Wooster.any_permission?(self.class.wooster_records.delete,self)
99
+ raise InvalidDeleteError
100
+ end
101
+ end
102
+ before_save do
103
+ changes.each {|field,value|
104
+ if false
105
+ raise InvalidSaveError
106
+ end
107
+ }
108
+ end
109
+ end
110
+ end
111
+
112
+ ActiveRecord::Querying.module_eval {
113
+ alias_method :find_by_sql_without_wooster, :find_by_sql
114
+ def find_by_sql(sql,binds=[])
115
+ find_by_sql_without_wooster(sql,binds).select{|rec| Wooster.any_permission?(wooster_records.read, rec) }
116
+ end
117
+ }
@@ -0,0 +1,88 @@
1
+ require 'byebug'
2
+ module Wooster::Policy
3
+ module Helpers
4
+ def allow
5
+ ->(x) { true}
6
+ end
7
+ def either(*args)
8
+ # case args.size
9
+ # when 1:
10
+ # args[0]
11
+ # else:
12
+ # ->(x){args[0]
13
+ # end
14
+ ->(x) {args.any?{|fun| self.instance_exec x,&fun}}
15
+ end
16
+ end
17
+ class Builder
18
+ @registry = {}
19
+
20
+ def self.registry
21
+ @registry
22
+ end
23
+
24
+ def self.define(&block)
25
+ definition_proxy = DefinitionProxy.new
26
+ definition_proxy.instance_eval(&block)
27
+ end
28
+
29
+ end
30
+ def self.build(&block)
31
+ Builder.define &block
32
+ end
33
+ class DefinitionProxy
34
+ include Helpers
35
+ def permissions(permissions_class, &block)
36
+ permissions = Permissions.new(permissions_class)
37
+ permissions.instance_eval(&block)
38
+ end
39
+ end
40
+
41
+
42
+ class Permissions # < BasicObject
43
+ include Helpers
44
+ def initialize(klass)
45
+ @klass = klass
46
+ end
47
+ def record(*args)
48
+ case args[0]
49
+ when ::Symbol
50
+ type, block = *args
51
+ #byebug
52
+ @klass.class_variable_get(:@@wooster_records)[type] << block
53
+ when ::Proc
54
+ [:read, :write, :delete, :create].each {|type| record type, args[0] }
55
+ else
56
+ raise ArgumentError
57
+ end
58
+ end
59
+ def read( block)
60
+ record(:read,block)
61
+ end
62
+ def delete( block)
63
+ record(:delete,block)
64
+ end
65
+ def create( block)
66
+ record(:create,block)
67
+ end
68
+ def write(block)
69
+ record(:write,block)
70
+ end
71
+
72
+ def field(name,type,block)
73
+ fields = @klass.class_variable_get(:@@wooster_field)
74
+ fields[name.to_s][type] << block
75
+ end
76
+ def field_read(name, block)
77
+ field name,:read, block
78
+ end
79
+ def field_write(name, block)
80
+ field name,:write, block
81
+ end
82
+ def field_readwrite(name, block)
83
+ field name,:read, block
84
+ field name,:write, block
85
+ end
86
+ end
87
+
88
+ end
@@ -0,0 +1,3 @@
1
+ module Wooster
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,23 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'wooster/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "wooster"
8
+ spec.version = Wooster::VERSION
9
+ spec.authors = ["Julian Bangert", "Alexander J. Lin", "Julia Huang"]
10
+ spec.email = ["jbangert@acm.org"]
11
+ spec.summary = %q{Mandatory Access Control for Rails}
12
+ spec.description = %q{}
13
+ spec.homepage = ""
14
+ spec.license = "MIT"
15
+
16
+ spec.files = `git ls-files -z`.split("\x0")
17
+ spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
18
+ spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
19
+ spec.require_paths = ["lib"]
20
+
21
+ spec.add_development_dependency "bundler", "~> 1.7"
22
+ spec.add_development_dependency "rake", "~> 10.0"
23
+ end
metadata ADDED
@@ -0,0 +1,84 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: wooster
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ platform: ruby
6
+ authors:
7
+ - Julian Bangert
8
+ - Alexander J. Lin
9
+ - Julia Huang
10
+ autorequire:
11
+ bindir: bin
12
+ cert_chain: []
13
+ date: 2014-12-10 00:00:00.000000000 Z
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: bundler
17
+ requirement: !ruby/object:Gem::Requirement
18
+ requirements:
19
+ - - "~>"
20
+ - !ruby/object:Gem::Version
21
+ version: '1.7'
22
+ type: :development
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ requirements:
26
+ - - "~>"
27
+ - !ruby/object:Gem::Version
28
+ version: '1.7'
29
+ - !ruby/object:Gem::Dependency
30
+ name: rake
31
+ requirement: !ruby/object:Gem::Requirement
32
+ requirements:
33
+ - - "~>"
34
+ - !ruby/object:Gem::Version
35
+ version: '10.0'
36
+ type: :development
37
+ prerelease: false
38
+ version_requirements: !ruby/object:Gem::Requirement
39
+ requirements:
40
+ - - "~>"
41
+ - !ruby/object:Gem::Version
42
+ version: '10.0'
43
+ description: ''
44
+ email:
45
+ - jbangert@acm.org
46
+ executables: []
47
+ extensions: []
48
+ extra_rdoc_files: []
49
+ files:
50
+ - ".gitignore"
51
+ - Gemfile
52
+ - LICENSE.txt
53
+ - README.md
54
+ - Rakefile
55
+ - lib/wooster.rb
56
+ - lib/wooster/base.rb
57
+ - lib/wooster/policy_builder.rb
58
+ - lib/wooster/version.rb
59
+ - wooster.gemspec
60
+ homepage: ''
61
+ licenses:
62
+ - MIT
63
+ metadata: {}
64
+ post_install_message:
65
+ rdoc_options: []
66
+ require_paths:
67
+ - lib
68
+ required_ruby_version: !ruby/object:Gem::Requirement
69
+ requirements:
70
+ - - ">="
71
+ - !ruby/object:Gem::Version
72
+ version: '0'
73
+ required_rubygems_version: !ruby/object:Gem::Requirement
74
+ requirements:
75
+ - - ">="
76
+ - !ruby/object:Gem::Version
77
+ version: '0'
78
+ requirements: []
79
+ rubyforge_project:
80
+ rubygems_version: 2.2.2
81
+ signing_key:
82
+ specification_version: 4
83
+ summary: Mandatory Access Control for Rails
84
+ test_files: []