cadenero 0.0.2.a → 0.0.2.a1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/README.md +46 -9
- data/app/controllers/cadenero/v1/account/dashboard_controller.rb +1 -1
- data/app/controllers/cadenero/v1/account/sessions_controller.rb +27 -0
- data/app/controllers/cadenero/v1/accounts_controller.rb +4 -0
- data/app/extenders/controllers/application_controller_decorator.rb +4 -3
- data/app/serializers/cadenero/user_serializer.rb +1 -0
- data/config/initializers/warden/strategies/password.rb +13 -4
- data/config/initializers/warden.rb +1 -0
- data/config/routes.rb +6 -11
- data/db/seeds.rb +8 -2
- data/lib/cadenero/engine.rb +1 -0
- data/lib/cadenero/version.rb +1 -1
- data/lib/cadenero.rb +25 -0
- data/lib/generators/cadenero/install/templates/initializer.rb +0 -3
- data/lib/generators/cadenero/install_generator.rb +40 -17
- data/spec/dummy/app/controllers/application_controller.rb +6 -0
- data/spec/dummy/db/seeds.rb +8 -0
- data/spec/dummy/log/development.log +527 -87
- data/spec/dummy/log/test.log +3117 -8571
- data/spec/dummy/tmp/cache/assets/D0B/E90/sprockets%2F2c56f5dc65ded8014ad1226c5c985124 +0 -0
- data/spec/dummy/tmp/cache/assets/D86/490/sprockets%2Faaf0d4667cf7ef62869d70539bc77af7 +0 -0
- data/spec/dummy/tmp/cache/assets/DA6/CC0/sprockets%2F1c575d7a7db598dfcf41536ccc83f01e +0 -0
- data/spec/dummy/tmp/cache/assets/DB6/250/sprockets%2F0f882b7b9528900cfec89e8b2fffcc38 +0 -0
- data/spec/dummy/tmp/cache/assets/E18/9D0/sprockets%2F1f79e8f926ea465ded9dcc552cd56bff +0 -0
- data/spec/dummy/tmp/restart.txt +0 -0
- data/spec/features/users/sign_in_spec.rb +29 -10
- data/spec/features/users/sign_up_spec.rb +2 -2
- data/spec/generators/install_generator_spec.rb +1 -24
- metadata +17 -3
- data/app/controllers/cadenero/v1/sessions_controller.rb +0 -13
data/README.md
CHANGED
@@ -18,19 +18,56 @@ Authentication Engine for Rails.API multitenant RESTful APIs based on Warden. It
|
|
18
18
|
### Why Cadenero?
|
19
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
20
|
|
21
|
+
### Inatalling **Cadenero**
|
22
|
+
Generate first your Rails.API app as usual using:
|
23
|
+
```
|
24
|
+
> rails-api new your_app --skip-test-unit
|
25
|
+
```
|
26
|
+
In the `Gemfile` add the following lines:
|
27
|
+
```ruby
|
28
|
+
gem 'cadenero', '~> 0.0.2.a1'
|
29
|
+
gem 'pg'
|
30
|
+
```
|
31
|
+
In the `config/database.yml` replace the `sqlite3` adapter for `postgresql` as follow:
|
32
|
+
```
|
33
|
+
development:
|
34
|
+
adapter: postgresql
|
35
|
+
database: your_app_development
|
36
|
+
min_messages: warning
|
37
|
+
|
38
|
+
test:
|
39
|
+
adapter: postgresql
|
40
|
+
database: your_app_test
|
41
|
+
min_messages: warning
|
42
|
+
```
|
43
|
+
|
44
|
+
Then run bundle, create the databases and the generator:
|
45
|
+
```
|
46
|
+
> bundle install; rake db:create; rails-api g cadenero:install
|
47
|
+
```
|
48
|
+
Finally run the server:
|
49
|
+
```
|
50
|
+
rails-api s
|
51
|
+
```
|
52
|
+
|
53
|
+
Check that you can access the API using the default account `www` and user `testy@example.com` with password `changeme˜ for that you can use [cURL](http://curl.haxx.se/) or [RESTClient](http://restclient.net/)
|
54
|
+
|
55
|
+
Then have fun!
|
56
|
+
|
21
57
|
### Access Points
|
22
58
|
**Cadenero** creates the following versioned routes for exposing the authentication RESTful API
|
23
59
|
|
24
60
|
```
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
61
|
+
v1_root /v1(.:format) cadenero/v1/account/dashboard#index {:default=>:json}
|
62
|
+
v1_sessions POST /v1/sessions(.:format) cadenero/v1/account/sessions#create {:default=>:json}
|
63
|
+
DELETE /v1/sessions(.:format) cadenero/v1/account/sessions#delete {:default=>:json}
|
64
|
+
v1_users POST /v1/users(.:format) cadenero/v1/account/users#create {:default=>:json}
|
65
|
+
v1_accounts POST /v1/accounts(.:format) cadenero/v1/accounts#create {:default=>:json}
|
66
|
+
root / cadenero/v1/account/dashboard#index {:default=>:json}
|
67
|
+
```
|
68
|
+
You can check then running:
|
69
|
+
```
|
70
|
+
rake routes
|
34
71
|
```
|
35
72
|
|
36
73
|
### The Cadenero Task List
|
@@ -0,0 +1,27 @@
|
|
1
|
+
require_dependency "cadenero/application_controller"
|
2
|
+
|
3
|
+
module Cadenero::V1
|
4
|
+
class Account::SessionsController < Cadenero::ApplicationController
|
5
|
+
def create
|
6
|
+
Rails.logger.info "params: #{params}"
|
7
|
+
if env['warden'].authenticate(:password, :scope => :user)
|
8
|
+
render json: current_user, status: 201
|
9
|
+
else
|
10
|
+
render json: {errors: {user:["Invalid email or password"]}}, status: 422
|
11
|
+
end
|
12
|
+
end
|
13
|
+
def delete
|
14
|
+
user = Cadenero::User.find_by_id(params[:id])
|
15
|
+
Rails.logger.info "id: #{params[:id]}"
|
16
|
+
Rails.logger.info "user: #{user.to_json}"
|
17
|
+
Rails.logger.info "current_user.id: #{current_user}"
|
18
|
+
Rails.logger.info "user_signed_in?: #{user_signed_in?}"
|
19
|
+
if user_signed_in?
|
20
|
+
env['warden'].logout(:user)
|
21
|
+
render json: {message: "Successful logout"}, status: 201
|
22
|
+
else
|
23
|
+
render json: {message: "Unsuccessful logout user with id"}, status: 401
|
24
|
+
end
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
@@ -3,6 +3,10 @@ require_dependency "cadenero/application_controller"
|
|
3
3
|
module Cadenero
|
4
4
|
module V1
|
5
5
|
class AccountsController < Cadenero::ApplicationController
|
6
|
+
def new
|
7
|
+
errors = %Q{Please sign up. posting the account json data as {account: { name: "Testy", subdomain: "test", owner_attributes: {email: "testy@example.com", password: "changeme", password_confirmation: "changeme"} }} to /v1/accounts/sign_up}
|
8
|
+
render json: {errors: errors, links: "/v1/accounts/sign_up"}, status: 422
|
9
|
+
end
|
6
10
|
def create
|
7
11
|
@account = Cadenero::V1::Account.create_with_owner(params[:account])
|
8
12
|
if @account.valid?
|
@@ -23,7 +23,7 @@
|
|
23
23
|
if user_signed_in?
|
24
24
|
@current_user ||= begin
|
25
25
|
user_id = env['warden'].user(:scope => :user)
|
26
|
-
Cadenero::User.
|
26
|
+
Cadenero::User.find_by_id(user_id)
|
27
27
|
end
|
28
28
|
end
|
29
29
|
end
|
@@ -35,9 +35,10 @@
|
|
35
35
|
|
36
36
|
# it the user is not authenticated returns a 422 and an informative error with the link for sign
|
37
37
|
def authenticate_user!
|
38
|
+
Rails.logger.info "env['warden'].authenticated?(:user): #{env['warden'].authenticated?(:user)}"
|
38
39
|
unless user_signed_in?
|
39
|
-
errors =
|
40
|
-
render json: {errors: errors, links: "/v1/
|
40
|
+
errors = %Q{Please sign in. posting the user json credentials as: {"user": {"email": "testy2@example.com", "password": "changeme"}} to /v1/sessions}
|
41
|
+
render json: {errors: errors, links: "/v1/sessions"}, status: 422
|
41
42
|
end
|
42
43
|
end
|
43
44
|
|
@@ -3,18 +3,27 @@ Warden::Strategies.add(:password) do
|
|
3
3
|
ActionDispatch::Http::URL.extract_subdomains(request.host, 1)
|
4
4
|
end
|
5
5
|
|
6
|
+
def json_params
|
7
|
+
unless params.empty?
|
8
|
+
params
|
9
|
+
else
|
10
|
+
@json ||= env['rack.input'].gets
|
11
|
+
JSON.parse(@json)
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
6
15
|
def valid?
|
7
|
-
subdomain.present? &&
|
16
|
+
subdomain.present? && json_params["user"]
|
8
17
|
end
|
9
18
|
|
10
19
|
def authenticate!
|
11
20
|
account = Cadenero::V1::Account.find_by_subdomain(subdomain)
|
12
21
|
if account
|
13
|
-
u = account.users.find_by_email(
|
14
|
-
if u.nil?
|
22
|
+
u = account.users.find_by_email(json_params["user"]["email"])
|
23
|
+
if u.nil? || u.blank?
|
15
24
|
fail!
|
16
25
|
else
|
17
|
-
u.authenticate(
|
26
|
+
u.authenticate(json_params["user"]["password"]) ? success!(u) : fail!
|
18
27
|
end
|
19
28
|
else
|
20
29
|
fail!
|
data/config/routes.rb
CHANGED
@@ -2,23 +2,18 @@ require 'cadenero/constraints/subdomain_required'
|
|
2
2
|
|
3
3
|
Cadenero::Engine.routes.draw do
|
4
4
|
namespace :v1 do
|
5
|
-
get "users/new"
|
6
|
-
|
7
5
|
constraints(Cadenero::Constraints::SubdomainRequired) do
|
8
6
|
scope :module => "account" do
|
9
|
-
root :to => "dashboard#index"
|
10
|
-
|
11
|
-
|
12
|
-
|
13
|
-
post '/sign_up', :to => "users#create", :as => :user_sign_up
|
7
|
+
root :to => "dashboard#index", default: :json
|
8
|
+
post '/sessions', :to => "sessions#create", default: :json
|
9
|
+
delete '/sessions', :to => "sessions#delete", default: :json
|
10
|
+
post '/users', :to => "users#create", default: :json
|
14
11
|
end
|
15
12
|
end
|
16
|
-
|
17
|
-
post '/accounts', :to => "accounts#create", :as => :accounts
|
18
|
-
|
19
|
-
root :to => "dashboard#index"
|
13
|
+
post '/accounts', :to => "accounts#create", :as => :accounts, default: :json
|
20
14
|
|
21
15
|
end
|
16
|
+
root :to => "v1/account/dashboard#index", default: :json
|
22
17
|
# post '/v1/accounts', :to => "v1/accounts#create", :as => :accounts
|
23
18
|
|
24
19
|
end
|
data/db/seeds.rb
CHANGED
@@ -1,2 +1,8 @@
|
|
1
|
-
|
2
|
-
|
1
|
+
@account = Cadenero::V1::Account.create!(name: Cadenero.default_account_name,
|
2
|
+
subdomain: Cadenero.default_account_subdomain,
|
3
|
+
owner: Cadenero::User.create!(email: Cadenero.default_user_email,
|
4
|
+
password: Cadenero.default_user_password,
|
5
|
+
password_confirmation: Cadenero.default_user_password))
|
6
|
+
|
7
|
+
@account.create_schema
|
8
|
+
@account.ensure_authentication_token!
|
data/lib/cadenero/engine.rb
CHANGED
data/lib/cadenero/version.rb
CHANGED
data/lib/cadenero.rb
CHANGED
@@ -26,4 +26,29 @@ require 'warden'
|
|
26
26
|
require 'apartment'
|
27
27
|
|
28
28
|
module Cadenero
|
29
|
+
mattr_accessor :base_path,
|
30
|
+
:user_class,
|
31
|
+
:default_account_name,
|
32
|
+
:default_account_subdomain,
|
33
|
+
:default_user_email,
|
34
|
+
:default_user_password
|
35
|
+
|
36
|
+
class << self
|
37
|
+
def base_path
|
38
|
+
@@base_path ||= Rails.application.routes.named_routes[:cadenero].path
|
39
|
+
end
|
40
|
+
|
41
|
+
def user_class
|
42
|
+
if @@user_class.is_a?(Class)
|
43
|
+
raise "You can no longer set Cadenero.user_class to be a class. Please use a string instead."
|
44
|
+
elsif @@user_class.is_a?(String)
|
45
|
+
begin
|
46
|
+
Object.const_get(@@user_class)
|
47
|
+
rescue NameError
|
48
|
+
@@user_class.constantize
|
49
|
+
end
|
50
|
+
end
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
29
54
|
end
|
@@ -1,8 +1,5 @@
|
|
1
1
|
Cadenero.user_class = "<%= user_class %>"
|
2
|
-
Cadenero.email_from_address = "please-change-me@example.com"
|
3
2
|
# If you do not want to use gravatar for avatars then specify the method to use here:
|
4
|
-
# Cadenero.avatar_user_method = :custom_avatar_url
|
5
|
-
#Cadenero.per_page = <%= Cadenero.per_page.inspect %>
|
6
3
|
|
7
4
|
|
8
5
|
# Rails.application.config.to_prepare do
|
@@ -1,8 +1,12 @@
|
|
1
1
|
require 'rails/generators'
|
2
2
|
module Cadenero
|
3
3
|
module Generators
|
4
|
-
class InstallGenerator < Rails::Generators::Base
|
4
|
+
class InstallGenerator < Rails::Generators::Base
|
5
5
|
class_option "user-class", :type => :string
|
6
|
+
class_option "default-account-name", :type => :string
|
7
|
+
class_option "default-account-subdomain", :type => :string
|
8
|
+
class_option "default-user-email", :type => :string
|
9
|
+
class_option "default-user-password", :type => :string
|
6
10
|
class_option "no-migrate", :type => :boolean
|
7
11
|
class_option "current-user-helper", :type => :string
|
8
12
|
|
@@ -18,13 +22,13 @@ module Cadenero
|
|
18
22
|
|
19
23
|
def determine_user_class
|
20
24
|
@user_class = options["user-class"].presence ||
|
21
|
-
ask("What
|
25
|
+
ask("What will be the name for your user class? [User]").presence ||
|
22
26
|
'User'
|
23
27
|
end
|
24
28
|
|
25
29
|
def determine_current_user_helper
|
26
30
|
current_user_helper = options["current-user-helper"].presence ||
|
27
|
-
ask("What
|
31
|
+
ask("What will be the current_user helper called in your app? [current_user]").presence ||
|
28
32
|
:current_user
|
29
33
|
|
30
34
|
puts "Defining cadenero_user method inside ApplicationController..."
|
@@ -43,6 +47,30 @@ module Cadenero
|
|
43
47
|
|
44
48
|
end
|
45
49
|
|
50
|
+
def determine_default_account_name
|
51
|
+
Cadenero.default_account_name = options["default-account-name"].presence ||
|
52
|
+
ask("What will be the name for the default account? [Root Account]").presence ||
|
53
|
+
'Root Account'
|
54
|
+
end
|
55
|
+
|
56
|
+
def determine_default_account_subdomain
|
57
|
+
Cadenero.default_account_subdomain = options["default-account-subdomain"].presence ||
|
58
|
+
ask("What will be the subdomain for the default account? [www]").presence ||
|
59
|
+
'www'
|
60
|
+
end
|
61
|
+
|
62
|
+
def determine_default_user_email
|
63
|
+
Cadenero.default_user_email = options["default-user-email"].presence ||
|
64
|
+
ask("What will be the email for the default user owner of the default account? [testy@example.com]").presence ||
|
65
|
+
'testy@example.com'
|
66
|
+
end
|
67
|
+
|
68
|
+
def determine_default_user_password
|
69
|
+
Cadenero.default_user_password = options["default-user-password "].presence ||
|
70
|
+
ask("What will be the password for the default user owner of the default account? [change-me]").presence ||
|
71
|
+
'change-me'
|
72
|
+
end
|
73
|
+
|
46
74
|
def add_cadenero_initializer
|
47
75
|
path = "#{Rails.root}/config/initializers/cadenero.rb"
|
48
76
|
if File.exists?(path)
|
@@ -62,6 +90,11 @@ module Cadenero
|
|
62
90
|
end
|
63
91
|
|
64
92
|
def seed_database
|
93
|
+
puts "default_account_name: #{Cadenero.default_account_name}"
|
94
|
+
puts "default_account_subdomain: #{Cadenero.default_account_subdomain}"
|
95
|
+
puts "default_user_email: #{Cadenero.default_user_email}"
|
96
|
+
puts "default_user_password: #{Cadenero.default_user_password}"
|
97
|
+
|
65
98
|
load "#{Rails.root}/config/initializers/cadenero.rb"
|
66
99
|
unless options["no-migrate"]
|
67
100
|
puts "Creating default cadenero account and owner"
|
@@ -73,10 +106,11 @@ module Cadenero
|
|
73
106
|
puts "Mounting Cadenero::Engine at \"/\" in config/routes.rb..."
|
74
107
|
insert_into_file("#{Rails.root}/config/routes.rb", :after => /routes.draw.do\n/) do
|
75
108
|
%Q{
|
76
|
-
# This line mounts Cadenero's routes at / by default.
|
109
|
+
mount Cadenero::Engine, :at => "/" # This line mounts Cadenero's routes at / by default.
|
77
110
|
# This means, any requests to the / URL of your application will go to Cadenero::V1:Account::DashboardController#index.
|
78
111
|
# If you would like to change where this extension is mounted, simply change the :at option to something different
|
79
112
|
# but that is discourage, the idea is to protect the whole site
|
113
|
+
|
80
114
|
}
|
81
115
|
end
|
82
116
|
end
|
@@ -88,8 +122,6 @@ module Cadenero
|
|
88
122
|
Here's what happened:\n\n}
|
89
123
|
|
90
124
|
output += step("Cadenero's migrations were copied over into db/migrate.\n")
|
91
|
-
output += step("We created a new migration called AddCadeneroAdminToTable.
|
92
|
-
This creates a new field called \"cadenero_admin\" on your #{user_class} model's table.\n")
|
93
125
|
output += step("A new method called `cadenero_user` was inserted into your ApplicationController.
|
94
126
|
This lets Cadenero know what the current user of your application is.\n")
|
95
127
|
output += step("A new file was created at config/initializers/cadenero.rb
|
@@ -97,25 +129,16 @@ Here's what happened:\n\n}
|
|
97
129
|
|
98
130
|
unless options["no-migrate"]
|
99
131
|
output += step("`rake db:migrate` was run, running all the migrations against your database.\n")
|
100
|
-
output += step("Seed
|
132
|
+
output += step("Seed account and user were loaded into your database.\n")
|
101
133
|
end
|
102
134
|
output += step("The engine was mounted in your config/routes.rb file using this line:
|
103
135
|
|
104
136
|
mount Cadenero::Engine, :at => \"/\"
|
105
137
|
|
106
|
-
If you want to change where the forums are located, just change the \"
|
138
|
+
If you want to change where the forums are located, just change the \"/\" path at the end of this line to whatever you want.")
|
107
139
|
output += %Q{\nAnd finally:
|
108
140
|
|
109
141
|
#{step("We told you that Cadenero has been successfully installed and walked you through the steps.")}}
|
110
|
-
unless defined?(Devise)
|
111
|
-
output += %Q{We have detected you're not using Devise (which is OK with us, really!), so there's one extra step you'll need to do.
|
112
|
-
|
113
|
-
You'll need to define a "sign_in_path" method for Cadenero to use that points to the sign in path for your application. You can set Cadenero.sign_in_path to a String inside config/initializers/cadenero.rb to do this, or you can define it in your config/routes.rb file with a line like this:
|
114
|
-
|
115
|
-
get '/users/sign_in', :to => "users#sign_in"
|
116
|
-
|
117
|
-
Either way, Cadenero needs one of these two things in order to work properly. Please define them!}
|
118
|
-
end
|
119
142
|
output += "\nIf you have any questions, comments or issues, please post them on our issues page: http://github.com/AgilTec/cadenero/issues.\n\n"
|
120
143
|
output += "Thanks for using Cadenero!"
|
121
144
|
puts output
|
@@ -0,0 +1,8 @@
|
|
1
|
+
@account = Cadenero::V1::Account.create!(name: 'Root Account',
|
2
|
+
subdomain: 'www',
|
3
|
+
owner: Cadenero::User.create!(email: 'testy@example.com',
|
4
|
+
password: '12345678',
|
5
|
+
password_confirmation: '12345678'))
|
6
|
+
|
7
|
+
@account.create_schema
|
8
|
+
@account.ensure_authentication_token!
|