added authentication and everything
This commit is contained in:
parent
b45be30b19
commit
7641726677
1
Gemfile
1
Gemfile
|
@ -46,3 +46,4 @@ gem 'will_paginate'
|
||||||
gem 'will_paginate-bootstrap'
|
gem 'will_paginate-bootstrap'
|
||||||
gem 'http_accept_language'
|
gem 'http_accept_language'
|
||||||
gem 'devise'
|
gem 'devise'
|
||||||
|
gem 'bootstrap_form'
|
||||||
|
|
|
@ -31,6 +31,7 @@ GEM
|
||||||
bcrypt (3.1.7)
|
bcrypt (3.1.7)
|
||||||
bootstrap-sass (3.2.0.1)
|
bootstrap-sass (3.2.0.1)
|
||||||
sass (~> 3.2)
|
sass (~> 3.2)
|
||||||
|
bootstrap_form (2.1.1)
|
||||||
bootswatch-rails (3.2.0)
|
bootswatch-rails (3.2.0)
|
||||||
railties (>= 3.1)
|
railties (>= 3.1)
|
||||||
builder (3.2.2)
|
builder (3.2.2)
|
||||||
|
@ -140,6 +141,7 @@ PLATFORMS
|
||||||
|
|
||||||
DEPENDENCIES
|
DEPENDENCIES
|
||||||
bootstrap-sass (~> 3.2.0.1)
|
bootstrap-sass (~> 3.2.0.1)
|
||||||
|
bootstrap_form
|
||||||
bootswatch-rails (~> 3.2.0)
|
bootswatch-rails (~> 3.2.0)
|
||||||
coffee-rails (~> 4.0.0)
|
coffee-rails (~> 4.0.0)
|
||||||
devise
|
devise
|
||||||
|
|
|
@ -1,4 +1,5 @@
|
||||||
#= require jquery
|
#= require jquery
|
||||||
#= require jquery_ujs
|
#= require jquery_ujs
|
||||||
#= require turbolinks
|
#= require turbolinks
|
||||||
|
#= require bootstrap
|
||||||
#= require_tree .
|
#= require_tree .
|
||||||
|
|
|
@ -1,3 +1,7 @@
|
||||||
|
/*
|
||||||
|
*= require rails_bootstrap_forms
|
||||||
|
*= require_self
|
||||||
|
*/
|
||||||
@import "bootswatch/flatly/variables";
|
@import "bootswatch/flatly/variables";
|
||||||
@import "bootstrap";
|
@import "bootstrap";
|
||||||
body { padding-top: $navbar-height; }
|
body { padding-top: $navbar-height; }
|
||||||
|
|
|
@ -2,4 +2,14 @@ class ApplicationController < ActionController::Base
|
||||||
# Prevent CSRF attacks by raising an exception.
|
# Prevent CSRF attacks by raising an exception.
|
||||||
# For APIs, you may want to use :null_session instead.
|
# For APIs, you may want to use :null_session instead.
|
||||||
protect_from_forgery with: :exception
|
protect_from_forgery with: :exception
|
||||||
|
|
||||||
|
before_filter :configure_permitted_parameters, if: :devise_controller?
|
||||||
|
|
||||||
|
protected
|
||||||
|
|
||||||
|
def configure_permitted_parameters
|
||||||
|
devise_parameter_sanitizer.for(:sign_up) { |u| u.permit(:screen_name, :email, :password, :password_confirmation, :remember_me) }
|
||||||
|
devise_parameter_sanitizer.for(:sign_in) { |u| u.permit(:login, :screen_name, :email, :password, :remember_me) }
|
||||||
|
devise_parameter_sanitizer.for(:account_update) { |u| u.permit(:screen_name, :email, :password, :password_confirmation, :current_password) }
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,2 +1,18 @@
|
||||||
module ApplicationHelper
|
module ApplicationHelper
|
||||||
|
def nav_entry(body, path)
|
||||||
|
content_tag(:li, link_to(body, path), class: ('active' if current_page? path))
|
||||||
|
end
|
||||||
|
|
||||||
|
##
|
||||||
|
#
|
||||||
|
def bootstrap_color c
|
||||||
|
case c
|
||||||
|
when "error", "alert"
|
||||||
|
"danger"
|
||||||
|
when "notice"
|
||||||
|
"info"
|
||||||
|
else
|
||||||
|
c
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -2,5 +2,29 @@ class User < ActiveRecord::Base
|
||||||
# Include default devise modules. Others available are:
|
# Include default devise modules. Others available are:
|
||||||
# :confirmable, :lockable, :timeoutable and :omniauthable
|
# :confirmable, :lockable, :timeoutable and :omniauthable
|
||||||
devise :database_authenticatable, :registerable,
|
devise :database_authenticatable, :registerable,
|
||||||
:recoverable, :rememberable, :trackable, :validatable
|
:recoverable, :rememberable, :trackable,
|
||||||
|
:validatable, :authentication_keys => [:login]
|
||||||
|
|
||||||
|
# attr_accessor :login
|
||||||
|
|
||||||
|
SCREEN_NAME_REGEX = /\A[a-zA-Z0-9_]{1,16}\z/
|
||||||
|
|
||||||
|
validates :screen_name, presence: true, format: { with: SCREEN_NAME_REGEX }, uniqueness: { case_sensitive: false }
|
||||||
|
|
||||||
|
def login=(login)
|
||||||
|
@login = login
|
||||||
|
end
|
||||||
|
|
||||||
|
def login
|
||||||
|
@login || self.screen_name || self.email
|
||||||
|
end
|
||||||
|
|
||||||
|
def self.find_first_by_auth_conditions(warden_conditions)
|
||||||
|
conditions = warden_conditions.dup
|
||||||
|
if login = conditions.delete(:login)
|
||||||
|
where(conditions).where(["lower(screen_name) = :value OR lower(email) = :value", { :value => login.downcase }]).first
|
||||||
|
else
|
||||||
|
where(conditions).first
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
<h2>Resend confirmation instructions</h2>
|
||||||
|
|
||||||
|
<%= form_for(resource, as: resource_name, url: confirmation_path(resource_name), html: { method: :post }) do |f| %>
|
||||||
|
<%= devise_error_messages! %>
|
||||||
|
|
||||||
|
<div><%= f.label :screen_name %><br />
|
||||||
|
<%= f.email_field :screen_name, autofocus: true %></div>
|
||||||
|
|
||||||
|
<div><%= f.submit "Resend confirmation instructions" %></div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= render "devise/shared/links" %>
|
|
@ -0,0 +1,5 @@
|
||||||
|
<p>Welcome <%= @screen_name %>!</p>
|
||||||
|
|
||||||
|
<p>You can confirm your account email through the link below:</p>
|
||||||
|
|
||||||
|
<p><%= link_to 'Confirm my account', confirmation_url(@resource, confirmation_token: @token) %></p>
|
|
@ -0,0 +1,8 @@
|
||||||
|
<p>Hello <%= @resource.email %>!</p>
|
||||||
|
|
||||||
|
<p>Someone has requested a link to change your password. You can do this through the link below.</p>
|
||||||
|
|
||||||
|
<p><%= link_to 'Change my password', edit_password_url(@resource, reset_password_token: @token) %></p>
|
||||||
|
|
||||||
|
<p>If you didn't request this, please ignore this email.</p>
|
||||||
|
<p>Your password won't change until you access the link above and create a new one.</p>
|
|
@ -0,0 +1,7 @@
|
||||||
|
<p>Hello <%= @resource.email %>!</p>
|
||||||
|
|
||||||
|
<p>Your account has been locked due to an excessive number of unsuccessful sign in attempts.</p>
|
||||||
|
|
||||||
|
<p>Click the link below to unlock your account:</p>
|
||||||
|
|
||||||
|
<p><%= link_to 'Unlock my account', unlock_url(@resource, unlock_token: @token) %></p>
|
|
@ -0,0 +1,16 @@
|
||||||
|
<h2>Change your password</h2>
|
||||||
|
|
||||||
|
<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :put }) do |f| %>
|
||||||
|
<%= devise_error_messages! %>
|
||||||
|
<%= f.hidden_field :reset_password_token %>
|
||||||
|
|
||||||
|
<div><%= f.label :password, "New password" %><br />
|
||||||
|
<%= f.password_field :password, autofocus: true, autocomplete: "off" %></div>
|
||||||
|
|
||||||
|
<div><%= f.label :password_confirmation, "Confirm new password" %><br />
|
||||||
|
<%= f.password_field :password_confirmation, autocomplete: "off" %></div>
|
||||||
|
|
||||||
|
<div><%= f.submit "Change my password" %></div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= render "devise/shared/links" %>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<h2>Forgot your password?</h2>
|
||||||
|
|
||||||
|
<%= form_for(resource, as: resource_name, url: password_path(resource_name), html: { method: :post }) do |f| %>
|
||||||
|
<%= devise_error_messages! %>
|
||||||
|
|
||||||
|
<div><%= f.label :screen_name %><br />
|
||||||
|
<%= f.email_field :screen_name, autofocus: true %></div>
|
||||||
|
|
||||||
|
<div><%= f.submit "Send me reset password instructions" %></div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= render "devise/shared/links" %>
|
|
@ -0,0 +1,31 @@
|
||||||
|
<h2>Edit <%= resource_name.to_s.humanize %></h2>
|
||||||
|
|
||||||
|
<%= form_for(resource, as: resource_name, url: registration_path(resource_name), html: { method: :put }) do |f| %>
|
||||||
|
<%= devise_error_messages! %>
|
||||||
|
|
||||||
|
<div><%= f.label :screen_name %><br />
|
||||||
|
<%= f.email_field :screen_name, autofocus: true %></div>
|
||||||
|
<div><%= f.label :email %><br />
|
||||||
|
<%= f.email_field :email %></div>
|
||||||
|
|
||||||
|
<% if devise_mapping.confirmable? && resource.pending_reconfirmation? %>
|
||||||
|
<div>Currently waiting confirmation for: <%= resource.unconfirmed_email %></div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<div><%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br />
|
||||||
|
<%= f.password_field :password, autocomplete: "off" %></div>
|
||||||
|
|
||||||
|
<div><%= f.label :password_confirmation %><br />
|
||||||
|
<%= f.password_field :password_confirmation, autocomplete: "off" %></div>
|
||||||
|
|
||||||
|
<div><%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br />
|
||||||
|
<%= f.password_field :current_password, autocomplete: "off" %></div>
|
||||||
|
|
||||||
|
<div><%= f.submit "Update" %></div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<h3>Cancel my account</h3>
|
||||||
|
|
||||||
|
<p>Unhappy? <%= button_to "Cancel my account", registration_path(resource_name), data: { confirm: "Are you sure?" }, method: :delete %></p>
|
||||||
|
|
||||||
|
<%= link_to "Back", :back %>
|
|
@ -0,0 +1,15 @@
|
||||||
|
.container
|
||||||
|
%h1 Sign up
|
||||||
|
|
||||||
|
= bootstrap_form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f|
|
||||||
|
= devise_error_messages!
|
||||||
|
|
||||||
|
= f.text_field :screen_name, autofocus: true, label: "User name"
|
||||||
|
= f.email_field :email, autofocus: false, label: "Email address"
|
||||||
|
|
||||||
|
= f.password_field :password, autocomplete: "off", label: "Password"
|
||||||
|
= f.password_field :password_confirmation, autocomplete: "off", label: "Confirm password"
|
||||||
|
|
||||||
|
= f.submit "Sign up"
|
||||||
|
|
||||||
|
= render "devise/shared/links"
|
|
@ -0,0 +1,15 @@
|
||||||
|
.container
|
||||||
|
%h1 Sign in
|
||||||
|
= render 'layouts/messages'
|
||||||
|
|
||||||
|
= bootstrap_form_for(resource, as: resource_name, url: session_path(resource_name)) do |f|
|
||||||
|
|
||||||
|
= f.text_field :login, autofocus: true, label: "User name"
|
||||||
|
= f.password_field :password, autocomplete: "off", label: "Password"
|
||||||
|
|
||||||
|
- if devise_mapping.rememberable?
|
||||||
|
= f.check_box :remember_me
|
||||||
|
|
||||||
|
= f.submit "Sign in"
|
||||||
|
|
||||||
|
= render "devise/shared/links"
|
|
@ -0,0 +1,25 @@
|
||||||
|
<%- if controller_name != 'sessions' %>
|
||||||
|
<%= link_to "Sign in", new_session_path(resource_name) %><br />
|
||||||
|
<% end -%>
|
||||||
|
|
||||||
|
<%- if devise_mapping.registerable? && controller_name != 'registrations' %>
|
||||||
|
<%= link_to "Sign up", new_registration_path(resource_name) %><br />
|
||||||
|
<% end -%>
|
||||||
|
|
||||||
|
<%- if devise_mapping.recoverable? && controller_name != 'passwords' && controller_name != 'registrations' %>
|
||||||
|
<%= link_to "Forgot your password?", new_password_path(resource_name) %><br />
|
||||||
|
<% end -%>
|
||||||
|
|
||||||
|
<%- if devise_mapping.confirmable? && controller_name != 'confirmations' %>
|
||||||
|
<%= link_to "Didn't receive confirmation instructions?", new_confirmation_path(resource_name) %><br />
|
||||||
|
<% end -%>
|
||||||
|
|
||||||
|
<%- if devise_mapping.lockable? && resource_class.unlock_strategy_enabled?(:email) && controller_name != 'unlocks' %>
|
||||||
|
<%= link_to "Didn't receive unlock instructions?", new_unlock_path(resource_name) %><br />
|
||||||
|
<% end -%>
|
||||||
|
|
||||||
|
<%- if devise_mapping.omniauthable? %>
|
||||||
|
<%- resource_class.omniauth_providers.each do |provider| %>
|
||||||
|
<%= link_to "Sign in with #{provider.to_s.titleize}", omniauth_authorize_path(resource_name, provider) %><br />
|
||||||
|
<% end -%>
|
||||||
|
<% end -%>
|
|
@ -0,0 +1,12 @@
|
||||||
|
<h2>Resend unlock instructions</h2>
|
||||||
|
|
||||||
|
<%= form_for(resource, as: resource_name, url: unlock_path(resource_name), html: { method: :post }) do |f| %>
|
||||||
|
<%= devise_error_messages! %>
|
||||||
|
|
||||||
|
<div><%= f.label :email %><br />
|
||||||
|
<%= f.email_field :email, autofocus: true %></div>
|
||||||
|
|
||||||
|
<div><%= f.submit "Resend unlock instructions" %></div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<%= render "devise/shared/links" %>
|
|
@ -0,0 +1,26 @@
|
||||||
|
%nav.navbar.navbar-default.navbar-fixed-top{role: "navigation"}
|
||||||
|
.container
|
||||||
|
.navbar-header
|
||||||
|
%button.navbar-toggle{"data-target" => "#j2-main-navbar-collapse", "data-toggle" => "collapse", type: "button"}
|
||||||
|
%span.sr-only Toggle navigation
|
||||||
|
%span.icon-bar
|
||||||
|
%span.icon-bar
|
||||||
|
%span.icon-bar
|
||||||
|
%a.navbar-brand{href: "/"} justask2
|
||||||
|
#j2-main-navbar-collapse.collapse.navbar-collapse
|
||||||
|
%ul.nav.navbar-nav
|
||||||
|
= nav_entry "Front", "/"
|
||||||
|
%ul.nav.navbar-nav.navbar-right
|
||||||
|
- if user_signed_in?
|
||||||
|
%li.dropdown
|
||||||
|
%a.dropdown-toggle{href: "#", "data-toggle" => "dropdown"}
|
||||||
|
thsdfjhkl
|
||||||
|
%b.caret
|
||||||
|
%ul.dropdown-menu
|
||||||
|
%li= link_to "Profile", edit_user_registration_path
|
||||||
|
%li= link_to "Settings", "#"
|
||||||
|
%li.divider
|
||||||
|
%li= link_to "Logout", destroy_user_session_path, method: :delete
|
||||||
|
- else
|
||||||
|
= nav_entry "Sign in", new_user_session_path
|
||||||
|
= nav_entry "Sign up", new_user_registration_path
|
|
@ -0,0 +1,6 @@
|
||||||
|
- flash.each do |key, value|
|
||||||
|
.alert.alert-dismissible{class: "alert-#{bootstrap_color key}", role: "alert"}
|
||||||
|
%button.close{type: "button", "data-dismiss" => "alert"}
|
||||||
|
%span{"aria-hidden" => "true"} ×
|
||||||
|
%span.sr-only Close
|
||||||
|
= value
|
|
@ -6,15 +6,10 @@
|
||||||
= javascript_include_tag 'application', 'data-turbolinks-track' => true
|
= javascript_include_tag 'application', 'data-turbolinks-track' => true
|
||||||
= csrf_meta_tags
|
= csrf_meta_tags
|
||||||
%body
|
%body
|
||||||
%nav.navbar.navbar-default.navbar-fixed-top{role: "navigation"}
|
= render 'layouts/header'
|
||||||
|
= yield
|
||||||
|
- if Rails.env.development?
|
||||||
|
%hr
|
||||||
.container
|
.container
|
||||||
.navbar-header
|
%p.text-danger EVIL DEBUG MODE OF DOOM ENABLED!!!
|
||||||
%button.navbar-toggle{"data-target" => "#j2-main-navbar-collapse", "data-toggle" => "collapse", type: "button"}
|
= debug params
|
||||||
%span.sr-only Toggle navigation
|
|
||||||
%span.icon-bar
|
|
||||||
%span.icon-bar
|
|
||||||
%span.icon-bar
|
|
||||||
%a.navbar-brand{href: "/"} justask2
|
|
||||||
#j2-main-navbar-collapse.collapse.navbar-collapse
|
|
||||||
%ul.nav.navbar-nav
|
|
||||||
= yield
|
|
|
@ -1,3 +1,5 @@
|
||||||
.container
|
.container
|
||||||
%h1 Static#about
|
%h1 Static#about
|
||||||
|
= render 'layouts/messages'
|
||||||
|
|
||||||
%p Find me in app/views/static/about.html.haml
|
%p Find me in app/views/static/about.html.haml
|
||||||
|
|
|
@ -1,3 +1,5 @@
|
||||||
.container
|
.container
|
||||||
%h1 Static#index
|
%h1 Static#index
|
||||||
|
= render 'layouts/messages'
|
||||||
|
|
||||||
%p Find me in app/views/static/index.html.haml
|
%p Find me in app/views/static/index.html.haml
|
|
@ -29,7 +29,7 @@ Devise.setup do |config|
|
||||||
# session. If you need permissions, you should implement that in a before filter.
|
# session. If you need permissions, you should implement that in a before filter.
|
||||||
# You can also supply a hash where the value is a boolean determining whether
|
# You can also supply a hash where the value is a boolean determining whether
|
||||||
# or not authentication should be aborted when the value is not present.
|
# or not authentication should be aborted when the value is not present.
|
||||||
# config.authentication_keys = [ :email ]
|
config.authentication_keys = [ :login ]
|
||||||
|
|
||||||
# Configure parameters from the request object used for authentication. Each entry
|
# Configure parameters from the request object used for authentication. Each entry
|
||||||
# given should be a request method and it will automatically be passed to the
|
# given should be a request method and it will automatically be passed to the
|
||||||
|
@ -122,7 +122,7 @@ Devise.setup do |config|
|
||||||
config.reconfirmable = true
|
config.reconfirmable = true
|
||||||
|
|
||||||
# Defines which key will be used when confirming an account
|
# Defines which key will be used when confirming an account
|
||||||
# config.confirmation_keys = [ :email ]
|
config.confirmation_keys = [ :screen_name ]
|
||||||
|
|
||||||
# ==> Configuration for :rememberable
|
# ==> Configuration for :rememberable
|
||||||
# The time the user will be remembered without asking for credentials again.
|
# The time the user will be remembered without asking for credentials again.
|
||||||
|
@ -181,7 +181,7 @@ Devise.setup do |config|
|
||||||
# ==> Configuration for :recoverable
|
# ==> Configuration for :recoverable
|
||||||
#
|
#
|
||||||
# Defines which key will be used when recovering the password for an account
|
# Defines which key will be used when recovering the password for an account
|
||||||
# config.reset_password_keys = [ :email ]
|
config.reset_password_keys = [ :screen_name ]
|
||||||
|
|
||||||
# Time interval you can reset your password with a reset password key.
|
# Time interval you can reset your password with a reset password key.
|
||||||
# Don't put a too small interval or your users won't have the time to
|
# Don't put a too small interval or your users won't have the time to
|
||||||
|
|
|
@ -9,10 +9,10 @@ en:
|
||||||
failure:
|
failure:
|
||||||
already_authenticated: "You are already signed in."
|
already_authenticated: "You are already signed in."
|
||||||
inactive: "Your account is not activated yet."
|
inactive: "Your account is not activated yet."
|
||||||
invalid: "Invalid email or password."
|
invalid: "Invalid user name or password."
|
||||||
locked: "Your account is locked."
|
locked: "Your account is locked."
|
||||||
last_attempt: "You have one more attempt before your account will be locked."
|
last_attempt: "You have one more attempt before your account will be locked."
|
||||||
not_found_in_database: "Invalid email or password."
|
not_found_in_database: "Invalid user name or password."
|
||||||
timeout: "Your session expired. Please sign in again to continue."
|
timeout: "Your session expired. Please sign in again to continue."
|
||||||
unauthenticated: "You need to sign in or sign up before continuing."
|
unauthenticated: "You need to sign in or sign up before continuing."
|
||||||
unconfirmed: "You have to confirm your account before continuing."
|
unconfirmed: "You have to confirm your account before continuing."
|
||||||
|
|
|
@ -0,0 +1,6 @@
|
||||||
|
class AddScreenNameToUsers < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
add_column :users, :screen_name, :string
|
||||||
|
add_index :users, :screen_name, unique: true
|
||||||
|
end
|
||||||
|
end
|
|
@ -11,7 +11,7 @@
|
||||||
#
|
#
|
||||||
# It's strongly recommended that you check this file into your version control system.
|
# It's strongly recommended that you check this file into your version control system.
|
||||||
|
|
||||||
ActiveRecord::Schema.define(version: 20140801095807) do
|
ActiveRecord::Schema.define(version: 20140801103309) do
|
||||||
|
|
||||||
create_table "users", force: true do |t|
|
create_table "users", force: true do |t|
|
||||||
t.string "email", default: "", null: false
|
t.string "email", default: "", null: false
|
||||||
|
@ -26,9 +26,11 @@ ActiveRecord::Schema.define(version: 20140801095807) do
|
||||||
t.string "last_sign_in_ip"
|
t.string "last_sign_in_ip"
|
||||||
t.datetime "created_at"
|
t.datetime "created_at"
|
||||||
t.datetime "updated_at"
|
t.datetime "updated_at"
|
||||||
|
t.string "screen_name"
|
||||||
end
|
end
|
||||||
|
|
||||||
add_index "users", ["email"], name: "index_users_on_email", unique: true
|
add_index "users", ["email"], name: "index_users_on_email", unique: true
|
||||||
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
|
add_index "users", ["reset_password_token"], name: "index_users_on_reset_password_token", unique: true
|
||||||
|
add_index "users", ["screen_name"], name: "index_users_on_screen_name", unique: true
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue