the_role 0.9.9

Sign up to get free protection for your applications and to get access to all the features.
data/.gitignore ADDED
@@ -0,0 +1,4 @@
1
+ *.gem
2
+ .bundle
3
+ Gemfile.lock
4
+ pkg/*
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source "http://rubygems.org"
2
+
3
+ # Specify your gem's dependencies in the_role.gemspec
4
+ gem 'slim'
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2011 [name of plugin creator]
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,104 @@
1
+ ## TheRole
2
+
3
+ Gem for providing simple, but powerful and flexible role system for ROR3 applications.
4
+ Based on Hashes.
5
+
6
+ * Based on MVC semantik (easy to understand what's happening)
7
+ * Realtime dynamically management with simple interface
8
+ * Customizable
9
+
10
+ ## Installing
11
+
12
+ Gemfile
13
+
14
+ ``` ruby
15
+ gem 'the_role'
16
+ ```
17
+
18
+ ``` ruby
19
+ bundle
20
+ ```
21
+
22
+ ``` ruby
23
+ rake the_role_engine:install:migrations
24
+ >> Copied migration 20111028145956_create_roles.rb from the_role_engine
25
+ ```
26
+
27
+ ``` ruby
28
+ rake db:roles:create
29
+ >> Administrator, Moderator of pages, User, Demo
30
+ ```
31
+
32
+ When gem initialize, **User**, **Role**, **ApplicationController** classes are extending with next methods:
33
+
34
+ ## User
35
+
36
+ ``` ruby
37
+ # will be include into User.rb automaticaly
38
+ belongs_to :role
39
+ attr_accessible :role
40
+ after_save { |user| user.instance_variable_set(:@the_role, nil) }
41
+
42
+ # methods
43
+ the_role
44
+ admin?
45
+ moderator?(section)
46
+ has_role?(section, policy)
47
+ owner?(obj)
48
+
49
+ # instance variables
50
+ @the_role
51
+ ```
52
+
53
+ ## Role
54
+
55
+ ``` ruby
56
+ # will be include into Role.rb automaticaly
57
+ has_many :users
58
+ validates :name, :presence => {:message => I18n.translate('the_role.name_presence')}
59
+ validates :title, :presence => {:message => I18n.translate('the_role.title_presence')}
60
+ ```
61
+
62
+ ## ApplicationController
63
+
64
+ ``` ruby
65
+ # private methods (should be define as before filters)
66
+ the_role_access_denied
67
+ the_role_object
68
+ the_role_require
69
+ the_owner_require
70
+ ```
71
+ ## Routes
72
+
73
+ method **the_role_access_denied** needs **root_path** for redirect
74
+
75
+ ### Now try to use into console
76
+
77
+ ``` ruby
78
+ rails g scaffold article title:string content:text user_id:integer
79
+ rails g scaffold page title:string content:text user_id:integer
80
+ rails c
81
+ >> User.new(:login => 'cosmo', :username => 'John Black').save
82
+ >> u = User.first
83
+ >> u.role = Role.first # admin
84
+ >> u.save
85
+ >> u.has_role? :x, :y
86
+ => true
87
+ >> u.role = Role.last # demo
88
+ >> u.save
89
+ >> u.has_role? :pages, :show
90
+ => true
91
+ >> u.has_role? :pages, :delete
92
+ => flase
93
+ ```
94
+
95
+ ## Example
96
+
97
+ ``` ruby
98
+ - if curent_user.has_role? :pages, :show
99
+ Page content
100
+ - else
101
+ Access denied
102
+ ```
103
+
104
+ Copyright (c) 2011 [Ilya N. Zykin Github.com/the-teacher], released under the MIT license
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,55 @@
1
+ .form{
2
+ background:#EEE;
3
+ padding:5px;
4
+ margin:0 0 15px 0;
5
+ border:2px solid gray;
6
+ -moz-border-radius:5px;
7
+ }
8
+ .form label{
9
+ display:block;
10
+ }
11
+ .form .input{
12
+ border:1px solid #000;
13
+ padding:2px 0 2px 5px;
14
+ font-size:13pt;
15
+ color:DarkBlue;
16
+ }
17
+ .form .textarea{
18
+ font-size:13pt;
19
+ padding:2px;
20
+ }
21
+ .form .message_textarea{
22
+ font-size:13pt;
23
+ padding:2px;
24
+ border:1px solid black;
25
+ height: 200px;
26
+ }
27
+ .form .submit{
28
+ font-size:16pt;
29
+ }
30
+ .article_buttons{
31
+ margin:0 0 10px 0;
32
+ padding:0 0 5px 0;
33
+ border-bottom:1px dashed gray;
34
+ }
35
+ .article_buttons input{
36
+ margin-right:10px;
37
+ }
38
+ .submit_button{
39
+ margin-bottom:10px;
40
+ }
41
+ .moderation_buttons{
42
+ background:silver;
43
+ margin:3px 3px 10px 3px;
44
+ padding:5px;
45
+ border:2px solid blue;
46
+ }
47
+ .delete_button{
48
+ background: none repeat scroll 0 0 lightGrey;
49
+ border: 1px dashed gray;
50
+ padding: 5px 0;
51
+ text-align: right;
52
+ }
53
+ .delete_button input{
54
+ color:Crimson;
55
+ }
@@ -0,0 +1,13 @@
1
+ h1,h2,h3,h4,h5,h6{
2
+ font-family: Verdana, Arial;
3
+ color:#333;
4
+ font-weight:normal;
5
+ line-height:100%;
6
+ margin-bottom:15px;
7
+ }
8
+ h1{font-size:3em;}
9
+ h2{font-size:2.8em;}
10
+ h3{font-size:2.6em;}
11
+ h4{font-size:2.4em;}
12
+ h5{font-size:2.2em;}
13
+ h6{font-size:2em;}
@@ -0,0 +1,63 @@
1
+ /*18 aug 2011 */
2
+ html, body, div, span, applet, object, iframe, h1, h2, h3, h4, h5, h6,
3
+ p, img, font, pre, blockquote, i, b, u, s, strike, sub, sup, tt, big, small,
4
+ center, abbr, em, code, acronym, address, ins, del, strong, var, cite,
5
+ dfn, kbd, samp, dd, dl, dt, ol, ul, li, caption,
6
+ table, tbody, tfoot, thead, tr, th, td,
7
+ form, fieldset, legend, label,
8
+ article, aside, canvas, details, embed, figure, figcaption,
9
+ footer, header, hgroup, menu, nav, output, ruby, section, summary, time, mark, audio, video{
10
+ margin:0;
11
+ padding:0;
12
+ border:0;
13
+ outline:0;
14
+ font-size:10px; /*zero-point*/
15
+ vertical-align:baseline;
16
+ background:transparent;
17
+ line-height:100%;
18
+ }
19
+ html, body, div, applet, object, iframe, img, p, pre, blockquote,
20
+ dd, dl, dt, ol, ul, li, caption, table, tbody, tfoot, thead, tr, th, td,
21
+ form, fieldset, legend, label{
22
+ font-weight:normal;
23
+ }
24
+
25
+ img, p, pre, blockquote, dd, dt, li, caption, legend, label{line-height:100%;}
26
+ table, tr, td{
27
+ vertical-align:top;
28
+ border-collapse:collapse;
29
+ border-spacing:0;
30
+ }
31
+ img{vertical-align:top;}
32
+ ol, ul{list-style:none; margin:0;}
33
+ li{list-style-position:outside;}
34
+
35
+ a{text-decoration:none;}
36
+ a:hover{text-decoration:none;}
37
+
38
+ sup, sub{font-size:85%; zoom:1;}
39
+ sup{vertical-align:40%;}
40
+ sub{vertical-align:-40%;}
41
+ :focus{outline:0;}
42
+ .overblock{overflow:hidden; zoom:1;}
43
+ .nobr{white-space:nowrap;}
44
+ .u{text-decoration:underline;}
45
+ noscript{color:red;}
46
+ /*basic LIST styles*/
47
+ .numered_list, .marked_list{margin-left:20px;}
48
+ .numered_list li, .marked_list li{
49
+ list-style-position: outside;
50
+ margin-left: 15px;
51
+ padding-left: 5px;
52
+ }
53
+ .numered_list li{list-style-type:decimal;}
54
+ .marked_list li{list-style-type:disc;}
55
+ /*Inherit*/
56
+ a, span, font, i, b, u, s, strike{ font-size: inherit; }
57
+ /*CUSTOM*/
58
+ img, p, pre, blockquote, dd, dt, caption, legend, label{
59
+ line-height:150%;
60
+ }
61
+ p, pre, blockquote{margin-bottom:15px;}
62
+ a{color:#8CA357;}
63
+ a:hover{text-decoration:underline;}
@@ -0,0 +1,76 @@
1
+ .body{
2
+ width: 900px;
3
+ margin:auto;
4
+ font:Tahoma;
5
+ font-family:Tahoma,Trebuchet MS,Times New Roman;
6
+ }
7
+ img, p, pre, blockquote, dd, dt, caption, legend, label{
8
+ font-size: 2em;
9
+ }
10
+ ul.index{
11
+ p{
12
+ padding: 5px;
13
+ &:hover{
14
+ background: #DDD;
15
+
16
+ }
17
+ a.delete{
18
+ float: right;
19
+ }
20
+ }
21
+ }//ul.index
22
+
23
+ h4{
24
+ position: relative;
25
+ padding: 5px;
26
+ background: LightBlue;
27
+ .controls{
28
+ a{
29
+ color: blue;
30
+ }
31
+ }
32
+ }
33
+
34
+ .controls{
35
+ position:absolute;
36
+ right:10px;
37
+ top:10%;
38
+ zoom:1;
39
+ padding-bottom:6px;
40
+ }
41
+ .controls a{
42
+ margin:0 10px;
43
+ font-size:10pt;
44
+ color:#CCC;
45
+ border:1px solid transparent;
46
+ padding:3px;
47
+ text-decoration:none;
48
+ }
49
+ .controls a:hover{
50
+ color:#999;
51
+ border:1px solid #999;
52
+ }
53
+ ul.rights{
54
+ margin:0 0 20px;
55
+ }
56
+ ul.rights li{
57
+ margin:0 0 5px 20px;
58
+ position:relative;
59
+ zoom:1;
60
+ border-bottom:1px solid #EEE;
61
+ padding: 5px 0;
62
+ font-size:9pt;
63
+ }
64
+ ul.rights li .controls{
65
+ top:10%;
66
+ right:5px;
67
+ padding:5px;
68
+ }
69
+ form.new_action{
70
+ padding:15px;
71
+ background:#EEE;
72
+ margin:0 0 50px 0;
73
+ }
74
+ form{
75
+ margin:0 0 50px 0;
76
+ }
@@ -0,0 +1,37 @@
1
+ class Admin::RoleSectionController < ApplicationController
2
+ # before_filter :login_required
3
+ before_filter :find_role, :only=>[:destroy, :delete_policy]
4
+
5
+ def destroy
6
+ section_name = params[:id]
7
+ role = TheRole.get(@role.the_role)
8
+ role.delete(section_name.to_sym)
9
+
10
+ if @role.update_attributes({:the_role => role.to_yaml})
11
+ flash[:notice] = t('the_role.section_deleted')
12
+ redirect_to edit_admin_role_path(@role)
13
+ else
14
+ render :action => :edit
15
+ end
16
+ end#destroy
17
+
18
+ def delete_policy
19
+ section_name = params[:id]
20
+ policy_name = params[:name]
21
+ role = TheRole.get(@role.the_role)
22
+ role[section_name.to_sym].delete(policy_name.to_sym)
23
+
24
+ if @role.update_attributes({:the_role => role.to_yaml})
25
+ flash[:notice] = t('the_role.section_policy_deleted')
26
+ redirect_to edit_admin_role_path(@role)
27
+ else
28
+ render :action => :edit
29
+ end
30
+ end#delete_policy
31
+
32
+ protected
33
+
34
+ def find_role
35
+ @role = Role.find(params[:role_id])
36
+ end
37
+ end
@@ -0,0 +1,106 @@
1
+ require 'the_role'
2
+
3
+ class Admin::RolesController < ApplicationController
4
+ layout 'the_role'
5
+ # before_filter :login_required
6
+ # before_filter :role_require
7
+ before_filter :find_role, :only => [:show, :edit, :update, :destroy, :new_role_section, :new_role_policy]
8
+
9
+ def index
10
+ @roles = Role.all(:order => "created_at ASC")
11
+ end
12
+
13
+ def new
14
+ @role = Role.new
15
+ end
16
+
17
+ def edit; end
18
+
19
+ def create
20
+ @role = Role.new(params[:role])
21
+
22
+ if @role.save
23
+ flash[:notice] = t('the_role.role_created')
24
+ redirect_to edit_admin_role_path(@role)
25
+ else
26
+ render :action => :new
27
+ end
28
+ end
29
+
30
+ def update
31
+ role = TheRole.get(@role.the_role).the_reset!
32
+ role.the_merge!(params[:role][:the_role])
33
+
34
+ if @role.update_attribute(:the_role, role.to_yaml)
35
+ flash[:notice] = t('the_role.role_updated')
36
+ redirect_to edit_admin_role_path(@role)
37
+ else
38
+ render :action => :edit
39
+ end
40
+ end
41
+
42
+ def new_role_section
43
+ # validate 1
44
+ if params[:section_name].blank?
45
+ flash[:error] = t('the_role.section_name_is_blank')
46
+ redirect_to edit_admin_role_path(@role) and return
47
+ end
48
+
49
+ # validate 2
50
+ section_name = params[:section_name]
51
+ unless section_name.match(TheRole::NAME_SYMBOLS)
52
+ flash[:error] = t('the_role.section_name_is_wrong')
53
+ redirect_to edit_admin_role_path(@role) and return
54
+ end
55
+
56
+ section_name.downcase!
57
+ role = TheRole.get(@role.the_role)
58
+
59
+ # validate 3
60
+ if role[section_name.to_sym]
61
+ flash[:error] = t('the_role.section_exists')
62
+ redirect_to edit_admin_role_path(@role) and return
63
+ end
64
+
65
+ role[section_name.to_sym] = Hash.new
66
+
67
+ if @role.update_attributes({:the_role => role.to_yaml})
68
+ flash[:notice] = t('the_role.section_created')
69
+ redirect_to edit_admin_role_path(@role)
70
+ else
71
+ render :action => :edit
72
+ end
73
+ end#new_role_section
74
+
75
+ def new_role_policy
76
+ params[:section_policy].downcase!
77
+
78
+ # validate 1
79
+ unless params[:section_policy].match(TheRole::NAME_SYMBOLS)
80
+ flash[:error] = t('the_role.section_policy_wrong_name')
81
+ redirect_to edit_admin_role_path(@role)
82
+ end
83
+
84
+ role = TheRole.get(@role.the_role)
85
+ role[params[:section_name].to_sym][params[:section_policy].to_sym] = true
86
+
87
+ if @role.update_attributes({:the_role => role.to_yaml})
88
+ flash[:notice] = t('the_role.section_policy_created')
89
+ redirect_to edit_admin_role_path(@role)
90
+ else
91
+ render :action => :edit
92
+ end
93
+ end#new_role_policy
94
+
95
+ def destroy
96
+ @role.destroy
97
+ redirect_to admin_roles_url
98
+ end
99
+
100
+ protected
101
+
102
+ def find_role
103
+ @role = Role.find(params[:id])
104
+ end
105
+
106
+ end
@@ -0,0 +1,26 @@
1
+ - role = TheRole.get(@role.the_role)
2
+
3
+ - if role.blank?
4
+ h3
5
+ = t('.empty')
6
+ - else
7
+ -role.each do |name, set|
8
+ h4
9
+ = name
10
+ span.controls
11
+ = link_to(t('.delete'), admin_role_section_url(@role, name), :method => :delete, :confirm => t('.destroy_section_confirm'))
12
+
13
+ - if set.is_a?(Hash)
14
+ ul.rights
15
+ - set.each do |n, v|
16
+ li
17
+ = check_box_tag "role[the_role][#{name}][#{n}]", true, v
18
+ = n
19
+ .controls
20
+ = link_to t('.delete'), delete_policy_admin_role_section_path(@role, name, :name => n), :method => :delete, :confirm => t('.delete_policy_confirm')
21
+
22
+ = f.submit button
23
+
24
+
25
+
26
+
@@ -0,0 +1,37 @@
1
+ - content_for :title do
2
+ = t('.title')
3
+
4
+ p= flash[:notice]
5
+
6
+ h1= t('.title')
7
+
8
+ p= link_to raw(t('.back')), admin_roles_path
9
+
10
+ h2
11
+ == t('.name')
12
+ = @role.title
13
+
14
+ = form_for :role, :url => {:action=> :update }, :html => {:method => :put, :class => :form } do |f|
15
+ = render :partial => 'form', :locals => {:f => f, :button => t('.update')}
16
+
17
+ h4= t('.create_section')
18
+ - role = TheRole.get(@role.the_role)
19
+
20
+ = form_tag(new_role_section_admin_role_path, :method => :post, :class => :new_action) do
21
+ = text_field_tag :section_name
22
+ = submit_tag t('.create_section')
23
+
24
+ h4= t('.create_access_policy')
25
+
26
+ - unless role.empty?
27
+ = form_tag(new_role_policy_admin_role_path(@role), :method => :post, :class => :new_action) do
28
+ = text_field_tag :section_policy
29
+
30
+ select name=:section_name
31
+ -role.each do |name, set|
32
+ option value=name
33
+ = name
34
+
35
+ input type=:submit value=t('.create_policy')
36
+ - else
37
+ p= t('.section_needs')
@@ -0,0 +1,9 @@
1
+ h3= t('.list')
2
+ ul.index
3
+ - @roles.each do |role|
4
+ li
5
+ p
6
+ = link_to role.title, edit_admin_role_url(role)
7
+ = link_to t('.delete') + role.title , admin_role_url(role), :method => :delete, :class => :delete
8
+
9
+ p= link_to t('.new'), new_admin_role_path
@@ -0,0 +1,12 @@
1
+ p= link_to raw(t('.back')), admin_roles_path
2
+ - @role.errors.each do |f, m|
3
+ p= m
4
+
5
+ .form
6
+ h5= t('.create')
7
+ = form_for(@role, :url => admin_roles_path) do |f|
8
+ label= t('.name')
9
+ p= f.text_field :name
10
+ label= t('.title')
11
+ p= f.text_field :title
12
+ = f.submit t('.new')
@@ -0,0 +1,15 @@
1
+ doctype html
2
+ html
3
+ head
4
+ title= yield(:title)
5
+ = stylesheet_link_tag 'the_role/reset'
6
+ = stylesheet_link_tag 'the_role/style'
7
+ = stylesheet_link_tag 'the_role/headers'
8
+ = stylesheet_link_tag 'the_role/form'
9
+
10
+ = javascript_include_tag :jquery
11
+ = javascript_include_tag :jquery_ujs
12
+ = csrf_meta_tags
13
+
14
+ body
15
+ .body= yield
@@ -0,0 +1,42 @@
1
+ # Sample localization file for English. Add more files in this directory for other locales.
2
+ # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3
+ ru:
4
+ the_role:
5
+ name_presence: Установите имя роли
6
+ title_presence: Установите название роли
7
+ section_created: Правовая группа успешно создана
8
+ section_policy_created: В заданной группе успешно создана политика доступа
9
+ section_deleted: Политика доступа удалена
10
+ section_policy_deleted: Политика доступа удалена
11
+ section_name_is_wrong: Ошибочное название правовой группы
12
+ section_policy_wrong_name: Ошибочное название правовой политики
13
+ section_name_is_blank: Имя правовой группы оказалось пустым
14
+ section_exists: Правовая группа уже существует
15
+ role_created: Роль успешно создана
16
+ role_updated: Роль успешно обновлена
17
+ admin:
18
+ roles:
19
+ index:
20
+ list: Список ролей
21
+ delete: 'Удалить роль '
22
+ new: Создать новую роль
23
+ edit:
24
+ title: Редактирование роли
25
+ back: '&larr; К списку ролей'
26
+ name: 'Название роли &mdash; '
27
+ create_section: Создать правовую группу
28
+ create_access_policy: Создать политику доступа
29
+ create_policy: Создать политику
30
+ section_needs: Создайте хотя бы одну правовую группу
31
+ update: Обновить
32
+ form:
33
+ destroy_section_confirm: Удалить правовую группу?
34
+ empty: Нет ни одной правовой группы
35
+ delete_policy_confirm: Удалить политику доступа?
36
+ delete: Удалить
37
+ new:
38
+ back: '&larr; К списку ролей'
39
+ create: Создать новую роль
40
+ name: Имя роли (латиницей)
41
+ title: Название роли
42
+ new: Создать
data/config/routes.rb ADDED
@@ -0,0 +1,18 @@
1
+ Rails.application.routes.draw do
2
+ namespace :admin do
3
+ resources :roles do
4
+ member do
5
+ get :new
6
+ get :index
7
+ post :new_role_section
8
+ post :new_role_policy
9
+ end
10
+ resources :sections, :controller => :role_section do
11
+ member do
12
+ get :new_policy
13
+ delete :delete_policy
14
+ end
15
+ end#sections
16
+ end#policy
17
+ end#admin
18
+ end
@@ -0,0 +1,17 @@
1
+ class CreateRoles < ActiveRecord::Migration
2
+ def self.up
3
+ create_table :roles do |t|
4
+
5
+ t.string :name
6
+ t.string :title
7
+ t.text :description
8
+ t.text :the_role, :null => false
9
+
10
+ t.timestamps
11
+ end
12
+ end
13
+
14
+ def self.down
15
+ drop_table :roles
16
+ end
17
+ end
@@ -0,0 +1,120 @@
1
+ namespace :db do
2
+ namespace :roles do
3
+ # rake db:roles:create
4
+ desc 'create roles'
5
+ task :create => :environment do
6
+ # ADMIN
7
+ role = {
8
+ :system => {
9
+ :administrator => true
10
+ }
11
+ }
12
+ Role.new(
13
+ :name => :administrator,
14
+ :title => 'Administrator',
15
+ :description => 'Role for administrator',
16
+ :the_role => role.to_yaml
17
+ ).save!
18
+ puts 'Administrator'
19
+
20
+ # MODERATOR
21
+ role = {
22
+ :moderator => {
23
+ :pages => true
24
+ },
25
+ :markup => {
26
+ :html => true
27
+ }
28
+ }
29
+ Role.new(
30
+ :name => :user,
31
+ :title => 'Moderator of pages',
32
+ :description => "Moderator #1",
33
+ :the_role => role.to_yaml
34
+ ).save!
35
+ puts 'Moderator of pages'
36
+
37
+ # USER
38
+ role = {
39
+ :users => {
40
+ :cabinet => true,
41
+ :update => true,
42
+ :avatar_upload => true
43
+ },
44
+ :profiles => {
45
+ :edit => true,
46
+ :update => true
47
+ },
48
+ :articles => {
49
+ :new => true,
50
+ :create => true,
51
+ :edit => true,
52
+ :update => true,
53
+ :destroy => true,
54
+ :tags => false
55
+ },
56
+ :pages => {
57
+ :new => true,
58
+ :create => true,
59
+ :edit => true,
60
+ :update => true,
61
+ :destroy => true,
62
+ :tags => true
63
+ },
64
+ :markup => {
65
+ :html => false
66
+ }
67
+ }
68
+ Role.new(
69
+ :name => :user,
70
+ :title => 'User',
71
+ :description => "Role for User",
72
+ :the_role => role.to_yaml
73
+ ).save!
74
+ puts 'User'
75
+
76
+ # DEMO
77
+ role = {
78
+ :users => {
79
+ :cabinet => true,
80
+ :update => false,
81
+ :avatar_upload => false
82
+ },
83
+ :profiles => {
84
+ :edit => true,
85
+ :update => false
86
+ },
87
+ :articles => {
88
+ :new => true,
89
+ :show => true,
90
+ :create => false,
91
+ :edit => true,
92
+ :update => false,
93
+ :destroy => false,
94
+ :tags => false
95
+ },
96
+ :pages => {
97
+ :new => true,
98
+ :show => true,
99
+ :create => false,
100
+ :edit => true,
101
+ :update => false,
102
+ :destroy => false,
103
+ :tags => false
104
+ },
105
+ :markup => {
106
+ :html => false
107
+ }
108
+ }
109
+ Role.new(
110
+ :name => :user,
111
+ :title => 'Demo',
112
+ :description => "Demo user",
113
+ :the_role => role.to_yaml
114
+ ).save!
115
+ puts 'Demo'
116
+
117
+ puts 'Roles created'
118
+ end#create
119
+ end#roles
120
+ end#db
@@ -0,0 +1,12 @@
1
+ require 'the_role'
2
+ require 'rails'
3
+
4
+ module TheRole
5
+ class Engine < Rails::Engine
6
+ config.to_prepare do
7
+ Role.send :include, TheRole::RoleModel if the_class_exists? :Role
8
+ User.send :include, TheRole::UserModel if the_class_exists? :User
9
+ ApplicationController.send :include, TheRole::Requires if the_class_exists? :ApplicationController
10
+ end
11
+ end#Engine
12
+ end#TheRole
@@ -0,0 +1,25 @@
1
+ class Hash
2
+ def the_reset!(default_value= false)
3
+ base= self
4
+ base.each do |key, v|
5
+ if base[key.to_sym].is_a?(Hash)
6
+ base[key.to_sym]= base[key.to_sym].the_reset!(default_value)
7
+ else
8
+ base[key.to_sym]= default_value
9
+ end
10
+ end
11
+ end
12
+
13
+ def the_merge!(hash= nil, default_value= true)
14
+ return self unless hash.is_a?(Hash)
15
+ base= self
16
+ hash.each do |key, v|
17
+ if base[key.to_sym].is_a?(Hash) && hash[key.to_sym].is_a?(Hash)
18
+ base[key.to_sym]= base[key.to_sym].the_merge!(hash[key.to_sym], default_value)
19
+ else
20
+ base[key.to_sym]= default_value
21
+ end
22
+ end
23
+ base.to_hash
24
+ end
25
+ end
@@ -0,0 +1,8 @@
1
+ # the_class_exists? :User => true | flase
2
+ # the_class_exists? :Role => true | flase
3
+ def the_class_exists?(class_name)
4
+ klass = Module.const_get(class_name)
5
+ return klass.is_a?(Class)
6
+ rescue NameError
7
+ return false
8
+ end
@@ -0,0 +1,3 @@
1
+ module TheRole
2
+ VERSION = "0.9.9"
3
+ end
data/lib/the_role.rb ADDED
@@ -0,0 +1,107 @@
1
+ require "the_role/version"
2
+ require "the_role/hash"
3
+ require "the_role/engine"
4
+ require "the_role/the_class_exists"
5
+
6
+ module TheRole
7
+ # include TheRole::Requires
8
+ # include TheRole::UserModel
9
+ # include TheRole::RoleModel
10
+
11
+ NAME_SYMBOLS = /^[a-zA-Z][a-zA-Z0-9_\-]*[a-zA-Z0-9]$/
12
+
13
+ # TheRole.get(@role.the_role)
14
+ def self.get str
15
+ hash = YAML::load(str)
16
+ hash ? hash : Hash.new
17
+ end
18
+
19
+ module UserModel
20
+ def self.included(base)
21
+ base.class_eval do
22
+ belongs_to :role
23
+ attr_accessible :role
24
+ # when user changed - @the_role should be reload
25
+ after_save { |user| user.instance_variable_set(:@the_role, nil) }
26
+ end
27
+ end
28
+
29
+ def the_role
30
+ @the_role ||= self.role ? TheRole.get(self.role.the_role) : Hash.new
31
+ end
32
+
33
+ def admin?
34
+ role = self.the_role[:system] ? self.the_role[:system][:administrator] : false
35
+ role && role.is_a?(TrueClass)
36
+ end
37
+
38
+ def moderator? section
39
+ role = self.the_role[:system] ? self.the_role[:moderator][section.to_sym] : false
40
+ role && role.is_a?(TrueClass)
41
+ end
42
+
43
+ # TRUE if user has role - administartor of system
44
+ # TRUE if user is moderator of this section (controller_name)
45
+ # FALSE when this section (or role) is nil
46
+ # return current value of role (TRUE|FALSE) if it exists
47
+ def has_role?(section, policy)
48
+ return true if self.admin?
49
+ return true if self.moderator? section
50
+ self.the_role[section.to_sym][policy.to_sym].is_a?(TrueClass) if self.the_role[section.to_sym] && self.the_role[section.to_sym][policy.to_sym]
51
+ end
52
+
53
+ # FALSE if object is nil
54
+ # If object is a USER - check for youself
55
+ # Check for owner field - :user_id
56
+ # Check for owner _object_ if owner field is not :user_id
57
+ def owner?(obj)
58
+ return false unless obj
59
+ return true if self.admin?
60
+ return true if self.moderator? obj.class.to_s.tableize # moderator? 'pages'
61
+ return self.id == obj.id if obj.is_a?(User)
62
+ return self.id == obj[:user_id] if obj[:user_id]
63
+ return self.id == obj[:user][:id] if obj[:user]
64
+ false
65
+ end
66
+ end#UserModel
67
+
68
+ module RoleModel
69
+ def self.included(base)
70
+ base.class_eval do
71
+ has_many :users
72
+ validates :name, :presence => {:message => I18n.translate('the_role.name_presence')}
73
+ validates :title, :presence => {:message => I18n.translate('the_role.title_presence')}
74
+ end
75
+ end
76
+ end#RoleModel
77
+
78
+ # for application controller
79
+ # @the_role_object should be defined with before_filter
80
+ # @the_role_object = @page
81
+ module Requires
82
+ private
83
+
84
+ def the_role_access_denied
85
+ flash[:error] = t('the_role.access_denied')
86
+ redirect_to root_path
87
+ end
88
+
89
+ # before_filter :role_require
90
+ def the_role_require
91
+ the_role_access_denied unless current_user.has_role?(controller_name, action_name)
92
+ end
93
+
94
+ # before_filter :the_role_object
95
+ # define class variable for *the_owner_require* filter with Controller class name
96
+ # @the_role_object = @article
97
+ def the_role_object
98
+ variable_name = "@" + self.class.to_s.underscore.split('_').first.singularize
99
+ @the_role_object = self.instance_variable_get("@#{variable_name}")
100
+ end
101
+
102
+ # before_filter :owner_and_role_require
103
+ def the_owner_require
104
+ the_role_access_denied unless current_user.owner?(@the_role_object)
105
+ end
106
+ end#Requires
107
+ end#TheRole
data/the_role.gemspec ADDED
@@ -0,0 +1,24 @@
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "the_role/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = "the_role"
7
+ s.version = TheRole::VERSION
8
+ s.authors = ["Ilya N. Zykin"]
9
+ s.email = ["zykin-ilya@ya.ru"]
10
+ s.homepage = "https://github.com/the-teacher/the_role"
11
+ s.summary = %q{TheRole - simple, but powerful role system}
12
+ s.description = %q{TheRole - simple, but powerful role system for ROR applications}
13
+
14
+ s.rubyforge_project = "the_role"
15
+
16
+ s.files = `git ls-files`.split("\n")
17
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
18
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
19
+ s.require_paths = ["lib"]
20
+
21
+ # specify any dependencies here; for example:
22
+ # s.add_development_dependency "rspec"
23
+ # s.add_runtime_dependency "rest-client"
24
+ end
metadata ADDED
@@ -0,0 +1,71 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: the_role
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.9.9
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Ilya N. Zykin
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2011-10-29 00:00:00.000000000Z
13
+ dependencies: []
14
+ description: TheRole - simple, but powerful role system for ROR applications
15
+ email:
16
+ - zykin-ilya@ya.ru
17
+ executables: []
18
+ extensions: []
19
+ extra_rdoc_files: []
20
+ files:
21
+ - .gitignore
22
+ - Gemfile
23
+ - MIT-LICENSE
24
+ - README.md
25
+ - Rakefile
26
+ - app/assets/stylesheets/the_role/form.css
27
+ - app/assets/stylesheets/the_role/headers.css.scss
28
+ - app/assets/stylesheets/the_role/reset.css.scss
29
+ - app/assets/stylesheets/the_role/style.css.scss
30
+ - app/controllers/admin/role_section_controller.rb
31
+ - app/controllers/admin/roles_controller.rb
32
+ - app/views/admin/roles/_form.slim
33
+ - app/views/admin/roles/edit.slim
34
+ - app/views/admin/roles/index.slim
35
+ - app/views/admin/roles/new.slim
36
+ - app/views/layouts/the_role.slim
37
+ - config/locales/ru.yml
38
+ - config/routes.rb
39
+ - db/migrate/20111025025129_create_roles.rb
40
+ - lib/tasks/roles.rake
41
+ - lib/the_role.rb
42
+ - lib/the_role/engine.rb
43
+ - lib/the_role/hash.rb
44
+ - lib/the_role/the_class_exists.rb
45
+ - lib/the_role/version.rb
46
+ - the_role.gemspec
47
+ homepage: https://github.com/the-teacher/the_role
48
+ licenses: []
49
+ post_install_message:
50
+ rdoc_options: []
51
+ require_paths:
52
+ - lib
53
+ required_ruby_version: !ruby/object:Gem::Requirement
54
+ none: false
55
+ requirements:
56
+ - - ! '>='
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ none: false
61
+ requirements:
62
+ - - ! '>='
63
+ - !ruby/object:Gem::Version
64
+ version: '0'
65
+ requirements: []
66
+ rubyforge_project: the_role
67
+ rubygems_version: 1.8.6
68
+ signing_key:
69
+ specification_version: 3
70
+ summary: TheRole - simple, but powerful role system
71
+ test_files: []