citygate 0.0.6 → 0.0.7

Sign up to get free protection for your applications and to get access to all the features.
Files changed (65) hide show
  1. data/README.rdoc +21 -0
  2. data/app/assets/javascripts/citygate.js +1 -2
  3. data/app/assets/javascripts/citygate/admin_users.coffee +1 -1
  4. data/app/assets/javascripts/citygate/home.js.coffee.erb +13 -0
  5. data/app/controllers/citygate/admin/application_controller.rb +2 -4
  6. data/app/controllers/citygate/admin/users_controller.rb +17 -0
  7. data/app/controllers/citygate/application_controller.rb +11 -4
  8. data/app/controllers/citygate/home_controller.rb +9 -0
  9. data/app/helpers/citygate/application_helper.rb +12 -0
  10. data/app/models/citygate/permission.rb +18 -1
  11. data/app/models/citygate/user.rb +6 -1
  12. data/app/views/citygate/admin/users/edit.html.erb +22 -0
  13. data/app/views/citygate/home/_role_changer.html.erb +3 -0
  14. data/app/views/citygate/home/index.html.erb +2 -4
  15. data/app/views/citygate/shared/_navigation.html.erb +9 -10
  16. data/app/views/citygate/users/show.html.erb +2 -0
  17. data/app/views/layouts/{admin/application.html.erb → admin.html.erb} +3 -3
  18. data/config/initializers/01_load_config.rb +2 -1
  19. data/config/initializers/devise.rb +1 -1
  20. data/config/locales/controllers/admin/users/en.yml +6 -0
  21. data/config/routes.rb +2 -0
  22. data/db/migrate/20120916221334_add_conditions_to_permissions.rb +5 -0
  23. data/db/seeds.rb +1 -1
  24. data/lib/ability.rb +42 -22
  25. data/lib/citygate/version.rb +1 -1
  26. data/spec/dummy/config/accounts.yml +3 -0
  27. data/spec/dummy/db/development.sqlite3 +0 -0
  28. data/spec/dummy/db/migrate/20120916223209_add_conditions_to_permissions.citygate.rb +6 -0
  29. data/spec/dummy/db/schema.rb +2 -1
  30. data/spec/dummy/db/test.sqlite3 +0 -0
  31. data/spec/dummy/features/step_definitions/user_steps.rb +17 -1
  32. data/spec/dummy/features/support/paths.rb +3 -0
  33. data/spec/dummy/features/users/users_admin.feature +13 -0
  34. data/spec/dummy/log/development.log +9037 -0
  35. data/spec/dummy/log/test.log +11901 -0
  36. data/spec/dummy/spec/lib/ability_spec.rb +10 -0
  37. data/spec/dummy/spec/models/permission_spec.rb +13 -0
  38. data/spec/dummy/spec/models/user_spec.rb +11 -0
  39. data/spec/dummy/tmp/cache/assets/C49/CE0/sprockets%2F2648b1b520975b78028cd5d352510c64 +0 -0
  40. data/spec/dummy/tmp/cache/assets/C63/E40/sprockets%2F36a675f52eb281488964b58be8971051 +0 -0
  41. data/spec/dummy/tmp/cache/assets/C72/B10/sprockets%2F21a4b8118f1f4254bf815e306027b951 +0 -0
  42. data/spec/dummy/tmp/cache/assets/C79/FC0/sprockets%2F76c2f8ffd1175afd6274640057134300 +0 -0
  43. data/spec/dummy/tmp/cache/assets/C7A/CE0/sprockets%2F9124c83a02e7332a90b2883b69f81d04 +0 -0
  44. data/spec/dummy/tmp/cache/assets/C89/540/sprockets%2F606a455261f8f047c994c4b9a582f126 +0 -0
  45. data/spec/dummy/tmp/cache/assets/CC5/020/sprockets%2Ffa39f3f719158fea829829617391b42c +0 -0
  46. data/spec/dummy/tmp/cache/assets/CD6/2B0/sprockets%2F08e01b4122e606428c6de7234d87bee1 +0 -0
  47. data/spec/dummy/tmp/cache/assets/CD8/370/sprockets%2F357970feca3ac29060c1e3861e2c0953 +0 -0
  48. data/spec/dummy/tmp/cache/assets/CE2/7D0/sprockets%2Fe69b8c4ca0800c940d1d9785f1a92327 +0 -0
  49. data/spec/dummy/tmp/cache/assets/CE3/150/sprockets%2F7d7a09e1df5c7510266a8d752683c4b3 +0 -0
  50. data/spec/dummy/tmp/cache/assets/CE8/510/sprockets%2F0d85ab6e3972f70636a990e91fec8301 +0 -0
  51. data/spec/dummy/tmp/cache/assets/D0B/180/sprockets%2F33a5fea6d23f2a4a6872793d659420aa +0 -0
  52. data/spec/dummy/tmp/cache/assets/D0D/DE0/sprockets%2Fa35442f02b0b2479f22d83d639d8c4fd +0 -0
  53. data/spec/dummy/tmp/cache/assets/D32/A10/sprockets%2F13fe41fee1fe35b49d145bcc06610705 +0 -0
  54. data/spec/dummy/tmp/cache/assets/D4E/1B0/sprockets%2Ff7cbd26ba1d28d48de824f0e94586655 +0 -0
  55. data/spec/dummy/tmp/cache/assets/D5A/EA0/sprockets%2Fd771ace226fc8215a3572e0aa35bb0d6 +0 -0
  56. data/spec/dummy/tmp/cache/assets/D73/010/sprockets%2F834fa37dfa7f28148e125baf3f9d91b0 +0 -0
  57. data/spec/dummy/tmp/cache/assets/D78/BD0/sprockets%2Fd0c9ac69560ea197444b7f759ecd06da +0 -0
  58. data/spec/dummy/tmp/cache/assets/D7B/E90/sprockets%2F4b4bc96ff55fbc9a5844594eaba42790 +0 -0
  59. data/spec/dummy/tmp/cache/assets/D99/BF0/sprockets%2F2fd8d582e234f8d0a741c1b4cafb716e +0 -0
  60. data/spec/dummy/tmp/cache/assets/D9E/F10/sprockets%2F9ab223df888d724dcad09eb1163cc5f4 +0 -0
  61. data/spec/dummy/tmp/cache/assets/D9E/F70/sprockets%2Fc5d4a6e7d907804c52cbf910339dafdb +0 -0
  62. data/spec/dummy/tmp/cache/assets/DDC/400/sprockets%2Fcffd775d018f68ce5dba1ee0d951a994 +0 -0
  63. data/spec/dummy/tmp/cache/assets/E04/890/sprockets%2F2f5173deea6c795b8fdde723bb4b63af +0 -0
  64. data/spec/dummy/tmp/cache/assets/E2B/670/sprockets%2Feac21904ecb266ce92aecadb8681b7fe +0 -0
  65. metadata +52 -38
