oauth2_provider_engine 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (132) hide show
  1. data/MIT-LICENSE +20 -0
  2. data/README.rdoc +3 -0
  3. data/Rakefile +40 -0
  4. data/app/assets/javascripts/oauth2_provider/application.js +52 -0
  5. data/app/assets/javascripts/oauth2_provider/highcharts.js +162 -0
  6. data/app/assets/javascripts/oauth2_provider/jquery.tagsinput.js +218 -0
  7. data/app/assets/stylesheets/oauth2_provider/gh-buttons.css +388 -0
  8. data/app/assets/stylesheets/oauth2_provider/gh-icons.png +0 -0
  9. data/app/assets/stylesheets/oauth2_provider/jquery.tagsinput.css +6 -0
  10. data/app/assets/stylesheets/oauth2_provider/reset.css +2 -0
  11. data/app/assets/stylesheets/oauth2_provider/template.css +52 -0
  12. data/app/controllers/oauth2_provider/accesses_controller.rb +39 -0
  13. data/app/controllers/oauth2_provider/application_controller.rb +17 -0
  14. data/app/controllers/oauth2_provider/authorize_controller.rb +141 -0
  15. data/app/controllers/oauth2_provider/clients_controller.rb +85 -0
  16. data/app/controllers/oauth2_provider/scopes_controller.rb +63 -0
  17. data/app/controllers/oauth2_provider/token_controller.rb +187 -0
  18. data/app/helpers/clients_helper.rb +5 -0
  19. data/app/helpers/oauth2_provider/application_helper.rb +4 -0
  20. data/app/models/oauth2_provider/client.rb +129 -0
  21. data/app/models/oauth2_provider/document.rb +15 -0
  22. data/app/models/oauth2_provider/oauth_access.rb +80 -0
  23. data/app/models/oauth2_provider/oauth_authorization.rb +70 -0
  24. data/app/models/oauth2_provider/oauth_daily_request.rb +54 -0
  25. data/app/models/oauth2_provider/oauth_refresh_token.rb +20 -0
  26. data/app/models/oauth2_provider/oauth_token.rb +78 -0
  27. data/app/models/oauth2_provider/scope.rb +39 -0
  28. data/app/views/layouts/oauth2_provider/application.html.erb +62 -0
  29. data/app/views/oauth2_provider/accesses/index.html.erb +25 -0
  30. data/app/views/oauth2_provider/accesses/show.html.erb +35 -0
  31. data/app/views/oauth2_provider/clients/_form.html.erb +50 -0
  32. data/app/views/oauth2_provider/clients/edit.html.erb +9 -0
  33. data/app/views/oauth2_provider/clients/index.html.erb +43 -0
  34. data/app/views/oauth2_provider/clients/new.html.erb +8 -0
  35. data/app/views/oauth2_provider/clients/show.html.erb +49 -0
  36. data/app/views/oauth2_provider/scopes/_form.html.erb +35 -0
  37. data/app/views/oauth2_provider/scopes/edit.html.erb +8 -0
  38. data/app/views/oauth2_provider/scopes/index.html.erb +27 -0
  39. data/app/views/oauth2_provider/scopes/new.html.erb +7 -0
  40. data/app/views/oauth2_provider/scopes/show.html.erb +19 -0
  41. data/app/views/shared/authorize.html.erb +34 -0
  42. data/app/views/shared/token.json.erb +8 -0
  43. data/config/locales/en.yml +31 -0
  44. data/config/oauth.yml +4 -0
  45. data/config/routes.rb +25 -0
  46. data/lib/oauth2_provider.rb +38 -0
  47. data/lib/oauth2_provider/controller_mixin.rb +53 -0
  48. data/lib/oauth2_provider/engine.rb +4 -0
  49. data/lib/oauth2_provider_engine.rb +1 -0
  50. data/lib/oauth2_provider_engine/version.rb +3 -0
  51. data/test/dummy/CHANGELOG.rdoc +67 -0
  52. data/test/dummy/Gemfile +53 -0
  53. data/test/dummy/Gemfile.lock +254 -0
  54. data/test/dummy/README.rdoc +522 -0
  55. data/test/dummy/Rakefile +7 -0
  56. data/test/dummy/VERSION +1 -0
  57. data/test/dummy/app/assets/stylesheets/reset.css +2 -0
  58. data/test/dummy/app/assets/stylesheets/template.css +52 -0
  59. data/test/dummy/app/controllers/application_controller.rb +52 -0
  60. data/test/dummy/app/controllers/pastas_controller.rb +23 -0
  61. data/test/dummy/app/controllers/pizzas_controller.rb +23 -0
  62. data/test/dummy/app/controllers/sessions_controller.rb +26 -0
  63. data/test/dummy/app/controllers/users_controller.rb +59 -0
  64. data/test/dummy/app/models/user.rb +50 -0
  65. data/test/dummy/app/views/layouts/application.html.erb +65 -0
  66. data/test/dummy/app/views/sessions/new.html.erb +25 -0
  67. data/test/dummy/app/views/shared/403.json.erb +4 -0
  68. data/test/dummy/app/views/shared/404.json.erb +6 -0
  69. data/test/dummy/app/views/shared/422.json.erb +5 -0
  70. data/test/dummy/app/views/shared/500.json.erb +4 -0
  71. data/test/dummy/app/views/shared/html/404.html.erb +0 -0
  72. data/test/dummy/app/views/shared/html/422.html.erb +0 -0
  73. data/test/dummy/app/views/users/_form.html.erb +27 -0
  74. data/test/dummy/app/views/users/edit.html.erb +8 -0
  75. data/test/dummy/app/views/users/index.html.erb +20 -0
  76. data/test/dummy/app/views/users/new.html.erb +46 -0
  77. data/test/dummy/app/views/users/show.html.erb +15 -0
  78. data/test/dummy/app/views/users/show.json.erb +6 -0
  79. data/test/dummy/config.ru +4 -0
  80. data/test/dummy/config/application.rb +57 -0
  81. data/test/dummy/config/boot.rb +13 -0
  82. data/test/dummy/config/cucumber.yml +8 -0
  83. data/test/dummy/config/environment.rb +5 -0
  84. data/test/dummy/config/environments/development.rb +32 -0
  85. data/test/dummy/config/environments/production.rb +58 -0
  86. data/test/dummy/config/environments/test.rb +35 -0
  87. data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
  88. data/test/dummy/config/initializers/inflections.rb +10 -0
  89. data/test/dummy/config/initializers/mime_types.rb +5 -0
  90. data/test/dummy/config/initializers/secret_token.rb +7 -0
  91. data/test/dummy/config/initializers/session_store.rb +8 -0
  92. data/test/dummy/config/initializers/test.rb +3 -0
  93. data/test/dummy/config/locales/en.yml +1 -0
  94. data/test/dummy/config/mongoid.yml +20 -0
  95. data/test/dummy/config/routes.rb +22 -0
  96. data/test/dummy/db/seeds.rb +7 -0
  97. data/test/dummy/doc/README_FOR_APP +2 -0
  98. data/test/dummy/lib/tasks/cucumber.rake +53 -0
  99. data/test/dummy/lib/tasks/watchr.rake +5 -0
  100. data/test/dummy/public/404.html +26 -0
  101. data/test/dummy/public/422.html +26 -0
  102. data/test/dummy/public/500.html +4 -0
  103. data/test/dummy/public/favicon.ico +0 -0
  104. data/test/dummy/public/robots.txt +5 -0
  105. data/test/dummy/script/cucumber +10 -0
  106. data/test/dummy/script/rails +6 -0
  107. data/test/dummy/spec/acceptance/acceptance_helper.rb +5 -0
  108. data/test/dummy/spec/acceptance/accesses_controller_spec.rb +77 -0
  109. data/test/dummy/spec/acceptance/clients_controller_spec.rb +218 -0
  110. data/test/dummy/spec/acceptance/oauth_authorize_controller_spec.rb +241 -0
  111. data/test/dummy/spec/acceptance/oauth_token_controller_spec.rb +196 -0
  112. data/test/dummy/spec/acceptance/resource_controller_spec.rb +143 -0
  113. data/test/dummy/spec/acceptance/scopes_controller_spec.rb +227 -0
  114. data/test/dummy/spec/acceptance/support/helpers.rb +81 -0
  115. data/test/dummy/spec/acceptance/support/paths.rb +9 -0
  116. data/test/dummy/spec/acceptance/support/view_helpers.rb +52 -0
  117. data/test/dummy/spec/acceptance/users_controller_spec.rb +198 -0
  118. data/test/dummy/spec/extras/scope_spec.rb +105 -0
  119. data/test/dummy/spec/factories/oauth.rb +106 -0
  120. data/test/dummy/spec/models/oauth/client_spec.rb +123 -0
  121. data/test/dummy/spec/models/oauth/oauth_access_spec.rb +48 -0
  122. data/test/dummy/spec/models/oauth/oauth_authorization_spec.rb +50 -0
  123. data/test/dummy/spec/models/oauth/oauth_daily_request_spec.rb +14 -0
  124. data/test/dummy/spec/models/oauth/oauth_refresh_token_spec.rb +11 -0
  125. data/test/dummy/spec/models/oauth/oauth_token_spec.rb +55 -0
  126. data/test/dummy/spec/models/scope_spec.rb +17 -0
  127. data/test/dummy/spec/spec_helper.rb +39 -0
  128. data/test/dummy/spec/support/settings_helper.rb +28 -0
  129. data/test/dummy/test/initializers/capybara_headers_hack.rb +23 -0
  130. data/test/oauth2_provider_test.rb +7 -0
  131. data/test/test_helper.rb +15 -0
  132. metadata +387 -0
