cadenero 0.0.1

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.
Files changed (38) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.md +79 -0
  3. data/Rakefile +44 -0
  4. data/app/assets/javascripts/cadenero/application.js +15 -0
  5. data/app/assets/javascripts/cadenero/v1/accounts.js +2 -0
  6. data/app/assets/javascripts/cadenero/v1/users.js +2 -0
  7. data/app/assets/stylesheets/cadenero/application.css +13 -0
  8. data/app/assets/stylesheets/cadenero/v1/accounts.css +4 -0
  9. data/app/assets/stylesheets/cadenero/v1/users.css +4 -0
  10. data/app/controllers/cadenero/application_controller.rb +8 -0
  11. data/app/controllers/cadenero/v1/account/dashboard_controller.rb +11 -0
  12. data/app/controllers/cadenero/v1/account/users_controller.rb +27 -0
  13. data/app/controllers/cadenero/v1/accounts_controller.rb +23 -0
  14. data/app/controllers/cadenero/v1/sessions_controller.rb +13 -0
  15. data/app/extenders/controllers/application_controller_decorator.rb +51 -0
  16. data/app/helpers/cadenero/application_helper.rb +4 -0
  17. data/app/helpers/cadenero/v1/accounts_helper.rb +4 -0
  18. data/app/helpers/cadenero/v1/users_helper.rb +4 -0
  19. data/app/models/cadenero/member.rb +7 -0
  20. data/app/models/cadenero/user.rb +8 -0
  21. data/app/models/cadenero/v1/account.rb +60 -0
  22. data/app/serializers/cadenero/account_serializer.rb +9 -0
  23. data/app/serializers/cadenero/user_serializer.rb +8 -0
  24. data/config/initializers/apartment.rb +10 -0
  25. data/config/initializers/warden.rb +3 -0
  26. data/config/initializers/warden/strategies/password.rb +23 -0
  27. data/config/routes.rb +24 -0
  28. data/db/migrate/20130612061604_create_cadenero_v1_accounts.rb +12 -0
  29. data/db/migrate/20130612064652_create_cadenero_v1_users.rb +10 -0
  30. data/db/migrate/20130612073709_create_cadenero_v1_members.rb +12 -0
  31. data/db/migrate/20130612093908_add_authentication_token_to_accounts.rb +6 -0
  32. data/lib/cadenero.rb +29 -0
  33. data/lib/cadenero/active_record_extensions.rb +7 -0
  34. data/lib/cadenero/constraints/subdomain_required.rb +9 -0
  35. data/lib/cadenero/engine.rb +26 -0
  36. data/lib/cadenero/version.rb +3 -0
  37. data/lib/tasks/cadenero_tasks.rake +4 -0
  38. metadata +292 -0