@@ -46,6 +46,19 @@ In case of development add this to +config/environments/development.rb+
46
46
 
47
47
  config.action_mailer.default_url_options = { :host => 'localhost:3000' }
48
48
 
49
+ == Helper Configuration
50
+
51
+ In order to get the helper methods citygate exposes you'll have to include them in your +app/controllers/application_controller.rb+ like so:
52
+
53
+ class ApplicationController < ActionController::Base
54
+ helper Citygate::Engine.helpers
55
+ end
56
+
57
+ The exposed methods are:
58
+
59
+ role_changer:: a select for changing roles (only available when logged in and in development)
60
+ citygate_nav_links:: the default +nav+ for citygate with sign in, log out and admin links
61
+
49
62
  == OmniAuth Configuration
50
63
 
51
64
  Citygate needs your facebook apps identifiers which are loaded from a file you must create called +config/accounts.yml+ and has the following format:
@@ -54,8 +67,16 @@ Citygate needs your facebook apps identifiers which are loaded from a file you m
54
67
  app_id: "your app id from https://developers.facebook.com/apps"
55
68
  app_secret: "your app secret from https://developers.facebook.com/apps"
56
69
 
70
+ This file is not required for the application to run, but without it the facebook login will not work.
71
+
57
72
  In case you are wondering, the reason it is not required for you to add your google OAuth identifier is because it is the same for everyone. It then redirects you to a authentication service within google servers.