@@ -0,0 +1,7 @@
1
+ # Add your own tasks in files placed in lib/tasks ending in .rake,
2
+ # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
3
+
4
+ require File.expand_path('../config/application', __FILE__)
5
+ require 'rake'
6
+
7
+ Lelylan::Application.load_tasks
@@ -0,0 +1 @@
1
+ v0.3.1
@@ -0,0 +1,2 @@
1
+ html, body, div, form, p,
2
+ code, pre { margin: 0; padding: 0; border: 0; vertical-align: baseline; }
@@ -0,0 +1,52 @@
1
+ body { font: 14px/1.333 sans-serif; color: #444; background: #eee; }
2
+
3
+ a { color: #980905; }
4
+ a:hover, a:focus, a:active { text-decoration: none; }
5
+
6
+ h1 { margin: 0 0 0.2em; font-size: 36px; }
7
+ h2 { margin: 0 0 0.75em; font-size: 21px; }
8
+ h3 { margin: 0 0 0.333em; font-size: 16px; font-weight: normal; }
9
+ p { margin: 0 0 1.333em; }
10
+ em { font-style: italic; }
11
+ table { border-collapse: separate; border-spacing: 0; margin: 0; vertical-align: middle; }
12
+ th { font-weight: bold; }
13
+ th, td { padding: 5px 8px 5px 5px; text-align: left; vertical-align: middle; }
14
+ pre, code { font-family: monospace, sans-serif; font-size: 1em; color:#080; }
15
+
16
+ .container { position:relative; overflow:hidden; width: 780px; padding: 40px 60px; border: 1px solid #ccc; margin: 40px auto 20px; background: #fff; -webkit-box-shadow: 0 0 15px rgba(0,0,0,0.1); -moz-box-shadow: 0 0 15px rgba(0,0,0,0.1); box-shadow: 0 0 15px rgba(0,0,0,0.1); }
17
+
18
+ .container pre,
19
+ .container .prettyprint { padding: 0; border: 0; margin: 0 0 20px; font-size: 13px; background: #fff; }
20
+
21
+ .ribbon { position: absolute; top: -1px; right: -1px; opacity: 0.9; }
22
+ .ribbon:hover, .ribbon:focus, .ribbon:active { opacity: 1; }
23
+ .ribbon img { display: block; border: 0; }
24
+
25
+ .header { padding-right:80px; }
26
+ .header, .navigation { border-bottom: 1px solid #ccc; }
27
+ .navigation { padding: 10px; margin: 0px; background-color: #EEE }
28
+
29
+ .section { margin: 40px 0 20px; }
30
+
31
+ .example { padding: 20px; border: 1px solid #ccc; margin: 10px -20px 20px; }
32
+
33
+ .footer { margin: 20px 0 50px; font-size: 11px; color: #666; text-align: center; }
34
+ .footer a { color: #666; }
35
+
36
+ .field, .actions { margin: 0 0 1.333em; }
37
+ .field_show { margin: 0 0 0.666em; }
38
+
39
+ .admin_notice { color: green }
40
+ .details { color: #CCC; padding: 5px 0 }
41
+
42
+ .header_buttons { margin: -8px 0px 20px 0px }
43
+ .footer_buttons { margin: 1em 0 0 0 }
44
+
45
+ .flash_notice { margin: 0 0 1em 0; color: green; font-weight: bold }
46
+ .flash_alert { margin: 0 0 1em 0; color: #980905; font-weight: bold }
47
+
48
+ .field input { width: 300px; height: 25px; font: 14px/1.333 sans-serif; padding-left: 4px; }
49
+ .field input { border: 1px solid #CCC; }
50
+
51
+ #grant, #deny { padding: 5px 0px }
52
+ .green { color: green }
@@ -0,0 +1,52 @@
1
+ class ApplicationController < ActionController::Base
2
+ include Oauth2Provider::ControllerMixin
3
+
4
+ protect_from_forgery
5
+
6
+ before_filter :authenticate
7
+ helper_method :current_user
8
+ helper_method :admin_does_not_exist
9
+
10
+ rescue_from BSON::InvalidObjectId, with: :bson_invalid_object_id
11
+ rescue_from JSON::ParserError, with: :json_parse_error
12
+ rescue_from Mongoid::Errors::InvalidType, with: :mongoid_errors_invalid_type
13
+
14
+ protected
15
+
16
+ def authenticate
17
+ if api_request
18
+ oauth_authorized # uncomment to make all json API protected
19
+ else
20
+ session_auth
21
+ end
22
+ end
23
+
24
+ def session_auth
25
+ @current_user ||= User.where(:_id => session[:user_id]).first if session[:user_id]
26
+ unless current_user
27
+ session[:back] = request.url
28
+ redirect_to(log_in_path) and return false
29
+ end
30
+ return @current_user
31
+ end
32
+
33
+ def current_user
34
+ @current_user
35
+ end
36
+
37
+ def admin_does_not_exist
38
+ User.where(admin: true).first.nil?
39
+ end
40
+
41
+ def bson_invalid_object_id(e)
42
+ redirect_to root_path, alert: "Resource not found."
43
+ end
44
+
45
+ def json_parse_error(e)
46
+ redirect_to root_path, alert: "Json not valid"
47
+ end
48
+
49
+ def mongoid_errors_invalid_type(e)
50
+ redirect_to root_path, alert: "Json values is not an array"
51
+ end
52
+ end
@@ -0,0 +1,23 @@
1
+ class PastasController < ApplicationController
2
+ before_filter :oauth_authorized
3
+
4
+ def index
5
+ render json: {action: :index}
6
+ end
7
+
8
+ def show
9
+ render json: {action: :show}
10
+ end
11
+
12
+ def create
13
+ render json: {action: :create}
14
+ end
15
+
16
+ def update
17
+ render json: {action: :update}
18
+ end
19
+
20
+ def destroy
21
+ render json: {action: :destroy}
22
+ end
23
+ end
@@ -0,0 +1,23 @@
1
+ class PizzasController < ApplicationController
2
+ before_filter :oauth_authorized
3
+
4
+ def index
5
+ render json: {action: :index}
6
+ end
7
+
8
+ def show
9
+ render json: {action: :show}
10
+ end
11
+
12
+ def create
13
+ render json: {action: :create}
14
+ end
15
+
16
+ def update
17
+ render json: {action: :update}
18
+ end
19
+
20
+ def destroy
21
+ render json: {action: :destroy}
22
+ end
23
+ end
@@ -0,0 +1,26 @@
1
+ class SessionsController < ApplicationController
2
+
3
+ skip_before_filter :authenticate
4
+
5
+ def new
6
+ end
7
+
8
+ def create
9
+ user = User.authenticate(params[:email], params[:password])
10
+ if user
11
+ session[:user_id] = user.id
12
+ session[:back] ||= user_path(user)
13
+ redirect_to session[:back], notice: "Logged in!"
14
+ session[:back] = nil
15
+ else
16
+ flash.now.alert = "Invalid email or password"
17
+ render "new"
18
+ end
19
+ end
20
+
21
+ def destroy
22
+ session[:user_id] = nil
23
+ redirect_to root_url, :notice => "Logged out!"
24
+ end
25
+
26
+ end
@@ -0,0 +1,59 @@
1
+ class UsersController < ApplicationController
2
+
3
+ skip_before_filter :authenticate, only: ["new", "create"]
4
+ before_filter :admin?, only: ["index"]
5
+ before_filter :find_user, only: ["show", "edit", "update", "destroy"]
6
+
7
+ def index
8
+ @users = User.all
9
+ end
10
+
11
+ def show
12
+ end
13
+
14
+ def new
15
+ @user = User.new
16
+ end
17
+
18
+ def create
19
+ @user = User.new(params[:user])
20
+ @user.admin = true if admin_does_not_exist
21
+ if @user.save
22
+ redirect_to root_url, :notice => "Signed up!"
23
+ else
24
+ render "new"
25
+ end
26
+ end
27
+
28
+ def edit
29
+ end
30
+
31
+ def update
32
+ params[:user].delete_if { |key, value| key == "password" and value.empty? }
33
+ if @user.update_attributes(params[:user])
34
+ render "show"
35
+ else
36
+ render action: "edit"
37
+ end
38
+ end
39
+
40
+
41
+ private
42
+
43
+ def find_user
44
+ @user = current_user.admin? ? User.criteria : User.where(_id: current_user.id.to_s)
45
+ @user = @user.where(_id: params[:id]).first
46
+ unless @user
47
+ redirect_to root_path, alert: "Resource not found."
48
+ end
49
+ end
50
+
51
+ def admin?
52
+ unless current_user.admin?
53
+ flash.alert = "Unauthorized access."
54
+ redirect_to root_path
55
+ return false
56
+ end
57
+ end
58
+
59
+ end
@@ -0,0 +1,50 @@
1
+ class User
2
+ include Mongoid::Document
3
+ include Mongoid::Timestamps
4
+
5
+ field :email
6
+ field :name
7
+ field :password_hash
8
+ field :password_salt
9
+ field :admin, type: Boolean, default: false
10
+
11
+ attr_accessible :email, :name, :password
12
+
13
+ attr_accessor :password
14
+ before_save :encrypt_password
15
+
16
+ validates :password, presence: true, on: :create
17
+ # TODO: add password length
18
+ #validates :password, length: {min: 6}, empty: true
19
+ validates :email, presence: true
20
+ validates :email, uniqueness: true
21
+ validates :email, email: true
22
+
23
+ def self.authenticate(email, password)
24
+ user = where(email: email).first
25
+ user.verify(password) if user
26
+ end
27
+
28
+ def verify(password)
29
+ if password_hash == BCrypt::Engine.hash_secret(password, password_salt)
30
+ self
31
+ else
32
+ nil
33
+ end
34
+ end
35
+
36
+ def encrypt_password
37
+ if password.present?
38
+ self.password_salt = BCrypt::Engine.generate_salt
39
+ self.password_hash = BCrypt::Engine.hash_secret(password, password_salt)
40
+ end
41
+ end
42
+
43
+ def admin?
44
+ self.admin
45
+ end
46
+
47
+ def self.find_by_id(id)
48
+ self.where(:_id => id).first
49
+ end
50
+ end
@@ -0,0 +1,65 @@
1
+ <!DOCTYPE html>
2
+ <html>
3
+ <head>
4
+ <meta charset="utf-8">
5
+ <title>Rest OAuth 2.0 Server</title>
6
+ <%= stylesheet_link_tag :reset, :template %>
7
+ <%= csrf_meta_tag %>
8
+ </head>
9
+
10
+ <body">
11
+ <div class="container">
12
+ <a class="ribbon" href="https://github.com/lelylan/rest-oauth2-server" target="_blank"><img src="http://s3.amazonaws.com/github/ribbons/forkme_right_red_aa0000.png" alt="Fork me on GitHub"></a>
13
+
14
+ <div class="header">
15
+ <h1>Rest OAuth 2.0 Server</h1>
16
+ <p>
17
+ <b><a href="https://github.com/lelylan/rest-oauth2-server" title="GitHub repository">Rest OAuth 2.0 Server</a>
18
+ let you open up your API and manage end-user authentication and client application authorization
19
+ implementing the OAuth 2.0 Specifications (draft 13). Read more on <a href="https://github.com/lelylan/rest-oauth2-server" title="GitHub readme">Github</a>
20
+ </b>
21
+ </p>
22
+ </div>
23
+ <div class="navigation">
24
+ <% if current_user %>
25
+ <div style="float: right">
26
+ Logged in as <%= current_user.email %>.
27
+ <%= link_to "Log out", log_out_path %>
28
+ </div>
29
+ <div>
30
+ <%= link_to("Home", current_user) %>
31
+ <% if current_user.admin? %> |
32
+ <%= link_to("Users", users_path) %> |
33
+ <%= link_to("OAuth", oauth2_provider_engine.oauth2_provider_root_path) %> |
34
+ <% end %>
35
+ </div>
36
+ <% else %>
37
+ <%= link_to "Sign up", sign_up_path %> or
38
+ <%= link_to "log in", log_in_path %>
39
+ <% end %>
40
+ </div>
41
+ <br/>
42
+
43
+
44
+ <% if flash.notice %>
45
+ <div class="flash_notice">
46
+ <%= flash.notice %>
47
+ </div>
48
+ <% end %>
49
+
50
+ <% if flash.alert %>
51
+ <div class=flash_alert>
52
+ <%= flash.alert %>
53
+ <% if @info %>
54
+ <p>Additional information:
55
+ <%= @info.to_json%>
56
+ </p>
57
+ <% end %>
58
+ </div>
59
+ <% end %>
60
+
61
+ <%= yield %>
62
+
63
+ </div>
64
+ </body>
65
+ </html>
@@ -0,0 +1,25 @@
1
+ <html>
2
+ <head></head>
3
+ <body>
4
+ <h2>Log in</h2>
5
+
6
+ <%= form_tag sessions_path do %>
7
+ <div class="field">
8
+ <%= label_tag :email %><br />
9
+ <%= text_field_tag :email, params[:email] %>
10
+ </div>
11
+
12
+ <div class="field">
13
+ <%= label_tag :password %><br />
14
+ <%= password_field_tag :password %>
15
+ </div>
16
+
17
+ <div class="actions">
18
+ <%= submit_tag "Log in", class: "button" %>
19
+ </div>
20
+ <% end %>
21
+
22
+ </body>
23
+ </html>
24
+
25
+
@@ -0,0 +1,4 @@
1
+ {
2
+ "request" => "<%=request.url%>",
3
+ "message" => "to define"
4
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "request": "<%=raw request.url%>",
3
+ "message": "<%=raw @message%>",
4
+ "info": "<%=@info%>"
5
+ }
6
+
@@ -0,0 +1,5 @@
1
+ {
2
+ "request": "<%=raw request.url%>",
3
+ "message": "<%=raw @message%>",
4
+ "info": <%=raw @info%>
5
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "request": "<%=request.url%>",
3
+ "message": "<%=@message%>"
4
+ }
@@ -0,0 +1,27 @@
1
+ <%= form_for(@user) do |f| %>
2
+
3
+ <% if @user.errors.any? %>
4
+ <div id="error_explanation">
5
+ <div><%= pluralize(@user.errors.count, "error") %> prohibited this resource from being saved</div>
6
+ <ul>
7
+ <% @user.errors.full_messages.each do |msg| %>
8
+ <li><%= msg %></li>
9
+ <% end %>
10
+ </ul>
11
+ </div>
12
+ <% end %>
13
+
14
+ <div class="field">
15
+ <%= f.label :name%><br />
16
+ <%= f.text_field :name%>
17
+ </div>
18
+
19
+ <div class="field">
20
+ <%= f.label :password %><br />
21
+ <%= f.text_field :password %>
22
+ </div>
23
+
24
+ <div class="actions">
25
+ <%= f.submit nil, {class: "button"} %>
26
+ </div>
27
+ <% end %>