the_role 0.9.9

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 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: []