58
73
 
74
+ == Loading Assets
75
+
76
+ In order to have the javascript added by Citygate you need to include it in your manifest file, like so:
77
+
78
+ //= require citygate
79
+
59
80
  == Citygate Options
60
81
 
61
82
  You can change citygate's defaults by editing your +config/application.rb+ file like so
@@ -12,5 +12,4 @@
12
12
  //
13
13
  //= require jquery
14
14
  //= require jquery_ujs
15
- //= require ./citygate/jquery.pjax
16
- //= require ./citygate/admin_users
15
+ //= require citygate/home
@@ -1,2 +1,2 @@
1
1
  $ ->
2
- $("a").pjax("#container").on 'click'
2
+ $("a").pjax("#pjax-container").on 'click'
@@ -0,0 +1,13 @@
1
+ $ ->
2
+ role_selector =
3
+ $el: $("#role_id")
4
+
5
+ select_new_role: ->
6
+ role_selector.$el.on "change", (event) ->
7
+ $.post "home/role_change", { data: role_selector.$el.val() }, (data) ->
8
+ window.location.href = data.redirect
9
+
10
+ init: ->
11
+ role_selector.select_new_role()
12
+
13
+ role_selector.init()
@@ -4,12 +4,10 @@ class Citygate::Admin::ApplicationController < Citygate::ApplicationController
4
4
 
5
5
  private
6
6
  def set_layout
7
- if request.headers['X-PJAX-layout']
8
- "admin/application"
9
- elsif request.headers['X-PJAX']
7
+ if request.headers['X-NO-LAYOUT']
10
8
  false
11
9
  else
12
- "admin/application"
10
+ "admin"
13
11
  end
14
12
  end
15
13
  end
@@ -14,4 +14,21 @@ class Citygate::Admin::UsersController < Citygate::Admin::ApplicationController
14
14
  respond_with @user
15
15
  end
16
16
 
17
+ def edit
18
+ @user = Citygate::User.find(params[:id])
19
+
20
+ respond_with @user
21
+ end
22
+
23
+ def update
24
+ @user = Citygate::User.find(params[:id])
25
+
26
+ if @user.update_without_password(params[:user])
27
+ flash[:notice] = t('admin.users.update.success')
28
+ redirect_to :action => 'show'
29
+ else
30
+ flash[:error] = t('admin.users.update.error')
31
+ redirect_to :action => 'edit'
32
+ end
33
+ end
17
34
  end
@@ -6,23 +6,30 @@
6
6
  # end
7
7
  class Citygate::ApplicationController < ::ApplicationController
8
8
  protect_from_forgery
9
-
9
+
10
+ before_filter :set_locale
11
+
10
12
  rescue_from CanCan::AccessDenied do |exception|
11
13
  redirect_to root_url, :alert => t('cancan.access_denied')
12
14
  end unless ::ApplicationController.rescue_handlers.assoc "CanCan::AccessDenied"
13
-
15
+
14
16
  # Gets or creates an Ability instance for usage with CanCan
15
17
  def current_ability
16
18
  @current_ability ||= Ability.new(current_user)
17
19
  end
18
-
20
+
19
21
  # Change Devise's redirect after sign in url
20
22
  # @param [Object] resource_or_scope Not used here
21
23
  def stored_location_for(resource_or_scope)
22
24
  root_url
23
25
  end
24
-
26
+
25
27
  # Defines the omniauth prefix so that citygate can be
26
28
  # mounted in anywhere
27
29
  Devise.omniauth_path_prefix = "#{Citygate::Engine.mount_path}/users/auth".squeeze "/"
30
+
31
+ # Sets the language for the current page
32
+ def set_locale
33
+ I18n.locale = params[:locale] || I18n.default_locale
34
+ end
28
35
  end
@@ -1,7 +1,16 @@
1
1
  class Citygate::HomeController < Citygate::ApplicationController
2
2
  authorize_resource :class => false
3
+ skip_authorize_resource :only => :role_change
3
4
 
4
5
  def index
5
6
  @users = Citygate::User.all
6
7
  end