@@ -0,0 +1,20 @@
1
+ Copyright 2013 YOURNAME
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.
@@ -0,0 +1,79 @@
1
+ ![Cadenero Logo](https://raw.github.com/AgilTec/cadenero/master/cadenero.logo.png)
2
+ By [![Agiltec Logo](https://launchrock-assets.s3.amazonaws.com/logo-files/GpujzvLXPPqzAcz.png)](http://agiltec.github.io/).
3
+
4
+ [![Gem Version](https://fury-badge.herokuapp.com/rb/cadenero.png)](http://badge.fury.io/rb/cadenero)
5
+ [![Build Status](https://travis-ci.org/AgilTec/cadenero.png?branch=master)](https://travis-ci.org/AgilTec/cadenero)
6
+ [![Code Climate](https://codeclimate.com/github/AgilTec/cadenero.png)](https://codeclimate.com/github/AgilTec/cadenero)
7
+ [![Coverage Status](https://coveralls.io/repos/AgilTec/cadenero/badge.png?branch=master)](https://coveralls.io/r/AgilTec/cadenero?branch=master)
8
+ [![Dependency Status](https://gemnasium.com/AgilTec/cadenero.png)](https://gemnasium.com/AgilTec/cadenero)
9
+
10
+ Authentication Engine for Rails.API multitenant RESTful APIs based on Warden. It:
11
+ * Is Racked based
12
+ * Use token authentication as strategy for the API
13
+ * Is RESTful API
14
+ * Allows you to have multiple roles (or models/scopes) signed in at the same time
15
+
16
+ ## Information
17
+
18
+ ### Why Cadenero?
19
+ **"Cadenero"** is the spanish word for ["Bouncer (doorman)"](http://en.wikipedia.org/wiki/Bouncer_(doorman\)). The main function of **Cadenero** is to be a resource for authenticating consumers of the services that the API provides. As the real bouncers, **Cadenero** aims to provide security, check authorized access, to refuse entry for intoxication, aggressive behavior or non-compliance with statutory or establishment rules.
20
+
21
+ ### Access Points
22
+ **Cadenero** creates the following versioned routes for exposing the authentication RESTful API
23
+
24
+ ```
25
+ v1_users_new GET /v1/users/new(.:format) cadenero/v1/users#new
26
+ v1_root /v1(.:format) cadenero/v1/account/dashboard#index
27
+ v1_sign_in GET /v1/sign_in(.:format) cadenero/v1/account/sessions#new
28
+ v1_sessions POST /v1/sign_in(.:format) cadenero/v1/account/sessions#create
29
+ v1_user_sign_up GET /v1/sign_up(.:format) cadenero/v1/account/users#new
30
+ v1_user_sign_up POST /v1/sign_up(.:format) cadenero/v1/account/users#create
31
+ v1_sign_up GET /v1/sign_up(.:format) cadenero/v1/accounts#new
32
+ v1_accounts POST /v1/accounts(.:format) cadenero/v1/accounts#create
33
+ v1_root /v1(.:format) cadenero/v1/dashboard#index
34
+ ```
35
+
36
+ ### The Cadenero Task List
37
+ - [x] Specs for the code 100% Coverage using BDD with [Rspec](https://github.com/rspec/rspec) and [Capybara](https://github.com/jnicklas/capybara)
38
+ - [ ] Documatation for all the code
39
+ - [ ] Examples of use and demo
40
+
41
+ ### Bug reports
42
+
43
+ If you discover a problem with **Cadenero**, we would like to know about it. However, we ask that you please review these guidelines before submitting a bug report:
44
+
45
+ https://github.com/agiltec/cadenero/wiki/Bug-reports
46
+
47
+ If you found a security bug, do *NOT* use the GitHub issue tracker. Send an email to the maintainers listed at the bottom of the README please.
48
+
49
+ ### Contributing
50
+
51
+ We hope that you will consider contributing to **Cadenero**. Please read this short overview for some information about how to get started:
52
+
53
+ https://github.com/agiltec/devise/cadenero/Contributing
54
+
55
+ You will usually want to write tests for your changes using BDD tools as RSpec, Rack::Test and Capybara. To run the test suite, go into **Cadenero**'s top-level directory and run "bundle install" and "rspec". For the tests to pass, you will need to have a Postgresql server running on your system.
56
+
57
+ ### Warden
58
+
59
+ **Cadenero** is based on Warden, which is a general Rack authentication framework created by Daniel Neighman. We encourage you to read more about Warden here: https://github.com/hassox/warden
60
+
61
+ ### Rails::API
62
+
63
+ **Cadenero** is a Rails::API Engine, Rails::API is a subset of a normal Rails application, created for applications that don't require all functionality that a complete Rails application provides. It is a bit more lightweight, and consequently a bit faster than a normal Rails application. The main example for its usage is in API applications only, where you usually don't need the entire Rails middleware stack nor template generation. Rails::API was created by Santiago Pastorino. We encourage you to read more about Rails::API here: https://github.com/rails-api/rails-api
64
+
65
+ ### Multitenancy with Rails And subscriptions too!
66
+ Parts of the code of **Cadenero** have been based on the excellent work of [Ryan Bigg](https://github.com/radar) in his book ["Multitenancy with Rails And subscriptions too!"](https://leanpub.com/multi-tenancy-rails) but modified to be use in a RESTful API
67
+
68
+ ### Maintainers
69
+
70
+ * Manuel Vidaurre (https://github.com/mvidaurre)
71
+
72
+ ## License
73
+
74
+ MIT License. Copyright 2013 AgilTec. http://agiltec.com.mx
75
+
76
+ You are not granted rights or licenses to the trademarks of the AgilTec, including without limitation the **Cadenero** name or logo.
77
+
78
+
79
+ This project rocks and uses MIT-LICENSE.
@@ -0,0 +1,44 @@
1
+ #!/usr/bin/env rake
2
+ begin
3
+ require 'bundler/setup'
4
+ rescue LoadError
5
+ puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
+ end
7
+ begin
8
+ require 'rdoc/task'
9
+ rescue LoadError
10
+ require 'rdoc/rdoc'
11
+ require 'rake/rdoctask'
12
+ RDoc::Task = Rake::RDocTask
13
+ end
14
+
15
+ RDoc::Task.new(:rdoc) do |rdoc|
16
+ rdoc.rdoc_dir = 'rdoc'
17
+ rdoc.title = 'Cadenero'
18
+ rdoc.options << '--line-numbers'
19
+ rdoc.rdoc_files.include('README.rdoc')
20
+ rdoc.rdoc_files.include('lib/**/*.rb')
21
+ end
22
+
23
+ APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
24
+ load 'rails/tasks/engine.rake'
25
+
26
+
27
+
28
+ Bundler::GemHelper.install_tasks
29
+
30
+ require 'rake/testtask'
31
+
32
+ Rake::TestTask.new(:test) do |t|
33
+ t.libs << 'lib'
34
+ t.libs << 'test'
35
+ t.pattern = 'test/**/*_test.rb'
36
+ t.verbose = false
37
+ end
38
+
39
+ desc 'run Rspec specs'
40
+ task :spec do
41
+ sh 'rspec spec'
42
+ end
43
+
44
+ task :default => :spec
@@ -0,0 +1,15 @@
1
+ // This is a manifest file that'll be compiled into application.js, which will include all the files
2
+ // listed below.
3
+ //
4
+ // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
5
+ // or vendor/assets/javascripts of plugins, if any, can be referenced here using a relative path.
6
+ //
7
+ // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
8
+ // the compiled file.
9
+ //
10
+ // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
11
+ // GO AFTER THE REQUIRES BELOW.
12
+ //
13
+ //= require jquery
14
+ //= require jquery_ujs
15
+ //= require_tree .
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,2 @@
1
+ // Place all the behaviors and hooks related to the matching controller here.
2
+ // All this logic will automatically be available in application.js.
@@ -0,0 +1,13 @@
1
+ /*
2
+ * This is a manifest file that'll be compiled into application.css, which will include all the files
3
+ * listed below.
4
+ *
5
+ * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
6
+ * or vendor/assets/stylesheets of plugins, if any, can be referenced here using a relative path.
7
+ *
8
+ * You're free to add application-wide styles to this file and they'll appear at the top of the
9
+ * compiled file, but it's generally better to create a new file per style scope.
10
+ *
11
+ *= require_self
12
+ *= require_tree .
13
+ */
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,4 @@
1
+ /*
2
+ Place all the styles related to the matching controller here.
3
+ They will automatically be included in application.css.
4
+ */
@@ -0,0 +1,8 @@
1
+ # == Cadenero::ApplicationController main application controller
2
+ #
3
+ # Inherates methods from the [::ApplicationController] extender
4
+ #
5
+ module Cadenero
6
+ class ApplicationController < ::ApplicationController
7
+ end
8
+ end
@@ -0,0 +1,11 @@
1
+ require_dependency "cadenero/application_controller"
2
+
3
+ module Cadenero
4
+ class V1::Account::DashboardController < Cadenero::ApplicationController
5
+ before_filter :authenticate_user!
6
+
7
+ def index
8
+
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,27 @@
1
+ # == Cadenero::Account::UsersController for creating the users associated to an account
2
+ #
3
+ # Inherates methods from the [::ApplicationController] extender
4
+ # @author Manuel Vidaurre @mvidaurre <manuel.vidaurre@agiltec.com.mx>
5
+
6
+ require_dependency "cadenero/application_controller"
7
+
8
+ module Cadenero
9
+ module V1
10
+ class Account::UsersController < Cadenero::ApplicationController
11
+ # Create a [Cadenero::User] based on the params sended by the client as a JSON with the user inrormation
12
+ #
13
+ # @example Posting the user data to be created in an account via the subdomain
14
+ # post "http://#{account.subdomain}.example.com/v1/sign_up",
15
+ # user: { email: "user@example.com", password: "password", password_confirmation: "password" }
16
+ #
17
+ # @return render JSON of [Cadenero::User] created and the status 201 Created: The request has been
18
+ # fulfilled and resulted in a new resource being created..
19
+ def create
20
+ account = Cadenero::V1::Account.where(subdomain: request.subdomain).first
21
+ @user = account.users.create(params[:user])
22
+ force_authentication!(@user)
23
+ render json: @user, status: 201
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,23 @@
1
+ require_dependency "cadenero/application_controller"
2
+
3
+ module Cadenero
4
+ module V1
5
+ class AccountsController < Cadenero::ApplicationController
6
+ def create
7
+ @account = Cadenero::V1::Account.create_with_owner(params[:account])
8
+ if @account.valid?
9
+ force_authentication!(@account.owner)
10
+ @account.create_schema
11
+ @account.ensure_authentication_token!
12
+ data = {
13
+ account_id: @account.id,
14
+ auth_token: @account.authentication_token
15
+ }
16
+ render json: data, status: 201
17
+ else
18
+ render json: {errors: @account.errors}, status: 422
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,13 @@
1
+ require_dependency "cadenero/application_controller"
2
+
3
+ module Cadenero::V1
4
+ class Account::SessionsController < Cadenero::ApplicationController
5
+ def create
6
+ if env['warden'].authenticate(:scope => :user)
7
+ render json: current_user, status: 201
8
+ else
9
+ render json: {errors: {user:["Invalid email or password"]}}, status: 422
10
+ end
11
+ end
12
+ end
13
+ end
@@ -0,0 +1,51 @@
1
+ # == ApplicationController Extensions for Authentication
2
+ #
3
+ # Provide methods for manage authentication of users in a multitenant account environment.
4
+ #
5
+
6
+ ::ApplicationController.class_eval do
7
+
8
+ # Returns the current account for the authenticated user.
9
+ #
10
+ # @return [Cadenero::V1::Account] the current account.
11
+ def current_account
12
+ if user_signed_in?
13
+ @current_account ||= begin
14
+ Cadenero::V1::Account.find_by_subdomain(request.subdomain)
15
+ end
16
+ end
17
+ end
18
+
19
+ # Returns the current authenticated user.
20
+ #
21
+ # @return [Cadenero::User] the current account.
22
+ def current_user
23
+ if user_signed_in?
24
+ @current_user ||= begin
25
+ user_id = env['warden'].user(:scope => :user)
26
+ Cadenero::User.find(user_id)
27
+ end
28
+ end
29
+ end
30
+
31
+ # Check to see if there is an authenticated user
32
+ def user_signed_in?
33
+ env['warden'].authenticated?(:user)
34
+ end
35
+
36
+ # it the user is not authenticated returns a 422 and an informative error with the link for sign
37
+ def authenticate_user!
38
+ unless user_signed_in?
39
+ errors = "Please sign in. posting the user json credentials to /v1/sign_in"
40
+ render json: {errors: errors, links: "/v1/sign_in"}, status: 422
41
+ end
42
+ end
43
+
44
+ # Authenticate the provided user.
45
+ #
46
+ # @param user [Cadenero::User] the user to be authenthicated
47
+ def force_authentication!(user)
48
+ env['warden'].set_user(user.id, :scope => :user)
49
+ end
50
+
51
+ end
@@ -0,0 +1,4 @@
1
+ module Cadenero
2
+ module ApplicationHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Cadenero
2
+ module V1::AccountsHelper
3
+ end
4
+ end
@@ -0,0 +1,4 @@
1
+ module Cadenero
2
+ module V1::UsersHelper
3
+ end
4
+ end
@@ -0,0 +1,7 @@
1
+ module Cadenero
2
+ class Member < ActiveRecord::Base
3
+ belongs_to :account, :class_name => "Cadenero::V1::Account"
4
+ belongs_to :user, :class_name => "Cadenero::User"
5
+ # attr_accessible :title, :body
6
+ end
7
+ end
@@ -0,0 +1,8 @@
1
+ module Cadenero
2
+ class User < ActiveRecord::Base
3
+ attr_accessible :email, :password, :password_confirmation
4
+ has_secure_password
5
+ has_many :members, :class_name => "Cadenero::Member"
6
+ has_many :accounts, :through => :members
7
+ end
8
+ end
@@ -0,0 +1,60 @@
1
+ module Cadenero::V1
2
+ class Account < ActiveRecord::Base
3
+ belongs_to :owner, :class_name => "Cadenero::User"
4
+ has_many :members, :class_name => "Cadenero::Member"
5
+ has_many :users, :through => :members
6
+
7
+ accepts_nested_attributes_for :owner
8
+ attr_accessible :name, :subdomain, :owner_attributes
9
+ validates :subdomain, :presence => true, :uniqueness => true
10
+
11
+ # Creates an accout and assign the provided [Cadenero::User] as owner to the account
12
+ # @param [Hash] params list
13
+ # @example
14
+ # Example for the params JSON: {name: "Testy", subdomain: "test",
15
+ # owner_attributes: {email: "testy@example.com", password: "changeme",
16
+ # password_confirmation: "changeme"} }
17
+ # @return the [Cadenero::V1::Account] created
18
+ # @note because this model uses accepts_nested_attributes_for :owner the JSOB should have owner_attributes
19
+ def self.create_with_owner(params={})
20
+ account = new(params)
21
+ if account.save
22
+ account.users << account.owner
23
+ end
24
+ account
25
+ end
26
+
27
+ # Create a database schema using the subdomain
28
+ def create_schema
29
+ Apartment::Database.create(subdomain)
30
+ end
31
+
32
+ # Generate authentication token unless already exists and save the record.
33
+ def ensure_authentication_token!
34
+ reset_authentication_token! if authentication_token.blank?
35
+ end
36
+
37
+ # Generate new authentication token (a.k.a. "single access token").
38
+ def reset_authentication_token!
39
+ self.authentication_token = self.class.authentication_token
40
+ end
41
+
42
+ # Generate a token checking if one does not already exist in the database.
43
+ # @return the authentication_token
44
+ def authentication_token
45
+ generate_token(:authentication_token)
46
+ end
47
+
48
+ # Generate a token by looping and ensuring does not already exist.
49
+ # @params [String] column is the name of the column that has the authentication token
50
+ # @return a unique generated authentication_token
51
+ def generate_token(column)
52
+ loop do
53
+ token = SecureRandom.base64(15).tr('+/=lIO0', 'pqrsxyz')
54
+ break token unless Account.where({ column => token }).first
55
+ end
56
+ end
57
+
58
+
59
+ end
60
+ end
@@ -0,0 +1,9 @@
1
+ module Cadenero
2
+ class AccountSerializer < ActiveModel::Serializer
3
+ embed :ids
4
+ attributes :id, :name, :subdomain
5
+ has_one :owner, :class_name => "Cadenero::User"
6
+ has_many :members, :class_name => "Cadenero::Member"
7
+ has_many :users, :through => :members
8
+ end
9
+ end
@@ -0,0 +1,8 @@
1
+ module Cadenero
2
+ class UserSerializer < ActiveModel::Serializer
3
+ embed :ids
4
+ attributes :id, :email
5
+ has_many :members, :class_name => "Cadenero::Member"
6
+ has_many :accounts, :through => :members
7
+ end
8
+ end
@@ -0,0 +1,10 @@
1
+ Rails.application.config.middleware.use 'Apartment::Elevators::Subdomain'
2
+
3
+
4
+ Apartment.configure do |config|
5
+ config.excluded_models = ["Cadenero::V1::Account",
6
+ "Cadenero::Member",
7
+ "Cadenero::User"]
8
+ # Dynamically get database names to migrate
9
+ # config.database_names = lambda{ Account.pluck(:database_name) }
10
+ end
@@ -0,0 +1,3 @@
1
+ Rails.application.config.middleware.use Warden::Manager do |manager|
2
+ manager.default_strategies :password
3
+ end
@@ -0,0 +1,23 @@
1
+ Warden::Strategies.add(:password) do
2
+ def subdomain
3
+ ActionDispatch::Http::URL.extract_subdomains(request.host, 1)
4
+ end
5
+
6
+ def valid?
7
+ subdomain.present? && params["user"]
8
+ end
9
+
10
+ def authenticate!
11
+ account = Cadenero::V1::Account.find_by_subdomain(subdomain)
12
+ if account
13
+ u = account.users.find_by_email(params["user"]["email"])
14
+ if u.nil?
15
+ fail!
16
+ else
17
+ u.authenticate(params["user"]["password"]) ? success!(u) : fail!
18
+ end
19
+ else
20
+ fail!
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,24 @@
1
+ require 'cadenero/constraints/subdomain_required'
2
+
3
+ Cadenero::Engine.routes.draw do
4
+ namespace :v1 do
5
+ get "users/new"
6
+
7
+ constraints(Cadenero::Constraints::SubdomainRequired) do
8
+ scope :module => "account" do
9
+ root :to => "dashboard#index"
10
+ get '/sign_in', :to => "sessions#new"
11
+ post '/sign_in', :to => "sessions#create", :as => :sessions
12
+ get '/sign_up', :to => "users#new", :as => :user_sign_up
13
+ post '/sign_up', :to => "users#create", :as => :user_sign_up
14
+ end
15
+ end
16
+ get '/sign_up', :to => "accounts#new", :as => :sign_up
17
+ post '/accounts', :to => "accounts#create", :as => :accounts
18
+
19
+ root :to => "dashboard#index"
20
+
21
+ end
22
+ # post '/v1/accounts', :to => "v1/accounts#create", :as => :accounts
23
+
24
+ end
@@ -0,0 +1,12 @@
1
+ class CreateCadeneroV1Accounts < ActiveRecord::Migration
2
+ def change
3
+ create_table :cadenero_accounts do |t|
4
+ t.string :name
5
+ t.string :subdomain
6
+ t.references :owner
7
+
8
+ t.timestamps
9
+ end
10
+ add_index :cadenero_accounts, :owner_id
11
+ end
12
+ end
@@ -0,0 +1,10 @@
1
+ class CreateCadeneroV1Users < ActiveRecord::Migration
2
+ def change
3
+ create_table :cadenero_users do |t|
4
+ t.string :email
5
+ t.string :password_digest
6
+
7
+ t.timestamps
8
+ end
9
+ end
10
+ end
@@ -0,0 +1,12 @@
1
+ class CreateCadeneroV1Members < ActiveRecord::Migration
2
+ def change
3
+ create_table :cadenero_members do |t|
4
+ t.references :account
5
+ t.references :user
6
+
7
+ t.timestamps
8
+ end
9
+ add_index :cadenero_members, :account_id
10
+ add_index :cadenero_members, :user_id
11
+ end
12
+ end
@@ -0,0 +1,6 @@
1
+ class AddAuthenticationTokenToAccounts < ActiveRecord::Migration
2
+ def change
3
+ add_column :cadenero_accounts, :authentication_token, :string
4
+ add_index :cadenero_accounts, :authentication_token
5
+ end
6
+ end
@@ -0,0 +1,29 @@
1
+ #--
2
+ # Copyright (c) 2013 AgilTec. Manuel Vidaurre @mvidaurre
3
+ #
4
+ # Permission is hereby granted, free of charge, to any person obtaining
5
+ # a copy of this software and associated documentation files (the
6
+ # "Software"), to deal in the Software without restriction, including
7
+ # without limitation the rights to use, copy, modify, merge, publish,
8
+ # distribute, sublicense, and/or sell copies of the Software, and to
9
+ # permit persons to whom the Software is furnished to do so, subject to
10
+ # the following conditions:
11
+ #
12
+ # The above copyright notice and this permission notice shall be
13
+ # included in all copies or substantial portions of the Software.
14
+ #
15
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
16
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
17
+ # MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
18
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
19
+ # LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
20
+ # OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
21
+ # WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22
+ #++
23
+
24
+ require "cadenero/engine"
25
+ require 'warden'
26
+ require 'apartment'
27
+
28
+ module Cadenero
29
+ end
@@ -0,0 +1,7 @@
1
+ ActiveRecord::Base.class_eval do
2
+ def self.scoped_to_account
3
+ belongs_to :account, :class_name => "Cadenero::V1::Account"
4
+ association_name = self.to_s.downcase.pluralize
5
+ Cadenero::V1::Account.has_many association_name, :class_name => self.to_s
6
+ end
7
+ end
@@ -0,0 +1,9 @@
1
+ module Cadenero
2
+ module Constraints
3
+ class SubdomainRequired
4
+ def self.matches?(request)
5
+ request.subdomain.present? && request.subdomain != "www"
6
+ end
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,26 @@
1
+ require 'warden'
2
+ module Cadenero
3
+ class Engine < ::Rails::Engine
4
+ isolate_namespace Cadenero
5
+ config.middleware.use Warden::Manager do |manager|
6
+ manager.default_strategies :password
7
+ end
8
+
9
+ config.generators do |g|
10
+ g.test_framework :rspec
11
+ g.integration_tool :rspec
12
+ end
13
+
14
+ config.to_prepare do
15
+ root = Cadenero::Engine.root
16
+ extenders_path = root + "app/extenders/**/*.rb"
17
+ Dir.glob(extenders_path) do |file|
18
+ Rails.configuration.cache_classes ? require(file) : load(file)
19
+ end
20
+ end
21
+
22
+ config.middleware.use ActionDispatch::Cookies
23
+ config.middleware.use ActionDispatch::Session::CookieStore
24
+
25
+ end
26
+ end
@@ -0,0 +1,3 @@
1
+ module Cadenero
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :cadenero do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,292 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: cadenero
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.0.1
5
+ prerelease:
6
+ platform: ruby
7
+ authors:
8
+ - Manuel Vidaurre
9
+ autorequire:
10
+ bindir: bin
11
+ cert_chain: []
12
+ date: 2013-06-25 00:00:00.000000000 Z
13
+ dependencies:
14
+ - !ruby/object:Gem::Dependency
15
+ name: rails-api
16
+ requirement: !ruby/object:Gem::Requirement
17
+ none: false
18
+ requirements:
19
+ - - ~>
20
+ - !ruby/object:Gem::Version
21
+ version: 0.1.0
22
+ type: :runtime
23
+ prerelease: false
24
+ version_requirements: !ruby/object:Gem::Requirement
25
+ none: false
26
+ requirements:
27
+ - - ~>
28
+ - !ruby/object:Gem::Version
29
+ version: 0.1.0
30
+ - !ruby/object:Gem::Dependency
31
+ name: bcrypt-ruby
32
+ requirement: !ruby/object:Gem::Requirement
33
+ none: false
34
+ requirements:
35
+ - - ~>
36
+ - !ruby/object:Gem::Version
37
+ version: 3.0.1
38
+ type: :runtime
39
+ prerelease: false
40
+ version_requirements: !ruby/object:Gem::Requirement
41
+ none: false
42
+ requirements:
43
+ - - ~>
44
+ - !ruby/object:Gem::Version
45
+ version: 3.0.1
46
+ - !ruby/object:Gem::Dependency
47
+ name: warden
48
+ requirement: !ruby/object:Gem::Requirement
49
+ none: false
50
+ requirements:
51
+ - - ~>
52
+ - !ruby/object:Gem::Version
53
+ version: 1.2.1
54
+ type: :runtime
55
+ prerelease: false
56
+ version_requirements: !ruby/object:Gem::Requirement
57
+ none: false
58
+ requirements:
59
+ - - ~>
60
+ - !ruby/object:Gem::Version
61
+ version: 1.2.1
62
+ - !ruby/object:Gem::Dependency
63
+ name: apartment
64
+ requirement: !ruby/object:Gem::Requirement
65
+ none: false
66
+ requirements:
67
+ - - ~>
68
+ - !ruby/object:Gem::Version
69
+ version: 0.21.1
70
+ type: :runtime
71
+ prerelease: false
72
+ version_requirements: !ruby/object:Gem::Requirement
73
+ none: false
74
+ requirements:
75
+ - - ~>
76
+ - !ruby/object:Gem::Version
77
+ version: 0.21.1
78
+ - !ruby/object:Gem::Dependency
79
+ name: strong_parameters
80
+ requirement: !ruby/object:Gem::Requirement
81
+ none: false
82
+ requirements:
83
+ - - ~>
84
+ - !ruby/object:Gem::Version
85
+ version: 0.2.1
86
+ type: :runtime
87
+ prerelease: false
88
+ version_requirements: !ruby/object:Gem::Requirement
89
+ none: false
90
+ requirements:
91
+ - - ~>
92
+ - !ruby/object:Gem::Version
93
+ version: 0.2.1
94
+ - !ruby/object:Gem::Dependency
95
+ name: active_model_serializers
96
+ requirement: !ruby/object:Gem::Requirement
97
+ none: false
98
+ requirements:
99
+ - - ~>
100
+ - !ruby/object:Gem::Version
101
+ version: 0.8.1
102
+ type: :runtime
103
+ prerelease: false
104
+ version_requirements: !ruby/object:Gem::Requirement
105
+ none: false
106
+ requirements:
107
+ - - ~>
108
+ - !ruby/object:Gem::Version
109
+ version: 0.8.1
110
+ - !ruby/object:Gem::Dependency
111
+ name: pg
112
+ requirement: !ruby/object:Gem::Requirement
113
+ none: false
114
+ requirements:
115
+ - - ! '>='
116
+ - !ruby/object:Gem::Version
117
+ version: '0'
118
+ type: :development
119
+ prerelease: false
120
+ version_requirements: !ruby/object:Gem::Requirement
121
+ none: false
122
+ requirements:
123
+ - - ! '>='
124
+ - !ruby/object:Gem::Version
125
+ version: '0'
126
+ - !ruby/object:Gem::Dependency
127
+ name: rspec-rails
128
+ requirement: !ruby/object:Gem::Requirement
129
+ none: false
130
+ requirements:
131
+ - - ~>
132
+ - !ruby/object:Gem::Version
133
+ version: 2.13.2
134
+ type: :development
135
+ prerelease: false
136
+ version_requirements: !ruby/object:Gem::Requirement
137
+ none: false
138
+ requirements:
139
+ - - ~>
140
+ - !ruby/object:Gem::Version
141
+ version: 2.13.2
142
+ - !ruby/object:Gem::Dependency
143
+ name: coveralls
144
+ requirement: !ruby/object:Gem::Requirement
145
+ none: false
146
+ requirements:
147
+ - - ! '>='
148
+ - !ruby/object:Gem::Version
149
+ version: '0'
150
+ type: :development
151
+ prerelease: false
152
+ version_requirements: !ruby/object:Gem::Requirement
153
+ none: false
154
+ requirements:
155
+ - - ! '>='
156
+ - !ruby/object:Gem::Version
157
+ version: '0'
158
+ - !ruby/object:Gem::Dependency
159
+ name: capybara
160
+ requirement: !ruby/object:Gem::Requirement
161
+ none: false
162
+ requirements:
163
+ - - ~>
164
+ - !ruby/object:Gem::Version
165
+ version: 2.1.0
166
+ type: :development
167
+ prerelease: false
168
+ version_requirements: !ruby/object:Gem::Requirement
169
+ none: false
170
+ requirements:
171
+ - - ~>
172
+ - !ruby/object:Gem::Version
173
+ version: 2.1.0
174
+ - !ruby/object:Gem::Dependency
175
+ name: launchy
176
+ requirement: !ruby/object:Gem::Requirement
177
+ none: false
178
+ requirements:
179
+ - - ~>
180
+ - !ruby/object:Gem::Version
181
+ version: 2.3.0
182
+ type: :development
183
+ prerelease: false
184
+ version_requirements: !ruby/object:Gem::Requirement
185
+ none: false
186
+ requirements:
187
+ - - ~>
188
+ - !ruby/object:Gem::Version
189
+ version: 2.3.0
190
+ - !ruby/object:Gem::Dependency
191
+ name: factory_girl
192
+ requirement: !ruby/object:Gem::Requirement
193
+ none: false
194
+ requirements:
195
+ - - ~>
196
+ - !ruby/object:Gem::Version
197
+ version: 4.2.0
198
+ type: :development
199
+ prerelease: false
200
+ version_requirements: !ruby/object:Gem::Requirement
201
+ none: false
202
+ requirements:
203
+ - - ~>
204
+ - !ruby/object:Gem::Version
205
+ version: 4.2.0
206
+ - !ruby/object:Gem::Dependency
207
+ name: database_cleaner
208
+ requirement: !ruby/object:Gem::Requirement
209
+ none: false
210
+ requirements:
211
+ - - ~>
212
+ - !ruby/object:Gem::Version
213
+ version: 1.0.1
214
+ type: :development
215
+ prerelease: false
216
+ version_requirements: !ruby/object:Gem::Requirement
217
+ none: false
218
+ requirements:
219
+ - - ~>
220
+ - !ruby/object:Gem::Version
221
+ version: 1.0.1
222
+ description: An Engine tha use Warden and OAuth for authenticate users using a RESTful
223
+ API
224
+ email:
225
+ - manuel.vidaurre@agiltec.com.mx
226
+ executables: []
227
+ extensions: []
228
+ extra_rdoc_files: []
229
+ files:
230
+ - app/assets/javascripts/cadenero/application.js
231
+ - app/assets/javascripts/cadenero/v1/accounts.js
232
+ - app/assets/javascripts/cadenero/v1/users.js
233
+ - app/assets/stylesheets/cadenero/application.css
234
+ - app/assets/stylesheets/cadenero/v1/accounts.css
235
+ - app/assets/stylesheets/cadenero/v1/users.css
236
+ - app/controllers/cadenero/application_controller.rb
237
+ - app/controllers/cadenero/v1/account/dashboard_controller.rb
238
+ - app/controllers/cadenero/v1/account/users_controller.rb
239
+ - app/controllers/cadenero/v1/accounts_controller.rb
240
+ - app/controllers/cadenero/v1/sessions_controller.rb
241
+ - app/extenders/controllers/application_controller_decorator.rb
242
+ - app/helpers/cadenero/application_helper.rb
243
+ - app/helpers/cadenero/v1/accounts_helper.rb
244
+ - app/helpers/cadenero/v1/users_helper.rb
245
+ - app/models/cadenero/member.rb
246
+ - app/models/cadenero/user.rb
247
+ - app/models/cadenero/v1/account.rb
248
+ - app/serializers/cadenero/account_serializer.rb
249
+ - app/serializers/cadenero/user_serializer.rb
250
+ - config/initializers/apartment.rb
251
+ - config/initializers/warden/strategies/password.rb
252
+ - config/initializers/warden.rb
253
+ - config/routes.rb
254
+ - db/migrate/20130612061604_create_cadenero_v1_accounts.rb
255
+ - db/migrate/20130612064652_create_cadenero_v1_users.rb
256
+ - db/migrate/20130612073709_create_cadenero_v1_members.rb
257
+ - db/migrate/20130612093908_add_authentication_token_to_accounts.rb
258
+ - lib/cadenero/active_record_extensions.rb
259
+ - lib/cadenero/constraints/subdomain_required.rb
260
+ - lib/cadenero/engine.rb
261
+ - lib/cadenero/version.rb
262
+ - lib/cadenero.rb
263
+ - lib/tasks/cadenero_tasks.rake
264
+ - MIT-LICENSE
265
+ - Rakefile
266
+ - README.md
267
+ homepage: http://www.agiltec.com.mx/ruby/gems/cadenero
268
+ licenses: []
269
+ post_install_message:
270
+ rdoc_options: []
271
+ require_paths:
272
+ - lib
273
+ required_ruby_version: !ruby/object:Gem::Requirement
274
+ none: false
275
+ requirements:
276
+ - - ! '>='
277
+ - !ruby/object:Gem::Version
278
+ version: '0'
279
+ required_rubygems_version: !ruby/object:Gem::Requirement
280
+ none: false
281
+ requirements:
282
+ - - ! '>='
283
+ - !ruby/object:Gem::Version
284
+ version: '0'
285
+ requirements: []
286
+ rubyforge_project:
287
+ rubygems_version: 1.8.23
288
+ signing_key:
289
+ specification_version: 3
290
+ summary: Rails.API Engine for manage multitenant authentication
291
+ test_files: []
292
+ has_rdoc: