merges master and fix conflicts
This commit is contained in:
9
Gemfile
9
Gemfile
@@ -1,7 +1,7 @@
|
|||||||
source 'https://rubygems.org'
|
source 'https://rubygems.org'
|
||||||
|
|
||||||
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
|
# Bundle edge Rails instead: gem 'rails', github: 'rails/rails'
|
||||||
gem 'rails', '4.2.3'
|
gem 'rails', '4.2.4'
|
||||||
# Use PostgreSQL
|
# Use PostgreSQL
|
||||||
gem 'pg'
|
gem 'pg'
|
||||||
# Use SCSS for stylesheets
|
# Use SCSS for stylesheets
|
||||||
@@ -21,6 +21,11 @@ gem 'turbolinks'
|
|||||||
gem 'devise'
|
gem 'devise'
|
||||||
# Use ActiveModel has_secure_password
|
# Use ActiveModel has_secure_password
|
||||||
# gem 'bcrypt', '~> 3.1.7'
|
# gem 'bcrypt', '~> 3.1.7'
|
||||||
|
gem 'omniauth'
|
||||||
|
gem 'omniauth-twitter'
|
||||||
|
gem 'omniauth-facebook'
|
||||||
|
gem 'omniauth-google-oauth2'
|
||||||
|
|
||||||
gem 'kaminari'
|
gem 'kaminari'
|
||||||
gem 'acts_as_commentable_with_threading'
|
gem 'acts_as_commentable_with_threading'
|
||||||
gem 'acts-as-taggable-on'
|
gem 'acts-as-taggable-on'
|
||||||
@@ -32,7 +37,7 @@ gem 'simple_captcha2', require: 'simple_captcha'
|
|||||||
gem 'ckeditor'
|
gem 'ckeditor'
|
||||||
gem 'cancancan'
|
gem 'cancancan'
|
||||||
gem 'social-share-button'
|
gem 'social-share-button'
|
||||||
gem 'initialjs-rails'
|
gem 'initialjs-rails', '0.2.0'
|
||||||
gem 'unicorn'
|
gem 'unicorn'
|
||||||
gem 'paranoia'
|
gem 'paranoia'
|
||||||
|
|
||||||
|
|||||||
104
Gemfile.lock
104
Gemfile.lock
@@ -1,36 +1,36 @@
|
|||||||
GEM
|
GEM
|
||||||
remote: https://rubygems.org/
|
remote: https://rubygems.org/
|
||||||
specs:
|
specs:
|
||||||
actionmailer (4.2.3)
|
actionmailer (4.2.4)
|
||||||
actionpack (= 4.2.3)
|
actionpack (= 4.2.4)
|
||||||
actionview (= 4.2.3)
|
actionview (= 4.2.4)
|
||||||
activejob (= 4.2.3)
|
activejob (= 4.2.4)
|
||||||
mail (~> 2.5, >= 2.5.4)
|
mail (~> 2.5, >= 2.5.4)
|
||||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||||
actionpack (4.2.3)
|
actionpack (4.2.4)
|
||||||
actionview (= 4.2.3)
|
actionview (= 4.2.4)
|
||||||
activesupport (= 4.2.3)
|
activesupport (= 4.2.4)
|
||||||
rack (~> 1.6)
|
rack (~> 1.6)
|
||||||
rack-test (~> 0.6.2)
|
rack-test (~> 0.6.2)
|
||||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||||
actionview (4.2.3)
|
actionview (4.2.4)
|
||||||
activesupport (= 4.2.3)
|
activesupport (= 4.2.4)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
erubis (~> 2.7.0)
|
erubis (~> 2.7.0)
|
||||||
rails-dom-testing (~> 1.0, >= 1.0.5)
|
rails-dom-testing (~> 1.0, >= 1.0.5)
|
||||||
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
rails-html-sanitizer (~> 1.0, >= 1.0.2)
|
||||||
activejob (4.2.3)
|
activejob (4.2.4)
|
||||||
activesupport (= 4.2.3)
|
activesupport (= 4.2.4)
|
||||||
globalid (>= 0.3.0)
|
globalid (>= 0.3.0)
|
||||||
activemodel (4.2.3)
|
activemodel (4.2.4)
|
||||||
activesupport (= 4.2.3)
|
activesupport (= 4.2.4)
|
||||||
builder (~> 3.1)
|
builder (~> 3.1)
|
||||||
activerecord (4.2.3)
|
activerecord (4.2.4)
|
||||||
activemodel (= 4.2.3)
|
activemodel (= 4.2.4)
|
||||||
activesupport (= 4.2.3)
|
activesupport (= 4.2.4)
|
||||||
arel (~> 6.0)
|
arel (~> 6.0)
|
||||||
activesupport (4.2.3)
|
activesupport (4.2.4)
|
||||||
i18n (~> 0.7)
|
i18n (~> 0.7)
|
||||||
json (~> 1.7, >= 1.7.7)
|
json (~> 1.7, >= 1.7.7)
|
||||||
minitest (~> 5.1)
|
minitest (~> 5.1)
|
||||||
@@ -133,6 +133,8 @@ GEM
|
|||||||
factory_girl_rails (4.5.0)
|
factory_girl_rails (4.5.0)
|
||||||
factory_girl (~> 4.5.0)
|
factory_girl (~> 4.5.0)
|
||||||
railties (>= 3.0.0)
|
railties (>= 3.0.0)
|
||||||
|
faraday (0.9.1)
|
||||||
|
multipart-post (>= 1.2, < 3)
|
||||||
foundation-rails (5.5.2.1)
|
foundation-rails (5.5.2.1)
|
||||||
railties (>= 3.1.0)
|
railties (>= 3.1.0)
|
||||||
sass (>= 3.3.0, < 3.5)
|
sass (>= 3.3.0, < 3.5)
|
||||||
@@ -150,6 +152,7 @@ GEM
|
|||||||
activesupport (>= 4.1.0)
|
activesupport (>= 4.1.0)
|
||||||
groupdate (2.4.0)
|
groupdate (2.4.0)
|
||||||
activesupport (>= 3)
|
activesupport (>= 3)
|
||||||
|
hashie (3.4.2)
|
||||||
highline (1.7.3)
|
highline (1.7.3)
|
||||||
http-cookie (1.0.2)
|
http-cookie (1.0.2)
|
||||||
domain_name (~> 0.5)
|
domain_name (~> 0.5)
|
||||||
@@ -162,13 +165,14 @@ GEM
|
|||||||
i18n
|
i18n
|
||||||
term-ansicolor (>= 1.3.2)
|
term-ansicolor (>= 1.3.2)
|
||||||
terminal-table (>= 1.5.1)
|
terminal-table (>= 1.5.1)
|
||||||
initialjs-rails (0.1.0)
|
initialjs-rails (0.2.0)
|
||||||
railties (>= 3.1, < 5.0)
|
railties (>= 3.1, < 5.0)
|
||||||
jquery-rails (4.0.4)
|
jquery-rails (4.0.4)
|
||||||
rails-dom-testing (~> 1.0)
|
rails-dom-testing (~> 1.0)
|
||||||
railties (>= 4.2.0)
|
railties (>= 4.2.0)
|
||||||
thor (>= 0.14, < 2.0)
|
thor (>= 0.14, < 2.0)
|
||||||
json (1.8.3)
|
json (1.8.3)
|
||||||
|
jwt (1.5.1)
|
||||||
kaminari (0.16.3)
|
kaminari (0.16.3)
|
||||||
actionpack (>= 3.0.0)
|
actionpack (>= 3.0.0)
|
||||||
activesupport (>= 3.0.0)
|
activesupport (>= 3.0.0)
|
||||||
@@ -181,7 +185,7 @@ GEM
|
|||||||
actionmailer (>= 3.2)
|
actionmailer (>= 3.2)
|
||||||
letter_opener (~> 1.0)
|
letter_opener (~> 1.0)
|
||||||
railties (>= 3.2)
|
railties (>= 3.2)
|
||||||
loofah (2.0.2)
|
loofah (2.0.3)
|
||||||
nokogiri (>= 1.5.9)
|
nokogiri (>= 1.5.9)
|
||||||
mail (2.6.3)
|
mail (2.6.3)
|
||||||
mime-types (>= 1.16, < 3)
|
mime-types (>= 1.16, < 3)
|
||||||
@@ -189,12 +193,38 @@ GEM
|
|||||||
mini_portile (0.6.2)
|
mini_portile (0.6.2)
|
||||||
minitest (5.8.0)
|
minitest (5.8.0)
|
||||||
multi_json (1.11.2)
|
multi_json (1.11.2)
|
||||||
|
multi_xml (0.5.5)
|
||||||
|
multipart-post (2.0.0)
|
||||||
net-scp (1.2.1)
|
net-scp (1.2.1)
|
||||||
net-ssh (>= 2.6.5)
|
net-ssh (>= 2.6.5)
|
||||||
net-ssh (2.9.2)
|
net-ssh (2.9.2)
|
||||||
netrc (0.10.3)
|
netrc (0.10.3)
|
||||||
nokogiri (1.6.6.2)
|
nokogiri (1.6.6.2)
|
||||||
mini_portile (~> 0.6.0)
|
mini_portile (~> 0.6.0)
|
||||||
|
oauth (0.4.7)
|
||||||
|
oauth2 (1.0.0)
|
||||||
|
faraday (>= 0.8, < 0.10)
|
||||||
|
jwt (~> 1.0)
|
||||||
|
multi_json (~> 1.3)
|
||||||
|
multi_xml (~> 0.5)
|
||||||
|
rack (~> 1.2)
|
||||||
|
omniauth (1.2.2)
|
||||||
|
hashie (>= 1.2, < 4)
|
||||||
|
rack (~> 1.0)
|
||||||
|
omniauth-facebook (2.0.1)
|
||||||
|
omniauth-oauth2 (~> 1.2)
|
||||||
|
omniauth-google-oauth2 (0.2.6)
|
||||||
|
omniauth (> 1.0)
|
||||||
|
omniauth-oauth2 (~> 1.1)
|
||||||
|
omniauth-oauth (1.1.0)
|
||||||
|
oauth
|
||||||
|
omniauth (~> 1.0)
|
||||||
|
omniauth-oauth2 (1.3.1)
|
||||||
|
oauth2 (~> 1.0)
|
||||||
|
omniauth (~> 1.2)
|
||||||
|
omniauth-twitter (1.2.1)
|
||||||
|
json (~> 1.3)
|
||||||
|
omniauth-oauth (~> 1.1)
|
||||||
orm_adapter (0.5.0)
|
orm_adapter (0.5.0)
|
||||||
paranoia (2.1.3)
|
paranoia (2.1.3)
|
||||||
activerecord (~> 4.0)
|
activerecord (~> 4.0)
|
||||||
@@ -209,28 +239,28 @@ GEM
|
|||||||
rack (1.6.4)
|
rack (1.6.4)
|
||||||
rack-test (0.6.3)
|
rack-test (0.6.3)
|
||||||
rack (>= 1.0)
|
rack (>= 1.0)
|
||||||
rails (4.2.3)
|
rails (4.2.4)
|
||||||
actionmailer (= 4.2.3)
|
actionmailer (= 4.2.4)
|
||||||
actionpack (= 4.2.3)
|
actionpack (= 4.2.4)
|
||||||
actionview (= 4.2.3)
|
actionview (= 4.2.4)
|
||||||
activejob (= 4.2.3)
|
activejob (= 4.2.4)
|
||||||
activemodel (= 4.2.3)
|
activemodel (= 4.2.4)
|
||||||
activerecord (= 4.2.3)
|
activerecord (= 4.2.4)
|
||||||
activesupport (= 4.2.3)
|
activesupport (= 4.2.4)
|
||||||
bundler (>= 1.3.0, < 2.0)
|
bundler (>= 1.3.0, < 2.0)
|
||||||
railties (= 4.2.3)
|
railties (= 4.2.4)
|
||||||
sprockets-rails
|
sprockets-rails
|
||||||
rails-deprecated_sanitizer (1.0.3)
|
rails-deprecated_sanitizer (1.0.3)
|
||||||
activesupport (>= 4.2.0.alpha)
|
activesupport (>= 4.2.0.alpha)
|
||||||
rails-dom-testing (1.0.6)
|
rails-dom-testing (1.0.7)
|
||||||
activesupport (>= 4.2.0.beta, < 5.0)
|
activesupport (>= 4.2.0.beta, < 5.0)
|
||||||
nokogiri (~> 1.6.0)
|
nokogiri (~> 1.6.0)
|
||||||
rails-deprecated_sanitizer (>= 1.0.1)
|
rails-deprecated_sanitizer (>= 1.0.1)
|
||||||
rails-html-sanitizer (1.0.2)
|
rails-html-sanitizer (1.0.2)
|
||||||
loofah (~> 2.0)
|
loofah (~> 2.0)
|
||||||
railties (4.2.3)
|
railties (4.2.4)
|
||||||
actionpack (= 4.2.3)
|
actionpack (= 4.2.4)
|
||||||
activesupport (= 4.2.3)
|
activesupport (= 4.2.4)
|
||||||
rake (>= 0.8.7)
|
rake (>= 0.8.7)
|
||||||
thor (>= 0.18.1, < 2.0)
|
thor (>= 0.18.1, < 2.0)
|
||||||
raindrops (0.15.0)
|
raindrops (0.15.0)
|
||||||
@@ -283,7 +313,7 @@ GEM
|
|||||||
coffee-rails
|
coffee-rails
|
||||||
sass-rails
|
sass-rails
|
||||||
spring (1.3.6)
|
spring (1.3.6)
|
||||||
sprockets (3.2.0)
|
sprockets (3.3.3)
|
||||||
rack (~> 1.0)
|
rack (~> 1.0)
|
||||||
sprockets-rails (2.3.2)
|
sprockets-rails (2.3.2)
|
||||||
actionpack (>= 3.0)
|
actionpack (>= 3.0)
|
||||||
@@ -357,16 +387,20 @@ DEPENDENCIES
|
|||||||
fuubar
|
fuubar
|
||||||
groupdate
|
groupdate
|
||||||
i18n-tasks
|
i18n-tasks
|
||||||
initialjs-rails
|
initialjs-rails (= 0.2.0)
|
||||||
jquery-rails
|
jquery-rails
|
||||||
kaminari
|
kaminari
|
||||||
launchy
|
launchy
|
||||||
letter_opener_web (~> 1.3.0)
|
letter_opener_web (~> 1.3.0)
|
||||||
|
omniauth
|
||||||
|
omniauth-facebook
|
||||||
|
omniauth-google-oauth2
|
||||||
|
omniauth-twitter
|
||||||
paranoia
|
paranoia
|
||||||
pg
|
pg
|
||||||
poltergeist
|
poltergeist
|
||||||
quiet_assets
|
quiet_assets
|
||||||
rails (= 4.2.3)
|
rails (= 4.2.4)
|
||||||
responders
|
responders
|
||||||
rspec-rails (~> 3.0)
|
rspec-rails (~> 3.0)
|
||||||
sass-rails (~> 5.0)
|
sass-rails (~> 5.0)
|
||||||
|
|||||||
@@ -44,6 +44,12 @@ Para ejecutar los tests:
|
|||||||
bundle exec bin/rspec
|
bundle exec bin/rspec
|
||||||
```
|
```
|
||||||
|
|
||||||
|
### OAuth
|
||||||
|
|
||||||
|
Para probar los servicios de autenticación mediante proveedores externos OAuth — en este momento Twitter, Facebook y Google —, necesitas crear una "aplicación" en cada una de las plataformas soportadas y configurar la *key* y el *secret* proporcionados en tu *secrets.yml*
|
||||||
|
|
||||||
|
En el caso de Google, comprueba que las APIs *Contacts API* y *Google+ API* están habilitadas para la aplicación.
|
||||||
|
|
||||||
## Licencia
|
## Licencia
|
||||||
|
|
||||||
El código de este proyecto está publicado bajo la licencia AFFERO GPL v3 (ver [LICENSE-AGPLv3.txt](LICENSE-AGPLv3.txt))
|
El código de este proyecto está publicado bajo la licencia AFFERO GPL v3 (ver [LICENSE-AGPLv3.txt](LICENSE-AGPLv3.txt))
|
||||||
|
|||||||
@@ -152,7 +152,6 @@ h1, h2, h3, h4, h5, h6 {
|
|||||||
}
|
}
|
||||||
|
|
||||||
.f-dropdown {
|
.f-dropdown {
|
||||||
|
|
||||||
li a {
|
li a {
|
||||||
font-size: rem-calc(12);
|
font-size: rem-calc(12);
|
||||||
|
|
||||||
@@ -170,6 +169,19 @@ h1, h2, h3, h4, h5, h6 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.margin {
|
||||||
|
margin-top: $line-height;
|
||||||
|
margin-bottom: $line-height;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-top {
|
||||||
|
margin-top: $line-height;
|
||||||
|
}
|
||||||
|
|
||||||
|
.margin-bottom {
|
||||||
|
margin-bottom: $line-height;
|
||||||
|
}
|
||||||
|
|
||||||
// 04. Header
|
// 04. Header
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
@@ -514,9 +526,14 @@ footer {
|
|||||||
|
|
||||||
h2 {
|
h2 {
|
||||||
clear: both;
|
clear: both;
|
||||||
font-size: rem-calc(30);
|
font-size: rem-calc(18);
|
||||||
font-weight: bold;
|
font-weight: bold;
|
||||||
line-height: $line-height*2;
|
line-height: $line-height;
|
||||||
|
|
||||||
|
@media (min-width: $small-breakpoint) {
|
||||||
|
font-size: rem-calc(30);
|
||||||
|
line-height: $line-height*2;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
.back, .icon-angle-left {
|
.back, .icon-angle-left {
|
||||||
|
|||||||
@@ -85,6 +85,7 @@ $comment-official: rgba(70,219,145,.3);
|
|||||||
// 06. Responsive
|
// 06. Responsive
|
||||||
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
// - - - - - - - - - - - - - - - - - - - - - - - - -
|
||||||
|
|
||||||
|
$small: em-calc(480);
|
||||||
$small-breakpoint: em-calc(640);
|
$small-breakpoint: em-calc(640);
|
||||||
$medium-breakpoint: em-calc(1024);
|
$medium-breakpoint: em-calc(1024);
|
||||||
$large-breakpoint: em-calc(1440);
|
$large-breakpoint: em-calc(1440);
|
||||||
|
|||||||
@@ -13,6 +13,8 @@ class ApplicationController < ActionController::Base
|
|||||||
# 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_action :ensure_signup_complete
|
||||||
|
|
||||||
rescue_from CanCan::AccessDenied do |exception|
|
rescue_from CanCan::AccessDenied do |exception|
|
||||||
redirect_to main_app.root_url, alert: exception.message
|
redirect_to main_app.root_url, alert: exception.message
|
||||||
end
|
end
|
||||||
@@ -40,4 +42,13 @@ class ApplicationController < ActionController::Base
|
|||||||
def set_debate_votes(debates)
|
def set_debate_votes(debates)
|
||||||
@voted_values = current_user ? current_user.debate_votes(debates) : {}
|
@voted_values = current_user ? current_user.debate_votes(debates) : {}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def ensure_signup_complete
|
||||||
|
# Ensure we don't go into an infinite loop
|
||||||
|
return if action_name.in? %w(finish_signup do_finish_signup)
|
||||||
|
|
||||||
|
if user_signed_in? && !current_user.email_provided?
|
||||||
|
redirect_to finish_signup_path
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -5,6 +5,9 @@ class Organizations::RegistrationsController < Devise::RegistrationsController
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def success
|
||||||
|
end
|
||||||
|
|
||||||
def create
|
def create
|
||||||
build_resource(sign_up_params)
|
build_resource(sign_up_params)
|
||||||
if resource.valid_with_captcha?
|
if resource.valid_with_captcha?
|
||||||
@@ -17,6 +20,11 @@ class Organizations::RegistrationsController < Devise::RegistrationsController
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
protected
|
||||||
|
def after_inactive_sign_up_path_for(resource)
|
||||||
|
organizations_sign_up_success_path
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def sign_up_params
|
def sign_up_params
|
||||||
|
|||||||
29
app/controllers/users/omniauth_callbacks_controller.rb
Normal file
29
app/controllers/users/omniauth_callbacks_controller.rb
Normal file
@@ -0,0 +1,29 @@
|
|||||||
|
class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
||||||
|
def self.provides_callback_for(provider)
|
||||||
|
class_eval %Q{
|
||||||
|
def #{provider}
|
||||||
|
@user = User.find_for_oauth(env["omniauth.auth"], current_user)
|
||||||
|
|
||||||
|
if @user.persisted?
|
||||||
|
sign_in_and_redirect @user, event: :authentication
|
||||||
|
set_flash_message(:notice, :success, kind: "#{provider}".capitalize) if is_navigational_format?
|
||||||
|
else
|
||||||
|
session["devise.#{provider}_data"] = env["omniauth.auth"]
|
||||||
|
redirect_to new_user_registration_url
|
||||||
|
end
|
||||||
|
end
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
[:twitter, :facebook, :google_oauth2].each do |provider|
|
||||||
|
provides_callback_for provider
|
||||||
|
end
|
||||||
|
|
||||||
|
def after_sign_in_path_for(resource)
|
||||||
|
if resource.email_provided?
|
||||||
|
super(resource)
|
||||||
|
else
|
||||||
|
finish_signup_path
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
class Users::RegistrationsController < Devise::RegistrationsController
|
class Users::RegistrationsController < Devise::RegistrationsController
|
||||||
|
prepend_before_filter :authenticate_scope!, only: [:edit, :update, :destroy, :finish_signup, :do_finish_signup]
|
||||||
|
|
||||||
def create
|
def create
|
||||||
build_resource(sign_up_params)
|
build_resource(sign_up_params)
|
||||||
@@ -9,6 +10,19 @@ class Users::RegistrationsController < Devise::RegistrationsController
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def finish_signup
|
||||||
|
end
|
||||||
|
|
||||||
|
def do_finish_signup
|
||||||
|
if current_user.update(sign_up_params)
|
||||||
|
current_user.skip_reconfirmation!
|
||||||
|
sign_in(current_user, bypass: true)
|
||||||
|
redirect_to root_url
|
||||||
|
else
|
||||||
|
render :finish_signup
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
private
|
private
|
||||||
|
|
||||||
def sign_up_params
|
def sign_up_params
|
||||||
|
|||||||
17
app/models/identity.rb
Normal file
17
app/models/identity.rb
Normal file
@@ -0,0 +1,17 @@
|
|||||||
|
class Identity < ActiveRecord::Base
|
||||||
|
belongs_to :user
|
||||||
|
|
||||||
|
validates :provider, presence: true
|
||||||
|
validates :uid, presence: true, uniqueness: { scope: :provider }
|
||||||
|
|
||||||
|
def self.find_for_oauth(auth)
|
||||||
|
where(uid: auth.uid, provider: auth.provider).first_or_create
|
||||||
|
end
|
||||||
|
|
||||||
|
def update_user(new_user)
|
||||||
|
return unless user != new_user
|
||||||
|
|
||||||
|
self.user = new_user
|
||||||
|
save!
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -1,8 +1,12 @@
|
|||||||
class User < ActiveRecord::Base
|
class User < ActiveRecord::Base
|
||||||
include ActsAsParanoidAliases
|
include ActsAsParanoidAliases
|
||||||
|
|
||||||
|
OMNIAUTH_EMAIL_PREFIX = 'omniauth@participacion'
|
||||||
|
OMNIAUTH_EMAIL_REGEX = /\A#{OMNIAUTH_EMAIL_PREFIX}/
|
||||||
|
|
||||||
apply_simple_captcha
|
apply_simple_captcha
|
||||||
devise :database_authenticatable, :registerable, :confirmable,
|
devise :database_authenticatable, :registerable, :confirmable,
|
||||||
:recoverable, :rememberable, :trackable, :validatable
|
:recoverable, :rememberable, :trackable, :validatable, :omniauthable
|
||||||
|
|
||||||
acts_as_voter
|
acts_as_voter
|
||||||
acts_as_paranoid column: :hidden_at
|
acts_as_paranoid column: :hidden_at
|
||||||
@@ -11,9 +15,11 @@ class User < ActiveRecord::Base
|
|||||||
has_one :moderator
|
has_one :moderator
|
||||||
has_one :organization
|
has_one :organization
|
||||||
has_many :inappropiate_flags
|
has_many :inappropiate_flags
|
||||||
|
has_many :identities, dependent: :destroy
|
||||||
|
|
||||||
validates :username, presence: true, unless: :organization?
|
validates :username, presence: true, unless: :organization?
|
||||||
validates :official_level, inclusion: {in: 0..5}
|
validates :official_level, inclusion: {in: 0..5}
|
||||||
|
validates_format_of :email, without: OMNIAUTH_EMAIL_REGEX, on: :update
|
||||||
|
|
||||||
validates_associated :organization, message: false
|
validates_associated :organization, message: false
|
||||||
|
|
||||||
@@ -25,6 +31,43 @@ class User < ActiveRecord::Base
|
|||||||
scope :organizations, -> { joins(:organization) }
|
scope :organizations, -> { joins(:organization) }
|
||||||
scope :officials, -> { where("official_level > 0") }
|
scope :officials, -> { where("official_level > 0") }
|
||||||
|
|
||||||
|
def self.find_for_oauth(auth, signed_in_resource = nil)
|
||||||
|
# Get the identity and user if they exist
|
||||||
|
identity = Identity.find_for_oauth(auth)
|
||||||
|
|
||||||
|
# If a signed_in_resource is provided it always overrides the existing user
|
||||||
|
# to prevent the identity being locked with accidentally created accounts.
|
||||||
|
# Note that this may leave zombie accounts (with no associated identity) which
|
||||||
|
# can be cleaned up at a later date.
|
||||||
|
user = signed_in_resource ? signed_in_resource : identity.user
|
||||||
|
user ||= first_or_create_for_oauth(auth)
|
||||||
|
|
||||||
|
# Associate the identity with the user if needed
|
||||||
|
identity.update_user(user)
|
||||||
|
user
|
||||||
|
end
|
||||||
|
|
||||||
|
# Get the existing user by email if the provider gives us a verified email.
|
||||||
|
# If no verified email was provided we assign a temporary email and ask the
|
||||||
|
# user to verify it on the next step via RegistrationsController.finish_signup
|
||||||
|
def self.first_or_create_for_oauth(auth)
|
||||||
|
email = auth.info.email if auth.info.verified || auth.info.verified_email
|
||||||
|
user = User.where(email: email).first if email
|
||||||
|
|
||||||
|
# Create the user if it's a new registration
|
||||||
|
if user.nil?
|
||||||
|
user = User.new(
|
||||||
|
username: auth.info.nickname || auth.extra.raw_info.name.parameterize('-') || auth.uid,
|
||||||
|
email: email ? email : "#{OMNIAUTH_EMAIL_PREFIX}-#{auth.uid}-#{auth.provider}.com",
|
||||||
|
password: Devise.friendly_token[0,20]
|
||||||
|
)
|
||||||
|
user.skip_confirmation!
|
||||||
|
user.save!
|
||||||
|
end
|
||||||
|
|
||||||
|
user
|
||||||
|
end
|
||||||
|
|
||||||
def name
|
def name
|
||||||
organization? ? organization.name : username
|
organization? ? organization.name : username
|
||||||
end
|
end
|
||||||
@@ -67,4 +110,8 @@ class User < ActiveRecord::Base
|
|||||||
e.present? ? where(email: e) : none
|
e.present? ? where(email: e) : none
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def email_provided?
|
||||||
|
!!(email && email !~ OMNIAUTH_EMAIL_REGEX) ||
|
||||||
|
!!(unconfirmed_email && unconfirmed_email !~ OMNIAUTH_EMAIL_REGEX)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -26,7 +26,7 @@
|
|||||||
|
|
||||||
<div class="small-12 medium-6 column">
|
<div class="small-12 medium-6 column">
|
||||||
<h2><%= t("account.show.avatar")%></h2>
|
<h2><%= t("account.show.avatar")%></h2>
|
||||||
<%= avatar_image(@account, size: 100) %>
|
<%= avatar_image(@account, seed: @account.id, size: 100) %>
|
||||||
|
|
||||||
<h2><%= t("account.show.notifications")%></h2>
|
<h2><%= t("account.show.notifications")%></h2>
|
||||||
|
|
||||||
|
|||||||
@@ -14,7 +14,7 @@
|
|||||||
<% if comment.user.organization? %>
|
<% if comment.user.organization? %>
|
||||||
<%= image_tag("collective_avatar.png", size: 32, class: "avatar left") %>
|
<%= image_tag("collective_avatar.png", size: 32, class: "avatar left") %>
|
||||||
<% else %>
|
<% else %>
|
||||||
<%= avatar_image(comment.user, size: 32, class: "left") %>
|
<%= avatar_image(comment.user, seed: comment.user_id, size: 32, class: "left") %>
|
||||||
<% end %>
|
<% end %>
|
||||||
<% if comment.user.hidden? %>
|
<% if comment.user.hidden? %>
|
||||||
<i class="icon-deleted user-deleted"></i>
|
<i class="icon-deleted user-deleted"></i>
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
<h1><%= @debate.title %></h1>
|
<h1><%= @debate.title %></h1>
|
||||||
|
|
||||||
<div class="debate-info">
|
<div class="debate-info">
|
||||||
<%= avatar_image(@debate.author, size: 32, class: 'author-photo') %>
|
<%= avatar_image(@debate.author, seed: @debate.author_id, size: 32, class: 'author-photo') %>
|
||||||
<% if @debate.author.hidden? %>
|
<% if @debate.author.hidden? %>
|
||||||
<i class="icon-deleted author-deleted"></i>
|
<i class="icon-deleted author-deleted"></i>
|
||||||
<span class="author">
|
<span class="author">
|
||||||
|
|||||||
7
app/views/devise/_omniauth_form.html.erb
Normal file
7
app/views/devise/_omniauth_form.html.erb
Normal file
@@ -0,0 +1,7 @@
|
|||||||
|
<br/>
|
||||||
|
|
||||||
|
<%= link_to t("omniauth.twitter.sign_in"), user_omniauth_authorize_path(:twitter), class: 'button radius expand' %>
|
||||||
|
<%= link_to t("omniauth.facebook.sign_in"), user_omniauth_authorize_path(:facebook), class: 'button radius expand' %>
|
||||||
|
<%= link_to t("omniauth.google_oauth2.sign_in"), user_omniauth_authorize_path(:google_oauth2), class: 'button radius expand' %>
|
||||||
|
|
||||||
|
<hr/>
|
||||||
@@ -7,11 +7,11 @@
|
|||||||
<%= link_to(t("devise_views.menu.login_items.logout"), destroy_user_session_path, method: :delete) %>
|
<%= link_to(t("devise_views.menu.login_items.logout"), destroy_user_session_path, method: :delete) %>
|
||||||
</li>
|
</li>
|
||||||
<% else %>
|
<% else %>
|
||||||
<li>
|
<li>
|
||||||
<%= link_to(t("devise_views.menu.login_items.login"), new_user_session_path) %>
|
<%= link_to(t("devise_views.menu.login_items.login"), new_user_session_path) %>
|
||||||
</li>
|
</li>
|
||||||
<li>
|
<li>
|
||||||
<%= link_to(t("devise_views.menu.login_items.signup"), new_user_registration_path, class: "button radius small") %>
|
<%= link_to(t("devise_views.menu.login_items.signup"), new_user_registration_path, class: "button radius small") %>
|
||||||
</li>
|
</li>
|
||||||
<% end %>
|
<% end %>
|
||||||
</ul>
|
</ul>
|
||||||
@@ -3,6 +3,8 @@
|
|||||||
<div class="panel">
|
<div class="panel">
|
||||||
<h2><%= t("devise_views.sessions.new.title") %></h2>
|
<h2><%= t("devise_views.sessions.new.title") %></h2>
|
||||||
|
|
||||||
|
<%= render 'devise/omniauth_form' %>
|
||||||
|
|
||||||
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
|
<%= form_for(resource, as: resource_name, url: session_path(resource_name)) do |f| %>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="small-12 columns">
|
<div class="small-12 columns">
|
||||||
|
|||||||
@@ -25,7 +25,7 @@
|
|||||||
<%= link_to t("devise_views.shared.links.new_unlock"), new_unlock_path(resource_name) %><br>
|
<%= link_to t("devise_views.shared.links.new_unlock"), new_unlock_path(resource_name) %><br>
|
||||||
<% end -%>
|
<% end -%>
|
||||||
|
|
||||||
<%- if devise_mapping.omniauthable? %>
|
<%- if devise_mapping.omniauthable? && devise_mapping.name == 'user' %>
|
||||||
<%- resource_class.omniauth_providers.each do |provider| %>
|
<%- resource_class.omniauth_providers.each do |provider| %>
|
||||||
<%= link_to t("devise_views.shared.links.signin_with_provider", provider: provider.to_s.titleize), omniauth_authorize_path(resource_name, provider) %><br>
|
<%= link_to t("devise_views.shared.links.signin_with_provider", provider: provider.to_s.titleize), omniauth_authorize_path(resource_name, provider) %><br>
|
||||||
<% end -%>
|
<% end -%>
|
||||||
|
|||||||
15
app/views/organizations/registrations/success.html.erb
Normal file
15
app/views/organizations/registrations/success.html.erb
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
<div class="auth row">
|
||||||
|
<div class="small-12 medium-8 column small-centered">
|
||||||
|
<div class="panel">
|
||||||
|
<h2><%= t("devise_views.organizations.registrations.success.title") %></h2>
|
||||||
|
<p><%= t("devise_views.organizations.registrations.success.thank_you") %></p>
|
||||||
|
<p><%= t("devise_views.organizations.registrations.success.instructions_1_html") %></p>
|
||||||
|
<p><%= t("devise_views.organizations.registrations.success.instructions_2_html") %></p>
|
||||||
|
<p><%= t("devise_views.organizations.registrations.success.instructions_3_html") %></p>
|
||||||
|
<p>
|
||||||
|
<%= link_to t("devise_views.organizations.registrations.success.back_to_index"),
|
||||||
|
root_path, class: "button radius small margin-top" %>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
13
app/views/users/registrations/finish_signup.html.erb
Normal file
13
app/views/users/registrations/finish_signup.html.erb
Normal file
@@ -0,0 +1,13 @@
|
|||||||
|
<div class="auth row">
|
||||||
|
<div class="small-12 medium-8 large-5 column small-centered">
|
||||||
|
<div class="panel">
|
||||||
|
<h1><%= t('omniauth.finish_signup.title') %></h1>
|
||||||
|
|
||||||
|
<%= form_for current_user, as: :user, url: do_finish_signup_path, html: { role: 'form'} do |f| %>
|
||||||
|
<%= render 'shared/errors', resource: current_user %>
|
||||||
|
<%= f.email_field :email, placeholder: t("devise_views.users.registrations.new.email_label"), value: nil %>
|
||||||
|
<%= f.submit t("devise_views.users.registrations.new.submit"), class: 'button radius' %>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
@@ -2,6 +2,9 @@
|
|||||||
<div class="small-12 medium-8 large-5 column small-centered">
|
<div class="small-12 medium-8 large-5 column small-centered">
|
||||||
<div class="panel">
|
<div class="panel">
|
||||||
<h2><%= t("devise_views.users.registrations.new.title") %></h2>
|
<h2><%= t("devise_views.users.registrations.new.title") %></h2>
|
||||||
|
|
||||||
|
<%= render 'devise/omniauth_form' %>
|
||||||
|
|
||||||
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
|
<%= form_for(resource, as: resource_name, url: registration_path(resource_name)) do |f| %>
|
||||||
<%= render 'shared/errors', resource: resource %>
|
<%= render 'shared/errors', resource: resource %>
|
||||||
|
|
||||||
|
|||||||
@@ -2,4 +2,10 @@
|
|||||||
recaptcha_public_key: <%= ENV["MADRID_RECAPTCHA_PUBLIC_KEY"] %>
|
recaptcha_public_key: <%= ENV["MADRID_RECAPTCHA_PUBLIC_KEY"] %>
|
||||||
recaptcha_private_key: <%= ENV["MADRID_RECAPTCHA_PRIVATE_KEY"] %>
|
recaptcha_private_key: <%= ENV["MADRID_RECAPTCHA_PRIVATE_KEY"] %>
|
||||||
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
|
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
|
||||||
|
twitter_key: <%= ENV["TWITTER_KEY"] %>
|
||||||
|
twitter_secret: <%= ENV["TWITTER_SECRET"] %>
|
||||||
|
facebook_key: <%= ENV["FACEBOOK_KEY"] %>
|
||||||
|
facebook_secret: <%= ENV["FACEBOOK_SECRET"] %>
|
||||||
|
google_oauth2_key: <%= ENV["GOOGLE_KEY"] %>
|
||||||
|
google_oauth2_secret: <%= ENV["GOOGLE_SECRET"] %>
|
||||||
server_name: <%= fetch(:server_name) %>
|
server_name: <%= fetch(:server_name) %>
|
||||||
@@ -42,7 +42,7 @@ Rails.application.configure do
|
|||||||
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
|
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
|
||||||
|
|
||||||
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
|
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
|
||||||
# config.force_ssl = true
|
config.force_ssl = true
|
||||||
|
|
||||||
# Use the lowest log level to ensure availability of diagnostic information
|
# Use the lowest log level to ensure availability of diagnostic information
|
||||||
# when problems arise.
|
# when problems arise.
|
||||||
|
|||||||
@@ -42,7 +42,7 @@ Rails.application.configure do
|
|||||||
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
|
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
|
||||||
|
|
||||||
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
|
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
|
||||||
# config.force_ssl = true
|
config.force_ssl = true
|
||||||
|
|
||||||
# Use the lowest log level to ensure availability of diagnostic information
|
# Use the lowest log level to ensure availability of diagnostic information
|
||||||
# when problems arise.
|
# when problems arise.
|
||||||
|
|||||||
@@ -239,6 +239,9 @@ Devise.setup do |config|
|
|||||||
# Add a new OmniAuth provider. Check the wiki for more information on setting
|
# Add a new OmniAuth provider. Check the wiki for more information on setting
|
||||||
# up on your models and hooks.
|
# up on your models and hooks.
|
||||||
# config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
|
# config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
|
||||||
|
config.omniauth :twitter, Rails.application.secrets.twitter_key, Rails.application.secrets.twitter_secret
|
||||||
|
config.omniauth :facebook, Rails.application.secrets.facebook_key, Rails.application.secrets.facebook_secret
|
||||||
|
config.omniauth :google_oauth2, Rails.application.secrets.google_oauth2_key, Rails.application.secrets.google_oauth2_secret
|
||||||
|
|
||||||
# ==> Warden configuration
|
# ==> Warden configuration
|
||||||
# If you want to use other strategies, that are not supported by Devise, or
|
# If you want to use other strategies, that are not supported by Devise, or
|
||||||
|
|||||||
@@ -66,6 +66,13 @@ en:
|
|||||||
phone_number_label: "Phone number"
|
phone_number_label: "Phone number"
|
||||||
password_confirmation_label: "Confirm password"
|
password_confirmation_label: "Confirm password"
|
||||||
submit: "Sign up"
|
submit: "Sign up"
|
||||||
|
success:
|
||||||
|
title: "Registration of organization / collective"
|
||||||
|
thank_you: "Thank you for registering your organization or collective in the website. Now is <b>pending verification</b>."
|
||||||
|
instructions_1_html: "We will <b>contact you soon</b> in order to verify that you represent your collective."
|
||||||
|
instructions_2_html: "Meanwhile, <b>review your email</b>. We have sent you a <b>confirmation link to activate your account</b>."
|
||||||
|
instructions_3_html: "When you confirm your account will then be able to participate as a non-verified organization."
|
||||||
|
back_to_index: "Ok, go back to index"
|
||||||
sessions:
|
sessions:
|
||||||
new:
|
new:
|
||||||
title: "Log in"
|
title: "Log in"
|
||||||
|
|||||||
@@ -66,6 +66,13 @@ es:
|
|||||||
phone_number_label: "Teléfono"
|
phone_number_label: "Teléfono"
|
||||||
password_confirmation_label: "Confirmar contraseña"
|
password_confirmation_label: "Confirmar contraseña"
|
||||||
submit: "Registrarse"
|
submit: "Registrarse"
|
||||||
|
success:
|
||||||
|
title: "Registro de organización / colectivo"
|
||||||
|
thank_you: "Gracias por registrar tu colectivo en la web. Ahora está <b>pendiente de verificación</b>."
|
||||||
|
instructions_1_html: "En breve <b>nos pondremos en contacto contigo</b> para verificar que realmente representas a este colectivo."
|
||||||
|
instructions_2_html: "Mientras <b>revisa tu correo electrónico</b>, te hemos enviado un <b>enlace para confirmar tu cuenta</b>."
|
||||||
|
instructions_3_html: "Una vez confirmado, podrás empezar a participar como colectivo no verificado."
|
||||||
|
back_to_index: "Entendido, volver a la página principal"
|
||||||
sessions:
|
sessions:
|
||||||
new:
|
new:
|
||||||
title: "Entrar"
|
title: "Entrar"
|
||||||
|
|||||||
@@ -148,3 +148,12 @@ en:
|
|||||||
all: "You are not authorized to %{action} %{subject}."
|
all: "You are not authorized to %{action} %{subject}."
|
||||||
welcome:
|
welcome:
|
||||||
last_debates: Last debates
|
last_debates: Last debates
|
||||||
|
omniauth:
|
||||||
|
finish_signup:
|
||||||
|
title: Add Email
|
||||||
|
twitter:
|
||||||
|
sign_in: Sign in with Twitter
|
||||||
|
facebook:
|
||||||
|
sign_in: Sign in with Facebook
|
||||||
|
google_oauth2:
|
||||||
|
sign_in: Sign in with Google
|
||||||
|
|||||||
@@ -148,3 +148,12 @@ es:
|
|||||||
all: "No tienes permiso para realizar la acción '%{action}' sobre %{subject}."
|
all: "No tienes permiso para realizar la acción '%{action}' sobre %{subject}."
|
||||||
welcome:
|
welcome:
|
||||||
last_debates: Últimos debates
|
last_debates: Últimos debates
|
||||||
|
omniauth:
|
||||||
|
finish_signup:
|
||||||
|
title: Añade tu email
|
||||||
|
twitter:
|
||||||
|
sign_in: Entra con Twitter
|
||||||
|
facebook:
|
||||||
|
sign_in: Entra con Facebook
|
||||||
|
google_oauth2:
|
||||||
|
sign_in: Entra con Google
|
||||||
|
|||||||
@@ -1,10 +1,23 @@
|
|||||||
Rails.application.routes.draw do
|
Rails.application.routes.draw do
|
||||||
devise_for :users, controllers: { registrations: 'users/registrations' }
|
devise_for :users, controllers: {
|
||||||
|
registrations: 'users/registrations',
|
||||||
|
omniauth_callbacks: 'users/omniauth_callbacks'
|
||||||
|
}
|
||||||
devise_for :organizations, class_name: 'User',
|
devise_for :organizations, class_name: 'User',
|
||||||
controllers: {
|
controllers: {
|
||||||
registrations: 'organizations/registrations',
|
registrations: 'organizations/registrations',
|
||||||
sessions: 'devise/sessions'
|
sessions: 'devise/sessions',
|
||||||
}
|
},
|
||||||
|
skip: [:omniauth_callbacks]
|
||||||
|
|
||||||
|
devise_scope :organization do
|
||||||
|
get "organizations/sign_up/success", to: "organizations/registrations#success"
|
||||||
|
end
|
||||||
|
|
||||||
|
devise_scope :user do
|
||||||
|
get :finish_signup, to: 'users/registrations#finish_signup'
|
||||||
|
patch :do_finish_signup, to: 'users/registrations#do_finish_signup'
|
||||||
|
end
|
||||||
|
|
||||||
# The priority is based upon order of creation: first created -> highest priority.
|
# The priority is based upon order of creation: first created -> highest priority.
|
||||||
# See how all your routes lay out with "rake routes".
|
# See how all your routes lay out with "rake routes".
|
||||||
|
|||||||
@@ -14,12 +14,30 @@ default: &default
|
|||||||
|
|
||||||
development:
|
development:
|
||||||
secret_key_base: 56792feef405a59b18ea7db57b4777e855103882b926413d4afdfb8c0ea8aa86ea6649da4e729c5f5ae324c0ab9338f789174cf48c544173bc18fdc3b14262e4
|
secret_key_base: 56792feef405a59b18ea7db57b4777e855103882b926413d4afdfb8c0ea8aa86ea6649da4e729c5f5ae324c0ab9338f789174cf48c544173bc18fdc3b14262e4
|
||||||
|
twitter_key: AAAA
|
||||||
|
twitter_secret: BBBB
|
||||||
|
facebook_key: AAAA
|
||||||
|
facebook_secret: BBBB
|
||||||
|
google_oauth2_key: AAAA
|
||||||
|
google_oauth2_secret: BBBB
|
||||||
<<: *default
|
<<: *default
|
||||||
|
|
||||||
test:
|
test:
|
||||||
secret_key_base: 4d5adf961ddd27aef19622d6c0b3234d555f9ee003f022b1f829c92bbe33aaee907be7feb67bd54c14a1a32512fa968565ad405971fbc41bd0797af73c26a796
|
secret_key_base: 4d5adf961ddd27aef19622d6c0b3234d555f9ee003f022b1f829c92bbe33aaee907be7feb67bd54c14a1a32512fa968565ad405971fbc41bd0797af73c26a796
|
||||||
|
twitter_key: AAAA
|
||||||
|
twitter_secret: BBBB
|
||||||
|
facebook_key: AAAA
|
||||||
|
facebook_secret: BBBB
|
||||||
|
google_oauth2_key: AAAA
|
||||||
|
google_oauth2_secret: BBBB
|
||||||
<<: *default
|
<<: *default
|
||||||
|
|
||||||
production:
|
production:
|
||||||
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
|
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
|
||||||
|
twitter_key: <%= ENV["TWITTER_KEY"] %>
|
||||||
|
twitter_secret: <%= ENV["TWITTER_SECRET"] %>
|
||||||
|
facebook_key: <%= ENV["FACEBOOK_KEY"] %>
|
||||||
|
facebook_secret: <%= ENV["FACEBOOK_SECRET"] %>
|
||||||
|
google_oauth2_key: <%= ENV["GOOGLE_KEY"] %>
|
||||||
|
google_oauth2_secret: <%= ENV["GOOGLE_SECRET"] %>
|
||||||
<<: *default
|
<<: *default
|
||||||
11
db/migrate/20150824144524_create_identities.rb
Normal file
11
db/migrate/20150824144524_create_identities.rb
Normal file
@@ -0,0 +1,11 @@
|
|||||||
|
class CreateIdentities < ActiveRecord::Migration
|
||||||
|
def change
|
||||||
|
create_table :identities do |t|
|
||||||
|
t.references :user, index: true, foreign_key: true
|
||||||
|
t.string :provider
|
||||||
|
t.string :uid
|
||||||
|
|
||||||
|
t.timestamps null: false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
17
db/schema.rb
17
db/schema.rb
@@ -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: 20150824113326) do
|
ActiveRecord::Schema.define(version: 20150824144524) do
|
||||||
|
|
||||||
# These are extensions that must be enabled in order to support this database
|
# These are extensions that must be enabled in order to support this database
|
||||||
enable_extension "plpgsql"
|
enable_extension "plpgsql"
|
||||||
@@ -66,8 +66,8 @@ ActiveRecord::Schema.define(version: 20150824113326) do
|
|||||||
t.integer "author_id"
|
t.integer "author_id"
|
||||||
t.datetime "created_at", null: false
|
t.datetime "created_at", null: false
|
||||||
t.datetime "updated_at", null: false
|
t.datetime "updated_at", null: false
|
||||||
t.datetime "hidden_at"
|
|
||||||
t.string "visit_id"
|
t.string "visit_id"
|
||||||
|
t.datetime "hidden_at"
|
||||||
t.datetime "flagged_as_inappropiate_at"
|
t.datetime "flagged_as_inappropiate_at"
|
||||||
t.integer "inappropiate_flags_count", default: 0
|
t.integer "inappropiate_flags_count", default: 0
|
||||||
t.datetime "reviewed_at"
|
t.datetime "reviewed_at"
|
||||||
@@ -75,6 +75,16 @@ ActiveRecord::Schema.define(version: 20150824113326) do
|
|||||||
|
|
||||||
add_index "debates", ["hidden_at"], name: "index_debates_on_hidden_at", using: :btree
|
add_index "debates", ["hidden_at"], name: "index_debates_on_hidden_at", using: :btree
|
||||||
|
|
||||||
|
create_table "identities", force: :cascade do |t|
|
||||||
|
t.integer "user_id"
|
||||||
|
t.string "provider"
|
||||||
|
t.string "uid"
|
||||||
|
t.datetime "created_at", null: false
|
||||||
|
t.datetime "updated_at", null: false
|
||||||
|
end
|
||||||
|
|
||||||
|
add_index "identities", ["user_id"], name: "index_identities_on_user_id", using: :btree
|
||||||
|
|
||||||
create_table "inappropiate_flags", force: :cascade do |t|
|
create_table "inappropiate_flags", force: :cascade do |t|
|
||||||
t.integer "user_id"
|
t.integer "user_id"
|
||||||
t.string "flaggable_type"
|
t.string "flaggable_type"
|
||||||
@@ -156,10 +166,10 @@ ActiveRecord::Schema.define(version: 20150824113326) do
|
|||||||
t.string "unconfirmed_email"
|
t.string "unconfirmed_email"
|
||||||
t.boolean "email_on_debate_comment", default: false
|
t.boolean "email_on_debate_comment", default: false
|
||||||
t.boolean "email_on_comment_reply", default: false
|
t.boolean "email_on_comment_reply", default: false
|
||||||
|
t.string "phone_number", limit: 30
|
||||||
t.string "official_position"
|
t.string "official_position"
|
||||||
t.integer "official_level", default: 0
|
t.integer "official_level", default: 0
|
||||||
t.datetime "hidden_at"
|
t.datetime "hidden_at"
|
||||||
t.string "phone_number", limit: 30
|
|
||||||
t.string "username"
|
t.string "username"
|
||||||
end
|
end
|
||||||
|
|
||||||
@@ -214,6 +224,7 @@ ActiveRecord::Schema.define(version: 20150824113326) do
|
|||||||
add_index "votes", ["voter_id", "voter_type", "vote_scope"], name: "index_votes_on_voter_id_and_voter_type_and_vote_scope", using: :btree
|
add_index "votes", ["voter_id", "voter_type", "vote_scope"], name: "index_votes_on_voter_id_and_voter_type_and_vote_scope", using: :btree
|
||||||
|
|
||||||
add_foreign_key "administrators", "users"
|
add_foreign_key "administrators", "users"
|
||||||
|
add_foreign_key "identities", "users"
|
||||||
add_foreign_key "inappropiate_flags", "users"
|
add_foreign_key "inappropiate_flags", "users"
|
||||||
add_foreign_key "moderators", "users"
|
add_foreign_key "moderators", "users"
|
||||||
add_foreign_key "organizations", "users"
|
add_foreign_key "organizations", "users"
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
FactoryGirl.define do
|
FactoryGirl.define do
|
||||||
|
|
||||||
factory :user do
|
factory :user do
|
||||||
username 'Manuela'
|
username 'Manuela'
|
||||||
sequence(:email) { |n| "manuela#{n}@madrid.es" }
|
sequence(:email) { |n| "manuela#{n}@madrid.es" }
|
||||||
@@ -7,6 +6,12 @@ FactoryGirl.define do
|
|||||||
confirmed_at { Time.now }
|
confirmed_at { Time.now }
|
||||||
end
|
end
|
||||||
|
|
||||||
|
factory :identity do
|
||||||
|
user nil
|
||||||
|
provider "Twitter"
|
||||||
|
uid "MyString"
|
||||||
|
end
|
||||||
|
|
||||||
factory :debate do
|
factory :debate do
|
||||||
sequence(:title) { |n| "Debate #{n} title" }
|
sequence(:title) { |n| "Debate #{n} title" }
|
||||||
description 'Debate description'
|
description 'Debate description'
|
||||||
|
|||||||
@@ -2,44 +2,159 @@ require 'rails_helper'
|
|||||||
|
|
||||||
feature 'Users' do
|
feature 'Users' do
|
||||||
|
|
||||||
scenario 'Sign up' do
|
context 'Regular authentication' do
|
||||||
visit '/'
|
scenario 'Sign up' do
|
||||||
click_link 'Sign up'
|
visit '/'
|
||||||
|
click_link 'Sign up'
|
||||||
|
|
||||||
fill_in 'user_username', with: 'Manuela Carmena'
|
fill_in 'user_username', with: 'Manuela Carmena'
|
||||||
fill_in 'user_email', with: 'manuela@madrid.es'
|
fill_in 'user_email', with: 'manuela@madrid.es'
|
||||||
fill_in 'user_password', with: 'judgementday'
|
fill_in 'user_password', with: 'judgementday'
|
||||||
fill_in 'user_password_confirmation', with: 'judgementday'
|
fill_in 'user_password_confirmation', with: 'judgementday'
|
||||||
fill_in 'user_captcha', with: correct_captcha_text
|
fill_in 'user_captcha', with: correct_captcha_text
|
||||||
|
|
||||||
click_button 'Sign up'
|
click_button 'Sign up'
|
||||||
|
|
||||||
expect(page).to have_content "A message with a confirmation link has been sent to your email address. Please follow the link to activate your account."
|
expect(page).to have_content "A message with a confirmation link has been sent to your email address. Please follow the link to activate your account."
|
||||||
|
|
||||||
sent_token = /.*confirmation_token=(.*)".*/.match(ActionMailer::Base.deliveries.last.body.to_s)[1]
|
sent_token = /.*confirmation_token=(.*)".*/.match(ActionMailer::Base.deliveries.last.body.to_s)[1]
|
||||||
visit user_confirmation_path(confirmation_token: sent_token)
|
visit user_confirmation_path(confirmation_token: sent_token)
|
||||||
|
|
||||||
expect(page).to have_content "Your email address has been successfully confirmed"
|
expect(page).to have_content "Your email address has been successfully confirmed"
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Errors on sign up' do
|
||||||
|
visit '/'
|
||||||
|
click_link 'Sign up'
|
||||||
|
click_button 'Sign up'
|
||||||
|
|
||||||
|
expect(page).to have_content error_message
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Sign in' do
|
||||||
|
create(:user, email: 'manuela@madrid.es', password: 'judgementday')
|
||||||
|
|
||||||
|
visit '/'
|
||||||
|
click_link 'Log in'
|
||||||
|
fill_in 'user_email', with: 'manuela@madrid.es'
|
||||||
|
fill_in 'user_password', with: 'judgementday'
|
||||||
|
click_button 'Log in'
|
||||||
|
|
||||||
|
expect(page).to have_content 'Signed in successfully.'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario 'Errors on sign up' do
|
context 'OAuth authentication' do
|
||||||
visit '/'
|
context 'Twitter' do
|
||||||
click_link 'Sign up'
|
background do
|
||||||
click_button 'Sign up'
|
#request.env["devise.mapping"] = Devise.mappings[:user]
|
||||||
|
end
|
||||||
|
|
||||||
expect(page).to have_content error_message
|
scenario 'Sign up, when email was provided by OAuth provider' do
|
||||||
end
|
omniauth_twitter_hash = { 'provider' => 'twitter',
|
||||||
|
'uid' => '12345',
|
||||||
|
'info' => {
|
||||||
|
'name' => 'manuela',
|
||||||
|
'email' => 'manuelacarmena@example.com',
|
||||||
|
'nickname' => 'ManuelaRocks',
|
||||||
|
'verified' => '1'
|
||||||
|
},
|
||||||
|
'extra' => { 'raw_info' =>
|
||||||
|
{ 'location' => 'Madrid',
|
||||||
|
'name' => 'Manuela de las Carmenas'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
scenario 'Sign in' do
|
OmniAuth.config.add_mock(:twitter, omniauth_twitter_hash)
|
||||||
create(:user, email: 'manuela@madrid.es', password: 'judgementday')
|
|
||||||
|
|
||||||
visit '/'
|
visit '/'
|
||||||
click_link 'Log in'
|
click_link 'Sign up'
|
||||||
fill_in 'user_email', with: 'manuela@madrid.es'
|
|
||||||
fill_in 'user_password', with: 'judgementday'
|
|
||||||
click_button 'Log in'
|
|
||||||
|
|
||||||
expect(page).to have_content 'Signed in successfully.'
|
expect do
|
||||||
|
expect do
|
||||||
|
expect do
|
||||||
|
click_link 'Sign in with Twitter'
|
||||||
|
end.not_to change { ActionMailer::Base.deliveries.size }
|
||||||
|
end.to change { Identity.count }.by(1)
|
||||||
|
end.to change { User.count }.by(1)
|
||||||
|
|
||||||
|
expect(current_path).to eq(root_path)
|
||||||
|
expect_to_be_signed_in
|
||||||
|
|
||||||
|
user = User.last
|
||||||
|
expect(user.username).to eq('ManuelaRocks')
|
||||||
|
expect(user.email).to eq('manuelacarmena@example.com')
|
||||||
|
expect(user.confirmed?).to eq(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Sign up, when neither email nor nickname were provided by OAuth provider' do
|
||||||
|
omniauth_twitter_hash = { 'provider' => 'twitter',
|
||||||
|
'uid' => '12345',
|
||||||
|
'info' => {
|
||||||
|
'name' => 'manuela'
|
||||||
|
},
|
||||||
|
'extra' => { 'raw_info' =>
|
||||||
|
{ 'location' => 'Madrid',
|
||||||
|
'name' => 'Manuela de las Carmenas'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OmniAuth.config.add_mock(:twitter, omniauth_twitter_hash)
|
||||||
|
|
||||||
|
visit '/'
|
||||||
|
click_link 'Sign up'
|
||||||
|
|
||||||
|
expect do
|
||||||
|
expect do
|
||||||
|
expect do
|
||||||
|
click_link 'Sign in with Twitter'
|
||||||
|
end.not_to change { ActionMailer::Base.deliveries.size }
|
||||||
|
end.to change { Identity.count }.by(1)
|
||||||
|
end.to change { User.count }.by(1)
|
||||||
|
|
||||||
|
expect(current_path).to eq(finish_signup_path)
|
||||||
|
|
||||||
|
user = User.last
|
||||||
|
expect(user.username).to eq('manuela-de-las-carmenas')
|
||||||
|
expect(user.email).to eq("omniauth@participacion-12345-twitter.com")
|
||||||
|
|
||||||
|
fill_in 'user_email', with: 'manueladelascarmenas@example.com'
|
||||||
|
click_button 'Sign up'
|
||||||
|
|
||||||
|
sent_token = /.*confirmation_token=(.*)".*/.match(ActionMailer::Base.deliveries.last.body.to_s)[1]
|
||||||
|
visit user_confirmation_path(confirmation_token: sent_token)
|
||||||
|
|
||||||
|
expect(page).to have_content "Your email address has been successfully confirmed"
|
||||||
|
|
||||||
|
expect(user.reload.email).to eq('manueladelascarmenas@example.com')
|
||||||
|
end
|
||||||
|
|
||||||
|
scenario 'Sign in, user was already signed up with OAuth' do
|
||||||
|
user = create(:user, email: 'manuela@madrid.es', password: 'judgementday')
|
||||||
|
identity = create(:identity, uid: '12345', provider: 'twitter', user: user)
|
||||||
|
omniauth_twitter_hash = { 'provider' => 'twitter',
|
||||||
|
'uid' => '12345',
|
||||||
|
'info' => {
|
||||||
|
'name' => 'manuela'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
OmniAuth.config.add_mock(:twitter, omniauth_twitter_hash)
|
||||||
|
|
||||||
|
visit '/'
|
||||||
|
click_link 'Log in'
|
||||||
|
|
||||||
|
expect do
|
||||||
|
expect do
|
||||||
|
click_link 'Sign in with Twitter'
|
||||||
|
end.not_to change { Identity.count }
|
||||||
|
end.not_to change { User.count }
|
||||||
|
|
||||||
|
expect_to_be_signed_in
|
||||||
|
end
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
scenario 'Sign out' do
|
scenario 'Sign out' do
|
||||||
@@ -73,5 +188,4 @@ feature 'Users' do
|
|||||||
|
|
||||||
expect(page).to have_content "Your password has been changed successfully. You are now signed in."
|
expect(page).to have_content "Your password has been changed successfully. You are now signed in."
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|||||||
9
spec/models/identity_spec.rb
Normal file
9
spec/models/identity_spec.rb
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
require 'rails_helper'
|
||||||
|
|
||||||
|
RSpec.describe Identity, type: :model do
|
||||||
|
let(:identity) { build(:identity) }
|
||||||
|
|
||||||
|
it "should be valid" do
|
||||||
|
expect(identity).to be_valid
|
||||||
|
end
|
||||||
|
end
|
||||||
@@ -50,6 +50,26 @@ describe User do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
describe 'OmniAuth' do
|
||||||
|
describe '#email_provided?' do
|
||||||
|
it "is false if the email matchs was temporarely assigned by the OmniAuth process" do
|
||||||
|
subject.email = 'omniauth@participacion-ABCD-twitter.com'
|
||||||
|
expect(subject.email_provided?).to eq(false)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "is true if the email is not omniauth-like" do
|
||||||
|
subject.email = 'manuelacarmena@example.com'
|
||||||
|
expect(subject.email_provided?).to eq(true)
|
||||||
|
end
|
||||||
|
|
||||||
|
it "is true if the user's real email is pending to be confirmed" do
|
||||||
|
subject.email = 'omniauth@participacion-ABCD-twitter.com'
|
||||||
|
subject.unconfirmed_email = 'manuelacarmena@example.com'
|
||||||
|
expect(subject.email_provided?).to eq(true)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
describe "administrator?" do
|
describe "administrator?" do
|
||||||
it "is false when the user is not an admin" do
|
it "is false when the user is not an admin" do
|
||||||
expect(subject.administrator?).to be false
|
expect(subject.administrator?).to be false
|
||||||
|
|||||||
@@ -22,3 +22,5 @@ RSpec.configure do |config|
|
|||||||
end
|
end
|
||||||
|
|
||||||
Capybara.javascript_driver = :poltergeist
|
Capybara.javascript_driver = :poltergeist
|
||||||
|
|
||||||
|
OmniAuth.config.test_mode = true
|
||||||
|
|||||||
@@ -77,4 +77,7 @@ module CommonActions
|
|||||||
/\d errors? prohibited this (.*) from being saved:/
|
/\d errors? prohibited this (.*) from being saved:/
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def expect_to_be_signed_in
|
||||||
|
expect(find('.top-bar')).to have_content 'My account'
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
Reference in New Issue
Block a user