8
+
9
+ def role_change
10
+ saved = current_user.update_attribute :role_id, params[:data]
11
+
12
+ respond_to do |format|
13
+ format.json { render json: { text: (saved) ? "OK" : "Arrebentou", redirect: root_path } }
14
+ end
15
+ end
7
16
  end
@@ -1,4 +1,16 @@
1
1
  module Citygate
2
2
  module ApplicationHelper
3
+
4
+ def role_changer
5
+ if Rails.env == "development" && current_user
6
+ @role = current_user.role || Citygate::Role.new
7
+ render :partial => "citygate/home/role_changer"
8
+ end
9
+ end
10
+
11
+ def citygate_nav_links
12
+ render 'citygate/shared/navigation'
13
+ end
14
+
3
15
  end
4
16
  end
@@ -1,7 +1,24 @@
1
1
  module Citygate
2
2
  # @author Zamith
3
3
  class Permission < ActiveRecord::Base
4
- attr_accessible :action, :subject_class, :subject_id, :role_id
4
+ attr_accessible :action, :subject_class, :subject_id, :role_id, :conditions
5
5
  belongs_to :role
6
+
7
+ # Load all the permissions for all the roles
8
+ # DB intensive, should run only once!
9
+ def self.load_all
10
+ permissions = {}
11
+
12
+ # Get guest permissions
13
+ permissions[:guest] = Citygate::Permission.find_all_by_role_id(nil)
14
+
15
+ # Get everyother role permissions
16
+ roles = Citygate::Role.select [:id, :name]
17
+ roles.each do |role|
18
+ permissions[role.name.underscore.to_sym] = Citygate::Permission.find_all_by_role_id(role.id)
19
+ end
20
+
21
+ return permissions
22
+ end
6
23
  end
7
24
  end
@@ -50,9 +50,14 @@ module Citygate
50
50
  # Get the user's full name (the concatenation of his first and last names)
51
51
  # @return [String] the user's full name
52
52
  def full_name
53
- "#{self.first_name} #{self.last_name}".strip
53
+ name = "#{self.first_name} #{self.last_name}".strip
54
+ (name.blank?) ? nil : name
54
55
  end
55
56
 
57
+ # Alias for name_or_email
58
+ def to_s
59
+ self.name_or_email
60
+ end
56
61
 
57
62
  protected
58
63
 
@@ -0,0 +1,22 @@
1
+ <%= form_for @user, :url => admin_user_path(@user), :method => :put, :html => { :id => dom_id(@user, :edit) } do |f| %>
2
+ <%#= devise_error_messages! %>
3
+
4
+ <div class="field">
5
+ <%= f.label :first_name %>
6
+ <%= f.text_field :first_name %>
7
+ </div>
8
+
9
+ <div class="field">
10
+ <%= f.label :last_name %>
11
+ <%= f.text_field :last_name %>
12
+ </div>
13
+
14
+ <div class="field">
15
+ <%= f.label :email %>
16
+ <%= f.email_field :email %>
17
+ </div>
18
+
19
+ <div class="actions">
20
+ <%= f.submit t('admin.users.edit.update_link') %>
21
+ </div>
22
+ <% end %>
@@ -0,0 +1,3 @@
1
+ <%= form_for @role, url: citygate.home_role_change_path do |f| %>
2
+ <%= select "role", "id", Citygate::Role.all.collect {|r| [r.name, r.id]} %>
3
+ <% end %>
@@ -1,5 +1,3 @@
1
- <header>
2
- <h1>Welcome to CityGate!</h1>
1
+ <%= role_changer %>
3
2
 
4
- <%= render 'citygate/shared/navigation' %>
5
- </header>
3
+ <%= citygate_nav_links %>
@@ -1,20 +1,19 @@
1
1
  <nav>
2
2
  <ul>
3
3
  <% if user_signed_in? %>
