authority_engine 0.1.5

Sign up to get free protection for your applications and to get access to all the features.
data/README ADDED
File without changes
@@ -0,0 +1,53 @@
1
+ == Overview
2
+
3
+ One of the things I was most looking forward to in rails 3 was the plugin / engine architecture. Recently, I sat down to figure out how to create my first engine and package it up as a gem and it took me awhile of time just to get the structure of the engine setup. It's missing a lot of the "rails" you get in a normal rails app.
4
+
5
+ In it's simplest form engines are quite easy, however for a full-featured engine (such as creating a forum) there are a lot of extras that you're going to want. These are the things I spent time figuring out that I've packaged up into an easy starting point:
6
+
7
+ * Namespacing models & controllers so they don't collide with those in the main app
8
+ * Creating a global layout within your engine that gets nested within your application layout
9
+ * Generating migrations from your engine
10
+ * Creating an "acts_as_[plugin]" declaration for use inside your main app's models
11
+ * Easy plugin configuration file editable from main app directory
12
+ * Rake tasks within engine
13
+ * Writing tests for models complete with fixtures
14
+ * Serving static assets within engine
15
+ * Packaging and distributing as a gem
16
+ * Code is here - I've created an engine stub that has all the things setup for you already. I want to see a lot more rails 3 engines get created, I hope this helps! I'd love to hear feedback from you if you try it out.
17
+
18
+ Here’s how you get ready to create your first gem by using this starting point:
19
+
20
+ * git clone git@github.com:krschacht/rails_3_engine_demo.git
21
+ * cd rails_3_engine_demo
22
+ * [edit test/database.yml]
23
+ * rake test (this will initialize your test database and run the basic test suite)
24
+
25
+ Now, create a plain rails app and set it up to use your engine. FYI: even though the engine's directory is 'rails_3_engine_demo', internally the engine is named 'authority'
26
+
27
+ * cd .. [ this is to take you outside the 'rails_3_engine_demo' directory that was created above' ]
28
+ * rails new demo_app_to_use_gem -d mysql
29
+ * cd demo_app_to_use_gem
30
+ * [edit config/database.yml]
31
+ * [edit Gemfile, add line: ] gem ‘authority’, :path => "../rails_3_engine_demo"
32
+ * rails generate authority
33
+ * [examine config/initializers/authority.rb to see basic config parameters]
34
+ * rake db:create
35
+ * rake db:migrate (one of the migrations that you'll see run came from the engine)
36
+
37
+ You have now setup a empty rails app that utilizes your engine. To test out the functionality, startup the demo app’s webserver:
38
+
39
+ * rails server
40
+ * Then visit: http://localhost:3000/authority (this is a controller included within the engine)
41
+ * rake authority:reports (this is a a rake task that is included inside the engine)
42
+
43
+ Lastly, let's package up your engine as a real gem. You’ll need Jeweler installed for this:
44
+
45
+ * cd rails_3_engine_demo
46
+ * sudo gem install jeweler
47
+ * rake gemspec
48
+ * rake build
49
+ * rake install (you have now installed your engine as a gem locally)
50
+ * [ At this point if you wanted your demo app to use your installed gem, edit the Gemfile in your demo app and remove the 'path' option from your gem line. It should look like this: ] gem ‘authority’
51
+ * rake gemcutter:release (this pushes your gem up to Gemcutter, a public gem repository)
52
+
53
+ Now you’re ready to start customizing this engine for your own purposes. Do a global find in your engine directory and replace every instance of "authority" and "authority" with your engine name (be sure to preserve capitalization). Likewise, rename every directory and file that’s named "authority" with your engine name. I should really automate this but I haven’t figured out how to create a rake task that I can run from within the engine directory itself.
@@ -0,0 +1,32 @@
1
+ class AuthorityController < ActionController::Base
2
+
3
+ unloadable
4
+
5
+ def ensure_super_admin!
6
+ if controller_name != "sessions"
7
+ super_user_role = Role.find(1)
8
+ if !current_user.roles.include? super_user_role
9
+ raise 'Unauthorized Action'
10
+ end
11
+ end
12
+ end
13
+
14
+ def ensure_admin!
15
+ if controller_name != "sessions"
16
+ admin_user_role = Role.find_by_name(ADMIN_ROLE_NAME)
17
+ if !current_user.roles.include? admin_user_role
18
+ raise 'Unauthorized Action'
19
+ end
20
+ end
21
+ end
22
+
23
+ def ensure_accessible!
24
+ if controller_name != "sessions"
25
+ accessible_user_role = Role.find_by_name(ACCESSIBLE_ROLE_NAME)
26
+ if !current_user.roles.include? accessible_user_role
27
+ raise 'Unauthorized Action'
28
+ end
29
+ end
30
+ end
31
+
32
+ end
@@ -0,0 +1,5 @@
1
+ class Role < ActiveRecord::Base
2
+ establish_connection :authority
3
+ has_many :user_roles
4
+ has_many :users, :through => :user_roles
5
+ end
@@ -0,0 +1,19 @@
1
+ class User < ActiveRecord::Base
2
+ establish_connection :authority
3
+ # Include default devise modules. Others available are:
4
+ # :token_authenticatable, :confirmable, :lockable and :timeoutable
5
+ devise :database_authenticatable, :registerable,
6
+ :recoverable, :rememberable, :trackable, :validatable, :invitable
7
+
8
+ # Setup accessible (or protected) attributes for your model
9
+ attr_accessible :email, :password, :password_confirmation, :remember_me
10
+
11
+ has_many :user_roles, :dependent => :destroy
12
+ has_many :roles, :through => :user_roles
13
+
14
+ def admin?
15
+ admin_user_role = Role.find_by_name(ADMIN_ROLE_NAME)
16
+ current_user.roles.include? admin_user_role
17
+ end
18
+
19
+ end
@@ -0,0 +1,8 @@
1
+ class UserRole < ActiveRecord::Base
2
+ establish_connection :authority
3
+ belongs_to :user
4
+ belongs_to :role
5
+
6
+ validates_presence_of :user_id
7
+ validates_presence_of :role_id
8
+ end
@@ -0,0 +1,6 @@
1
+ Rails.application.routes.draw do |map|
2
+
3
+ mount_at = Authority::Engine.config.mount_at
4
+
5
+ devise_for :user
6
+ end
@@ -0,0 +1,3 @@
1
+ module ApplicationHelper
2
+
3
+ end
@@ -0,0 +1,148 @@
1
+ module AuthorityEngine
2
+ require 'engine' if defined?(Rails) && Rails::VERSION::MAJOR == 3
3
+ require 'devise'
4
+ require 'haml'
5
+ require 'devise_invitable'
6
+ Devise.setup do |config|
7
+ # ==> Mailer Configuration
8
+ # Configure the e-mail address which will be shown in DeviseMailer.
9
+ config.mailer_sender = "website@ahfmr.ab.ca"
10
+
11
+ # Configure the class responsible to send e-mails.
12
+ # config.mailer = "Devise::Mailer"
13
+
14
+ config.invite_for = 2.weeks
15
+
16
+ # ==> ORM configuration
17
+ # Load and configure the ORM. Supports :active_record (default) and
18
+ # :mongoid (bson_ext recommended) by default. Other ORMs may be
19
+ # available as additional gems.
20
+ require 'devise/orm/active_record'
21
+
22
+ # ==> Configuration for any authentication mechanism
23
+ # Configure which keys are used when authenticating an user. By default is
24
+ # just :email. You can configure it to use [:username, :subdomain], so for
25
+ # authenticating an user, both parameters are required. Remember that those
26
+ # parameters are used only when authenticating and not when retrieving from
27
+ # session. If you need permissions, you should implement that in a before filter.
28
+ # config.authentication_keys = [ :email ]
29
+
30
+ # Tell if authentication through request.params is enabled. True by default.
31
+ # config.params_authenticatable = true
32
+
33
+ # Tell if authentication through HTTP Basic Auth is enabled. True by default.
34
+ # config.http_authenticatable = true
35
+
36
+ # Set this to true to use Basic Auth for AJAX requests. True by default.
37
+ # config.http_authenticatable_on_xhr = true
38
+
39
+ # The realm used in Http Basic Authentication
40
+ # config.http_authentication_realm = "Application"
41
+
42
+ # ==> Configuration for :database_authenticatable
43
+ # For bcrypt, this is the cost for hashing the password and defaults to 10. If
44
+ # using other encryptors, it sets how many times you want the password re-encrypted.
45
+ config.stretches = 10
46
+
47
+ # Define which will be the encryption algorithm. Devise also supports encryptors
48
+ # from others authentication tools as :clearance_sha1, :authlogic_sha512 (then
49
+ # you should set stretches above to 20 for default behavior) and :restful_authentication_sha1
50
+ # (then you should set stretches to 10, and copy REST_AUTH_SITE_KEY to pepper)
51
+ # config.encryptor = :bcrypt
52
+
53
+ # Setup a pepper to generate the encrypted password.
54
+ config.pepper = "32f1d04431dbac7d3d8fb42d4a3f000342c745bd774e03d4c180a627f5074412c55a02cedca0291047dd8f3db933000a5cc4b12f35686eec626a6da092ab0b07"
55
+
56
+ # ==> Configuration for :confirmable
57
+ # The time you want to give your user to confirm his account. During this time
58
+ # he will be able to access your application without confirming. Default is nil.
59
+ # When confirm_within is zero, the user won't be able to sign in without confirming.
60
+ # You can use this to let your user access some features of your application
61
+ # without confirming the account, but blocking it after a certain period
62
+ # (ie 2 days).
63
+ # config.confirm_within = 2.days
64
+
65
+ # ==> Configuration for :rememberable
66
+ # The time the user will be remembered without asking for credentials again.
67
+ # config.remember_for = 2.weeks
68
+
69
+ # If true, a valid remember token can be re-used between multiple browsers.
70
+ # config.remember_across_browsers = true
71
+
72
+ # If true, extends the user's remember period when remembered via cookie.
73
+ # config.extend_remember_period = false
74
+
75
+ # ==> Configuration for :validatable
76
+ # Range for password length
77
+ # config.password_length = 6..20
78
+
79
+ # Regex to use to validate the email address
80
+ # config.email_regexp = /^([\w\.%\+\-]+)@([\w\-]+\.)+([\w]{2,})$/i
81
+
82
+ # ==> Configuration for :timeoutable
83
+ # The time you want to timeout the user session without activity. After this
84
+ # time the user will be asked for credentials again.
85
+ # config.timeout_in = 10.minutes
86
+
87
+ # ==> Configuration for :lockable
88
+ # Defines which strategy will be used to lock an account.
89
+ # :failed_attempts = Locks an account after a number of failed attempts to sign in.
90
+ # :none = No lock strategy. You should handle locking by yourself.
91
+ # config.lock_strategy = :failed_attempts
92
+
93
+ # Defines which strategy will be used to unlock an account.
94
+ # :email = Sends an unlock link to the user email
95
+ # :time = Re-enables login after a certain amount of time (see :unlock_in below)
96
+ # :both = Enables both strategies
97
+ # :none = No unlock strategy. You should handle unlocking by yourself.
98
+ # config.unlock_strategy = :both
99
+
100
+ # Number of authentication tries before locking an account if lock_strategy
101
+ # is failed attempts.
102
+ # config.maximum_attempts = 20
103
+
104
+ # Time interval to unlock the account if :time is enabled as unlock_strategy.
105
+ # config.unlock_in = 1.hour
106
+
107
+ # ==> Configuration for :token_authenticatable
108
+ # Defines name of the authentication token params key
109
+ # config.token_authentication_key = :auth_token
110
+
111
+ # ==> Scopes configuration
112
+ # Turn scoped views on. Before rendering "sessions/new", it will first check for
113
+ # "users/sessions/new". It's turned off by default because it's slower if you
114
+ # are using only default views.
115
+ # config.scoped_views = true
116
+
117
+ # Configure the default scope given to Warden. By default it's the first
118
+ # devise role declared in your routes.
119
+ # config.default_scope = :user
120
+
121
+ # Configure sign_out behavior.
122
+ # By default sign_out is scoped (i.e. /users/sign_out affects only :user scope).
123
+ # In case of sign_out_all_scopes set to true any logout action will sign out all active scopes.
124
+ # config.sign_out_all_scopes = false
125
+
126
+ # ==> Navigation configuration
127
+ # Lists the formats that should be treated as navigational. Formats like
128
+ # :html, should redirect to the sign in page when the user does not have
129
+ # access, but formats like :xml or :json, should return 401.
130
+ # If you have any extra navigational formats, like :iphone or :mobile, you
131
+ # should add them to the navigational formats lists. Default is [:html]
132
+ # config.navigational_formats = [:html, :iphone]
133
+
134
+ # ==> Warden configuration
135
+ # If you want to use other strategies, that are not (yet) supported by Devise,
136
+ # you can configure them inside the config.warden block. The example below
137
+ # allows you to setup OAuth, using http://github.com/roman/warden_oauth
138
+ #
139
+ # config.warden do |manager|
140
+ # manager.oauth(:twitter) do |twitter|
141
+ # twitter.consumer_secret = <YOUR CONSUMER SECRET>
142
+ # twitter.consumer_key = <YOUR CONSUMER KEY>
143
+ # twitter.options :site => 'http://twitter.com'
144
+ # end
145
+ # manager.default_strategies(:scope => :user).unshift :twitter_oauth
146
+ # end
147
+ end
148
+ end
@@ -0,0 +1,24 @@
1
+ require 'authority_engine'
2
+ require 'rails'
3
+ require 'action_controller'
4
+ require 'application_helper'
5
+
6
+ module Authority
7
+ class Engine < Rails::Engine
8
+
9
+ # Config defaults
10
+ config.mount_at = '/'
11
+
12
+ # Check the gem config
13
+ initializer "check config" do |app|
14
+
15
+ # make sure mount_at ends with trailing slash
16
+ config.mount_at += '/' unless config.mount_at.last == '/'
17
+ end
18
+
19
+ initializer "static assets" do |app|
20
+ app.middleware.use ::ActionDispatch::Static, "#{root}/public"
21
+ end
22
+
23
+ end
24
+ end
@@ -0,0 +1,56 @@
1
+ ENV["RAILS_ENV"] = "test"
2
+
3
+ require 'test/unit'
4
+ require 'rubygems'
5
+ require 'yaml'
6
+ require 'active_record'
7
+ require 'mysql'
8
+
9
+ require 'app/models/authority/widget.rb'
10
+
11
+ def authority_widget( fixture_name )
12
+ id = @@fixtures['authority_widget'][ fixture_name.to_s ][ 'id' ]
13
+ authority::Widget.find( id )
14
+ end
15
+
16
+ def load_schema
17
+ config = YAML::load( IO.read( File.dirname(__FILE__) + '/database.yml') )
18
+
19
+ # Manually initialize the database
20
+ conn = Mysql.real_connect( config['mysql']['host'], config['mysql']['username'], config['mysql']['password'] )
21
+ conn.query( "CREATE DATABASE IF NOT EXISTS #{config['mysql']['database']}" )
22
+
23
+ ActiveRecord::Base.establish_connection( config['mysql'] )
24
+ ActiveRecord::Base.connection()
25
+
26
+ load(File.dirname(__FILE__) + "/../" +
27
+ "lib/rails/generators/authority/templates/schema.rb")
28
+
29
+ @@fixtures = {}
30
+
31
+ load_fixture( 'authority_widget' )
32
+ end
33
+
34
+ def load_fixture( table )
35
+ @@fixtures[ table ] = {}
36
+ fixture = YAML::load( IO.read( File.dirname(__FILE__) + "/fixtures/#{table}.yml") )
37
+ @@fixtures[ table ] = fixture
38
+
39
+ klass = class_eval table.titleize.gsub(/ /, '::')
40
+
41
+ fixture.each do |record_name, record|
42
+ record.each do |column, value|
43
+ if ( match = column.match(/(.*)_id/) )
44
+ fixture_reference = "authority_" + match[1].pluralize
45
+ if value.is_a? Symbol
46
+ r = class_eval "#{fixture_reference}( '#{value}' )"
47
+ record[ column ] = r.id
48
+ end
49
+ end
50
+ end
51
+
52
+ r = klass.create( record )
53
+ @@fixtures[ table ][ record_name ][ 'id' ] = r.id
54
+ end
55
+
56
+ end
@@ -0,0 +1,11 @@
1
+ require 'test_helper'
2
+
3
+ class WidgetTest < Test::Unit::TestCase
4
+ load_schema
5
+
6
+ def test_fixtures_are_working
7
+ assert_equal authority_widget(:first).title, "This is the title"
8
+ end
9
+
10
+
11
+ end
metadata ADDED
@@ -0,0 +1,135 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: authority_engine
3
+ version: !ruby/object:Gem::Version
4
+ hash: 17
5
+ prerelease: false
6
+ segments:
7
+ - 0
8
+ - 1
9
+ - 5
10
+ version: 0.1.5
11
+ platform: ruby
12
+ authors:
13
+ - Jordan Yeo
14
+ autorequire:
15
+ bindir: bin
16
+ cert_chain: []
17
+
18
+ date: 2010-11-12 00:00:00 -07:00
19
+ default_executable:
20
+ dependencies:
21
+ - !ruby/object:Gem::Dependency
22
+ name: aihs_devise
23
+ prerelease: false
24
+ requirement: &id001 !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ">="
28
+ - !ruby/object:Gem::Version
29
+ hash: 3
30
+ segments:
31
+ - 0
32
+ version: "0"
33
+ type: :runtime
34
+ version_requirements: *id001
35
+ - !ruby/object:Gem::Dependency
36
+ name: aihs_devise_invitable
37
+ prerelease: false
38
+ requirement: &id002 !ruby/object:Gem::Requirement
39
+ none: false
40
+ requirements:
41
+ - - ">="
42
+ - !ruby/object:Gem::Version
43
+ hash: 3
44
+ segments:
45
+ - 0
46
+ version: "0"
47
+ type: :runtime
48
+ version_requirements: *id002
49
+ - !ruby/object:Gem::Dependency
50
+ name: haml
51
+ prerelease: false
52
+ requirement: &id003 !ruby/object:Gem::Requirement
53
+ none: false
54
+ requirements:
55
+ - - ">="
56
+ - !ruby/object:Gem::Version
57
+ hash: 3
58
+ segments:
59
+ - 0
60
+ version: "0"
61
+ type: :runtime
62
+ version_requirements: *id003
63
+ - !ruby/object:Gem::Dependency
64
+ name: formtastic
65
+ prerelease: false
66
+ requirement: &id004 !ruby/object:Gem::Requirement
67
+ none: false
68
+ requirements:
69
+ - - ">="
70
+ - !ruby/object:Gem::Version
71
+ hash: 3
72
+ segments:
73
+ - 0
74
+ version: "0"
75
+ type: :runtime
76
+ version_requirements: *id004
77
+ description:
78
+ email: jordan.yeo@albertainnovates.ca
79
+ executables: []
80
+
81
+ extensions: []
82
+
83
+ extra_rdoc_files:
84
+ - README
85
+ - README.rdoc
86
+ files:
87
+ - app/controllers/authority_controller.rb
88
+ - app/models/role.rb
89
+ - app/models/user.rb
90
+ - app/models/user_role.rb
91
+ - config/routes.rb
92
+ - lib/application_helper.rb
93
+ - lib/authority_engine.rb
94
+ - lib/engine.rb
95
+ - README
96
+ - README.rdoc
97
+ - test/test_helper.rb
98
+ - test/unit/widget_test.rb
99
+ has_rdoc: true
100
+ homepage:
101
+ licenses: []
102
+
103
+ post_install_message:
104
+ rdoc_options:
105
+ - --charset=UTF-8
106
+ require_paths:
107
+ - lib
108
+ required_ruby_version: !ruby/object:Gem::Requirement
109
+ none: false
110
+ requirements:
111
+ - - ">="
112
+ - !ruby/object:Gem::Version
113
+ hash: 3
114
+ segments:
115
+ - 0
116
+ version: "0"
117
+ required_rubygems_version: !ruby/object:Gem::Requirement
118
+ none: false
119
+ requirements:
120
+ - - ">="
121
+ - !ruby/object:Gem::Version
122
+ hash: 3
123
+ segments:
124
+ - 0
125
+ version: "0"
126
+ requirements: []
127
+
128
+ rubyforge_project:
129
+ rubygems_version: 1.3.7
130
+ signing_key:
131
+ specification_version: 3
132
+ summary: Authentication engine for AIHS
133
+ test_files:
134
+ - test/test_helper.rb
135
+ - test/unit/widget_test.rb