cadenero 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/MIT-LICENSE +20 -0
- data/README.md +79 -0
- data/Rakefile +44 -0
- data/app/assets/javascripts/cadenero/application.js +15 -0
- data/app/assets/javascripts/cadenero/v1/accounts.js +2 -0
- data/app/assets/javascripts/cadenero/v1/users.js +2 -0
- data/app/assets/stylesheets/cadenero/application.css +13 -0
- data/app/assets/stylesheets/cadenero/v1/accounts.css +4 -0
- data/app/assets/stylesheets/cadenero/v1/users.css +4 -0
- data/app/controllers/cadenero/application_controller.rb +8 -0
- data/app/controllers/cadenero/v1/account/dashboard_controller.rb +11 -0
- data/app/controllers/cadenero/v1/account/users_controller.rb +27 -0
- data/app/controllers/cadenero/v1/accounts_controller.rb +23 -0
- data/app/controllers/cadenero/v1/sessions_controller.rb +13 -0
- data/app/extenders/controllers/application_controller_decorator.rb +51 -0
- data/app/helpers/cadenero/application_helper.rb +4 -0
- data/app/helpers/cadenero/v1/accounts_helper.rb +4 -0
- data/app/helpers/cadenero/v1/users_helper.rb +4 -0
- data/app/models/cadenero/member.rb +7 -0
- data/app/models/cadenero/user.rb +8 -0
- data/app/models/cadenero/v1/account.rb +60 -0
- data/app/serializers/cadenero/account_serializer.rb +9 -0
- data/app/serializers/cadenero/user_serializer.rb +8 -0
- data/config/initializers/apartment.rb +10 -0
- data/config/initializers/warden.rb +3 -0
- data/config/initializers/warden/strategies/password.rb +23 -0
- data/config/routes.rb +24 -0
- data/db/migrate/20130612061604_create_cadenero_v1_accounts.rb +12 -0
- data/db/migrate/20130612064652_create_cadenero_v1_users.rb +10 -0
- data/db/migrate/20130612073709_create_cadenero_v1_members.rb +12 -0
- data/db/migrate/20130612093908_add_authentication_token_to_accounts.rb +6 -0
- data/lib/cadenero.rb +29 -0
- data/lib/cadenero/active_record_extensions.rb +7 -0
- data/lib/cadenero/constraints/subdomain_required.rb +9 -0
- data/lib/cadenero/engine.rb +26 -0
- data/lib/cadenero/version.rb +3 -0
- data/lib/tasks/cadenero_tasks.rake +4 -0
- metadata +292 -0
data/MIT-LICENSE
ADDED
@@ -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.
|
data/README.md
ADDED
@@ -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.
|
data/Rakefile
ADDED
@@ -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,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,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,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,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,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
|
data/config/routes.rb
ADDED
@@ -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 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
|
data/lib/cadenero.rb
ADDED
@@ -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,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
|
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:
|