4
- <li><%= link_to t('navigation.links.profile'), profile_path %></li>
5
- <li><%= link_to t('navigation.links.edit'), edit_user_registration_path %></li>
6
- <li><%= link_to t('navigation.links.log_out'), destroy_user_session_path, :method => 'delete' %></li>
4
+ <% if can?(:manage, Citygate::User) and !params[:controller]["admin"] %>
5
+ <li><i class='icon-cog'></i><%= link_to t('navigation.links.admin'), citygate.admin_users_path %></li>
6
+ <% end %>
7
+
8
+ <li><i class='icon-user'></i><%= link_to t('navigation.links.profile'), citygate.profile_path %></li>
9
+ <li><i class='icon-unlock'></i><%= link_to t('navigation.links.log_out'), citygate.destroy_user_session_path, method: 'delete' %></li>
7
10
  <% else %>
8
- <li><%= link_to t('navigation.links.log_in'), new_user_session_path %></li>
9
- <li><%= link_to t('navigation.links.sign_up'), new_user_registration_path %></li>
11
+ <li><%= link_to t('navigation.links.log_in'), citygate.new_user_session_path %></li>
12
+ <li><%= link_to t('navigation.links.sign_up'), citygate.new_user_registration_path %></li>
10
13
 
11
14
  <% Citygate::User.omniauth_providers.each do |provider| %>
12
- <li><%= link_to t('navigation.links.omniauth', provider: provider.to_s.titleize), omniauth_authorize_path(Citygate::User.new, provider), :id => "#{provider.to_s}" %></li>
15
+ <li><%= link_to t('navigation.links.omniauth', provider: provider.to_s.titleize), "/users/auth/#{provider.to_s}", :id => "#{provider.to_s}" %></li>
13
16
  <% end -%>
14
17
  <% end %>
15
-
16
- <% if can?(:manage, Citygate::User) and !params[:controller]["admin"] %>
17
- <li><%= link_to t('navigation.links.admin'), admin_users_path %></li>
18
- <% end %>
19
18
  </ul>
20
19
  </nav>
@@ -14,3 +14,5 @@
14
14
  </div>
15
15
  <% end %>
16
16
  </div>
17
+
18
+ <%= link_to t('navigation.links.edit'), citygate.edit_user_registration_path %>
@@ -6,15 +6,15 @@
6
6
  <%= csrf_meta_tags %>
7
7
  <%= yield :head %>
8
8
  </head>
9
- <body data-pjax-container>
9
+ <body>
10
10
  <%= render 'citygate/shared/navigation' %>
11
11
 
12
12
  <% flash.each do |name, msg| %>
13
13
  <%= content_tag :div, msg, :id => "flash_#{name}" if msg.is_a?(String) %>
14
14
  <% end %>
15
15
 
16
- <div id="container" class="container">
16
+ <div id="main">
17
17
  <%= yield %>
18
- </div>
18
+ </div> <!-- /main -->
19
19
  </body>
20
20
  </html>
@@ -1 +1,2 @@
1
- ACCOUNTS = YAML.load_file("#{Citygate.root}/config/accounts.yml") unless Rails.env.test?
1
+ file_name = "#{Rails.root}/config/accounts.yml"
2
+ ACCOUNTS = YAML.load_file(file_name) unless Rails.env.test? or not File.exist?(file_name)
@@ -205,7 +205,7 @@ Devise.setup do |config|
205
205
  # Add a new OmniAuth provider. Check the wiki for more information on setting
206
206
  # up on your models and hooks.
207
207
  # config.omniauth :github, 'APP_ID', 'APP_SECRET', :scope => 'user,public_repo'
208
- unless Rails.env.test?
208
+ if not Rails.env.test? and (defined? ACCOUNTS and ACCOUNTS['facebook'])
209
209
  config.omniauth :facebook, ACCOUNTS['facebook']['app_id'], ACCOUNTS['facebook']['app_secret'],
210
210
  { :scope => 'email, offline_access' }
211
211
 
@@ -0,0 +1,6 @@
1
+ en:
2
+ admin:
3
+ users:
4
+ update:
5
+ success: "User updated successfully"
6
+ error: "Error updating user"
@@ -5,6 +5,8 @@ Citygate::Engine.routes.draw do
5
5
 
6
6
  match '/confirm/:confirmation_token', :to => "devise/confirmations#show", :as => "user_confirm", :only_path => false
7
7
 
8
+ match "/home/role_change", :to => "home#role_change", :via => :post
9
+
8
10
  devise_for :users,
9
11
  :controllers => {
10
12
  :omniauth_callbacks => "citygate/users/omniauth_callbacks"
@@ -0,0 +1,5 @@
1
+ class AddConditionsToPermissions < ActiveRecord::Migration
2
+ def change
3
+ add_column :citygate_permissions, :conditions, :string
4
+ end
5
+ end
@@ -16,7 +16,7 @@ roles.each do |attributes|
16
16
  Citygate::Role.find_or_initialize_by_name(attributes[:name]).save!
17
17
  end
18
18
 
19
- puts 'Creating permission for citygate...'
19
+ puts 'Creating permissions for citygate...'
20
20
  permissions = [
21
21
  # Guest
22
22
  {:action => "index", :subject_class => "home", :role_id => nil },
@@ -2,16 +2,19 @@
2
2
  class Ability
3
3
  include CanCan::Ability
4
4
 
5
- # Defines the permissions for a user wich is not logged in or if it is,
5
+ # Defines the permissions for a user wich is not logged in or if it is,
6
6
  # calls the corresponding method to its role
7
7
  # @param [Citygate::User] user the current user
8
8
  def initialize(user)
9
+ # This runs only once
10
+ @@permissions ||= Citygate::Permission.load_all
11
+
9
12
  @user = user || Citygate::User.new # guest user (not logged in)
10
-
11
- Citygate::Permission.find_all_by_role_id(nil).each do |permission|
13
+
14
+ @@permissions[:guest].each do |permission|
12
15
  handle_permission permission
13
16
  end
14
-
17
+
15
18
  if @user.role
16
19
  send(@user.role.name.downcase)
17
20
  end
@@ -19,35 +22,52 @@ class Ability
19
22
 
20
23
  # Defines the permissions on a user with the role of member
21
24
  def member
22
- Citygate::Permission.find_all_by_role_id(1).each do |permission|
25
+ @@permissions[:member].each do |permission|
23
26
  handle_permission permission
24
27
  end
25
28
  end
26
29
 
27
- # Defines the permissions on a user with the role of admin, which inherits from member
30
+ # Defines the permissions on a user with the role of admin
31
+ # As this is a super admin that can do anything, it does not need
32
+ # to inherit from member
28
33
  def admin
29
- member
30
- Citygate::Permission.find_all_by_role_id(2).each do |permission|
34
+ #member
35
+ @@permissions[:admin].each do |permission|
31
36
  handle_permission permission
32
37
  end
33
38
  end
34
-
39
+
35
40
  protected
36
-
37
- def handle_permission(permission)
38
- if permission.subject_id.nil?
39
- begin
40
- can permission.action.to_sym, permission.subject_class.constantize
41
- rescue
42
- can permission.action.to_sym, permission.subject_class.to_sym
41
+
42
+ def handle_permission(permission)
43
+ if permission.subject_id.nil?
44
+ begin
45
+ can permission.action.to_sym, permission.subject_class.constantize, generate_conditions_hash(permission)
46
+ rescue
47
+ can permission.action.to_sym, permission.subject_class.to_sym, generate_conditions_hash(permission)
48
+ end
49
+ else
50
+ begin
51
+ can permission.action.to_sym, permission.subject_class.constantize, generate_conditions_hash(permission)
52
+ rescue
53
+ can permission.action.to_sym, permission.subject_class.to_sym, generate_conditions_hash(permission)
54
+ end
43
55
  end
44
- else
45
- begin
46
- can permission.action.to_sym, permission.subject_class.constantize, :id => permission.subject_id
47
- rescue
48
- can permission.action.to_sym, permission.subject_class.to_sym, :id => permission.subject_id
56
+ end
57
+
58
+ def generate_conditions_hash(permission)
59
+ user = @user
60
+ conditions_hash = {}
61
+ if permission.conditions
62
+ permission.conditions.split(",").each do |condition|
63
+ key,value = condition.split("#")
64
+ conditions_hash[key.to_sym] = instance_eval value
65
+ end
66
+
67
+ conditions_hash.merge({id: permission.subject_id}) if permission.subject_id
49
68
  end
69
+
70
+ return conditions_hash
50
71
  end
51
- end
52
72
 
53
73
  end