oauth2_provider_engine 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.rdoc +3 -0
- data/Rakefile +40 -0
- data/app/assets/javascripts/oauth2_provider/application.js +52 -0
- data/app/assets/javascripts/oauth2_provider/highcharts.js +162 -0
- data/app/assets/javascripts/oauth2_provider/jquery.tagsinput.js +218 -0
- data/app/assets/stylesheets/oauth2_provider/gh-buttons.css +388 -0
- data/app/assets/stylesheets/oauth2_provider/gh-icons.png +0 -0
- data/app/assets/stylesheets/oauth2_provider/jquery.tagsinput.css +6 -0
- data/app/assets/stylesheets/oauth2_provider/reset.css +2 -0
- data/app/assets/stylesheets/oauth2_provider/template.css +52 -0
- data/app/controllers/oauth2_provider/accesses_controller.rb +39 -0
- data/app/controllers/oauth2_provider/application_controller.rb +17 -0
- data/app/controllers/oauth2_provider/authorize_controller.rb +141 -0
- data/app/controllers/oauth2_provider/clients_controller.rb +85 -0
- data/app/controllers/oauth2_provider/scopes_controller.rb +63 -0
- data/app/controllers/oauth2_provider/token_controller.rb +187 -0
- data/app/helpers/clients_helper.rb +5 -0
- data/app/helpers/oauth2_provider/application_helper.rb +4 -0
- data/app/models/oauth2_provider/client.rb +129 -0
- data/app/models/oauth2_provider/document.rb +15 -0
- data/app/models/oauth2_provider/oauth_access.rb +80 -0
- data/app/models/oauth2_provider/oauth_authorization.rb +70 -0
- data/app/models/oauth2_provider/oauth_daily_request.rb +54 -0
- data/app/models/oauth2_provider/oauth_refresh_token.rb +20 -0
- data/app/models/oauth2_provider/oauth_token.rb +78 -0
- data/app/models/oauth2_provider/scope.rb +39 -0
- data/app/views/layouts/oauth2_provider/application.html.erb +62 -0
- data/app/views/oauth2_provider/accesses/index.html.erb +25 -0
- data/app/views/oauth2_provider/accesses/show.html.erb +35 -0
- data/app/views/oauth2_provider/clients/_form.html.erb +50 -0
- data/app/views/oauth2_provider/clients/edit.html.erb +9 -0
- data/app/views/oauth2_provider/clients/index.html.erb +43 -0
- data/app/views/oauth2_provider/clients/new.html.erb +8 -0
- data/app/views/oauth2_provider/clients/show.html.erb +49 -0
- data/app/views/oauth2_provider/scopes/_form.html.erb +35 -0
- data/app/views/oauth2_provider/scopes/edit.html.erb +8 -0
- data/app/views/oauth2_provider/scopes/index.html.erb +27 -0
- data/app/views/oauth2_provider/scopes/new.html.erb +7 -0
- data/app/views/oauth2_provider/scopes/show.html.erb +19 -0
- data/app/views/shared/authorize.html.erb +34 -0
- data/app/views/shared/token.json.erb +8 -0
- data/config/locales/en.yml +31 -0
- data/config/oauth.yml +4 -0
- data/config/routes.rb +25 -0
- data/lib/oauth2_provider.rb +38 -0
- data/lib/oauth2_provider/controller_mixin.rb +53 -0
- data/lib/oauth2_provider/engine.rb +4 -0
- data/lib/oauth2_provider_engine.rb +1 -0
- data/lib/oauth2_provider_engine/version.rb +3 -0
- data/test/dummy/CHANGELOG.rdoc +67 -0
- data/test/dummy/Gemfile +53 -0
- data/test/dummy/Gemfile.lock +254 -0
- data/test/dummy/README.rdoc +522 -0
- data/test/dummy/Rakefile +7 -0
- data/test/dummy/VERSION +1 -0
- data/test/dummy/app/assets/stylesheets/reset.css +2 -0
- data/test/dummy/app/assets/stylesheets/template.css +52 -0
- data/test/dummy/app/controllers/application_controller.rb +52 -0
- data/test/dummy/app/controllers/pastas_controller.rb +23 -0
- data/test/dummy/app/controllers/pizzas_controller.rb +23 -0
- data/test/dummy/app/controllers/sessions_controller.rb +26 -0
- data/test/dummy/app/controllers/users_controller.rb +59 -0
- data/test/dummy/app/models/user.rb +50 -0
- data/test/dummy/app/views/layouts/application.html.erb +65 -0
- data/test/dummy/app/views/sessions/new.html.erb +25 -0
- data/test/dummy/app/views/shared/403.json.erb +4 -0
- data/test/dummy/app/views/shared/404.json.erb +6 -0
- data/test/dummy/app/views/shared/422.json.erb +5 -0
- data/test/dummy/app/views/shared/500.json.erb +4 -0
- data/test/dummy/app/views/shared/html/404.html.erb +0 -0
- data/test/dummy/app/views/shared/html/422.html.erb +0 -0
- data/test/dummy/app/views/users/_form.html.erb +27 -0
- data/test/dummy/app/views/users/edit.html.erb +8 -0
- data/test/dummy/app/views/users/index.html.erb +20 -0
- data/test/dummy/app/views/users/new.html.erb +46 -0
- data/test/dummy/app/views/users/show.html.erb +15 -0
- data/test/dummy/app/views/users/show.json.erb +6 -0
- data/test/dummy/config.ru +4 -0
- data/test/dummy/config/application.rb +57 -0
- data/test/dummy/config/boot.rb +13 -0
- data/test/dummy/config/cucumber.yml +8 -0
- data/test/dummy/config/environment.rb +5 -0
- data/test/dummy/config/environments/development.rb +32 -0
- data/test/dummy/config/environments/production.rb +58 -0
- data/test/dummy/config/environments/test.rb +35 -0
- data/test/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/test/dummy/config/initializers/inflections.rb +10 -0
- data/test/dummy/config/initializers/mime_types.rb +5 -0
- data/test/dummy/config/initializers/secret_token.rb +7 -0
- data/test/dummy/config/initializers/session_store.rb +8 -0
- data/test/dummy/config/initializers/test.rb +3 -0
- data/test/dummy/config/locales/en.yml +1 -0
- data/test/dummy/config/mongoid.yml +20 -0
- data/test/dummy/config/routes.rb +22 -0
- data/test/dummy/db/seeds.rb +7 -0
- data/test/dummy/doc/README_FOR_APP +2 -0
- data/test/dummy/lib/tasks/cucumber.rake +53 -0
- data/test/dummy/lib/tasks/watchr.rake +5 -0
- data/test/dummy/public/404.html +26 -0
- data/test/dummy/public/422.html +26 -0
- data/test/dummy/public/500.html +4 -0
- data/test/dummy/public/favicon.ico +0 -0
- data/test/dummy/public/robots.txt +5 -0
- data/test/dummy/script/cucumber +10 -0
- data/test/dummy/script/rails +6 -0
- data/test/dummy/spec/acceptance/acceptance_helper.rb +5 -0
- data/test/dummy/spec/acceptance/accesses_controller_spec.rb +77 -0
- data/test/dummy/spec/acceptance/clients_controller_spec.rb +218 -0
- data/test/dummy/spec/acceptance/oauth_authorize_controller_spec.rb +241 -0
- data/test/dummy/spec/acceptance/oauth_token_controller_spec.rb +196 -0
- data/test/dummy/spec/acceptance/resource_controller_spec.rb +143 -0
- data/test/dummy/spec/acceptance/scopes_controller_spec.rb +227 -0
- data/test/dummy/spec/acceptance/support/helpers.rb +81 -0
- data/test/dummy/spec/acceptance/support/paths.rb +9 -0
- data/test/dummy/spec/acceptance/support/view_helpers.rb +52 -0
- data/test/dummy/spec/acceptance/users_controller_spec.rb +198 -0
- data/test/dummy/spec/extras/scope_spec.rb +105 -0
- data/test/dummy/spec/factories/oauth.rb +106 -0
- data/test/dummy/spec/models/oauth/client_spec.rb +123 -0
- data/test/dummy/spec/models/oauth/oauth_access_spec.rb +48 -0
- data/test/dummy/spec/models/oauth/oauth_authorization_spec.rb +50 -0
- data/test/dummy/spec/models/oauth/oauth_daily_request_spec.rb +14 -0
- data/test/dummy/spec/models/oauth/oauth_refresh_token_spec.rb +11 -0
- data/test/dummy/spec/models/oauth/oauth_token_spec.rb +55 -0
- data/test/dummy/spec/models/scope_spec.rb +17 -0
- data/test/dummy/spec/spec_helper.rb +39 -0
- data/test/dummy/spec/support/settings_helper.rb +28 -0
- data/test/dummy/test/initializers/capybara_headers_hack.rb +23 -0
- data/test/oauth2_provider_test.rb +7 -0
- data/test/test_helper.rb +15 -0
- metadata +387 -0
data/test/dummy/Rakefile
ADDED
@@ -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
|
data/test/dummy/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
v0.3.1
|
@@ -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
|
+
|
File without changes
|
File without changes
|
@@ -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 %>
|