From 193e51d42f7702343084bf576893cacd34a323a7 Mon Sep 17 00:00:00 2001 From: Julian Herrero Date: Sat, 18 Jan 2020 18:51:06 +0700 Subject: [PATCH] Enable Wordpress Oauth login and registration --- app/assets/stylesheets/layout.scss | 18 +++++ .../users/omniauth_callbacks_controller.rb | 4 + app/models/setting.rb | 1 + app/views/devise/_omniauth_form.html.erb | 19 +++++ config/initializers/devise.rb | 7 ++ config/locales/en/general.yml | 4 + config/locales/en/settings.yml | 2 + config/locales/es/general.yml | 4 + config/locales/es/settings.yml | 2 + config/secrets.yml.example | 3 + lib/omniauth_wordpress.rb | 40 ++++++++++ spec/features/users_auth_spec.rb | 77 +++++++++++++++++++ 12 files changed, 181 insertions(+) create mode 100644 lib/omniauth_wordpress.rb diff --git a/app/assets/stylesheets/layout.scss b/app/assets/stylesheets/layout.scss index 3104a59a2..aaccdd7dc 100644 --- a/app/assets/stylesheets/layout.scss +++ b/app/assets/stylesheets/layout.scss @@ -1539,6 +1539,7 @@ table { .button.button-twitter, .button.button-facebook, .button.button-google, +.button.button-wordpress, .button.button-telegram { background: #fff; color: $text; @@ -1678,6 +1679,23 @@ table { } } +.button.button-wordpress { + background: #dcdde3; + border-left: 3px solid #2f2f33; + + &::before { + color: #2f2f33; + content: "J"; + font-family: "icons" !important; + font-size: rem-calc(24); + left: 0; + line-height: $line-height * 2; + padding: 0 rem-calc(20); + position: absolute; + top: 0; + } +} + .button.button-telegram { background: #ecf7fc; border-left: 3px solid #08c; diff --git a/app/controllers/users/omniauth_callbacks_controller.rb b/app/controllers/users/omniauth_callbacks_controller.rb index 66e6811fa..f5b5350b8 100644 --- a/app/controllers/users/omniauth_callbacks_controller.rb +++ b/app/controllers/users/omniauth_callbacks_controller.rb @@ -11,6 +11,10 @@ class Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController sign_in_with :google_login, :google_oauth2 end + def wordpress_oauth2 + sign_in_with :wordpress_login, :wordpress_oauth2 + end + def after_sign_in_path_for(resource) if resource.registering_with_oauth finish_signup_path diff --git a/app/models/setting.rb b/app/models/setting.rb index d9d319784..503c3e68c 100644 --- a/app/models/setting.rb +++ b/app/models/setting.rb @@ -84,6 +84,7 @@ class Setting < ApplicationRecord "feature.facebook_login": true, "feature.google_login": true, "feature.twitter_login": true, + "feature.wordpress_login": false, "feature.public_stats": true, "feature.signature_sheets": true, "feature.user.recommendations": true, diff --git a/app/views/devise/_omniauth_form.html.erb b/app/views/devise/_omniauth_form.html.erb index e5c20e6c3..9010330c4 100644 --- a/app/views/devise/_omniauth_form.html.erb +++ b/app/views/devise/_omniauth_form.html.erb @@ -35,6 +35,15 @@ <% end %> + <% if feature? :wordpress_login %> +
+ <%= link_to t("omniauth.wordpress_oauth2.name"), user_wordpress_oauth2_omniauth_authorize_path, + title: t("omniauth.wordpress_oauth2.sign_in"), + class: "button-wordpress button expanded", + method: :post %> +
+ <% end %> +
<%= t("omniauth.or_fill") %>
@@ -72,6 +81,16 @@ title: t("omniauth.google_oauth2.sign_up"), class: "button-google button expanded", method: :post %> + + + <% end %> + + <% if feature? :wordpress_login %> +
+ <%= link_to t("omniauth.wordpress_oauth2.name"), user_wordpress_oauth2_omniauth_authorize_path, + title: t("omniauth.wordpress_oauth2.sign_up"), + class: "button-wordpress button expanded", + method: :post %>
<% end %> diff --git a/config/initializers/devise.rb b/config/initializers/devise.rb index 86cefbf61..cf6788ff9 100644 --- a/config/initializers/devise.rb +++ b/config/initializers/devise.rb @@ -1,3 +1,5 @@ +require Rails.root.join("lib", "omniauth_wordpress") + # Use this hook to configure devise mailer, warden hooks and so forth. # Many of these configuration options can be set straight in your model. Devise.setup do |config| @@ -242,6 +244,11 @@ Devise.setup do |config| 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, scope: "email", info_fields: "email,name,verified" config.omniauth :google_oauth2, Rails.application.secrets.google_oauth2_key, Rails.application.secrets.google_oauth2_secret + config.omniauth :wordpress_oauth2, + Rails.application.secrets.wordpress_oauth2_key, + Rails.application.secrets.wordpress_oauth2_secret, + strategy_class: OmniAuth::Strategies::Wordpress, + client_options: { site: Rails.application.secrets.wordpress_oauth2_site } # ==> Warden configuration # If you want to use other strategies, that are not supported by Devise, or diff --git a/config/locales/en/general.yml b/config/locales/en/general.yml index c7914a873..c2f654ff5 100644 --- a/config/locales/en/general.yml +++ b/config/locales/en/general.yml @@ -294,6 +294,10 @@ en: sign_in: Sign in with Google sign_up: Sign up with Google name: Google + wordpress_oauth2: + sign_in: Sign in with Wordpress + sign_up: Sign up with Wordpress + name: Wordpress twitter: sign_in: Sign in with Twitter sign_up: Sign up with Twitter diff --git a/config/locales/en/settings.yml b/config/locales/en/settings.yml index a8755f1db..3c164d1e5 100644 --- a/config/locales/en/settings.yml +++ b/config/locales/en/settings.yml @@ -89,6 +89,8 @@ en: facebook_login_description: "Allow users to sign up with their Facebook account" google_login: "Google login" google_login_description: "Allow users to sign up with their Google Account" + wordpress_login: "Wordpress login" + wordpress_login_description: "Allow users to sign up with their Wordpress Account" featured_proposals: "Featured proposals" featured_proposals_description: "Shows featured proposals on index proposals page" signature_sheets: "Signature sheets" diff --git a/config/locales/es/general.yml b/config/locales/es/general.yml index 07a47c6c6..d3132d80e 100644 --- a/config/locales/es/general.yml +++ b/config/locales/es/general.yml @@ -294,6 +294,10 @@ es: sign_in: Entra con Google sign_up: Regístrate con Google name: Google + wordpress_oauth2: + sign_in: Entra con Wordpress + sign_up: Regístrate con Wordpress + name: Wordpress twitter: sign_in: Entra con Twitter sign_up: Regístrate con Twitter diff --git a/config/locales/es/settings.yml b/config/locales/es/settings.yml index b7de45411..f5fa9c010 100644 --- a/config/locales/es/settings.yml +++ b/config/locales/es/settings.yml @@ -89,6 +89,8 @@ es: facebook_login_description: "Permitir que los usuarios se registren con su cuenta de Facebook" google_login: "Registro con Google" google_login_description: "Permitir que los usuarios se registren con su cuenta de Google" + wordpress_login: "Registro con Wordpress" + wordpress_login_description: "Permitir que los usuarios se registren con su cuenta de Wordpress" featured_proposals: "Propuestas destacadas" featured_proposals_description: "Muestra propuestas destacadas en la página principal de propuestas" signature_sheets: "Hojas de firmas" diff --git a/config/secrets.yml.example b/config/secrets.yml.example index 34de92444..6b81a6400 100644 --- a/config/secrets.yml.example +++ b/config/secrets.yml.example @@ -105,5 +105,8 @@ production: facebook_secret: "" google_oauth2_key: "" google_oauth2_secret: "" + wordpress_oauth2_key: "" + wordpress_oauth2_secret: "" + wordpress_oauth2_site: "" <<: *maps <<: *apis diff --git a/lib/omniauth_wordpress.rb b/lib/omniauth_wordpress.rb new file mode 100644 index 000000000..1131626db --- /dev/null +++ b/lib/omniauth_wordpress.rb @@ -0,0 +1,40 @@ +# This code is based on this gem https://github.com/jwickard/omniauth-wordpress-oauth2-plugin + +require "omniauth-oauth2" + +module OmniAuth + module Strategies + class Wordpress < OmniAuth::Strategies::OAuth2 + option :name, "wordpress_oauth2" + + option :client_options, {} + + uid { raw_info["ID"] } + + info do + { + name: raw_info["display_name"], + email: raw_info["user_email"], + nickname: raw_info["user_nicename"], + urls: { "Website" => raw_info["user_url"] } + } + end + + extra do + { raw_info: raw_info } + end + + def callback_url + full_host + script_name + callback_path + end + + def raw_info + @raw_info ||= obtain_raw_info + end + + def obtain_raw_info + access_token.get("/oauth/me", params: { "Authorization" => "Bearer #{access_token.token}" }).parsed + end + end + end +end diff --git a/spec/features/users_auth_spec.rb b/spec/features/users_auth_spec.rb index 415a65733..4b38b80ec 100644 --- a/spec/features/users_auth_spec.rb +++ b/spec/features/users_auth_spec.rb @@ -312,6 +312,83 @@ describe "Users" do expect(page).to have_field("user_email", with: "somethingelse@example.com") end end + + context "Wordpress" do + let(:wordpress_hash) do + { provider: "wordpress", + uid: "12345", + info: { + name: "manuela", + email: "manuelacarmena@example.com" }} + end + + before { Setting["feature.wordpress_login"] = true } + + scenario "Sign up" do + OmniAuth.config.add_mock(:wordpress_oauth2, wordpress_hash) + + visit "/" + click_link "Register" + + click_link "Sign up with Wordpress" + + expect(page).to have_current_path(new_user_session_path) + expect(page).to have_content "To continue, please click on the confirmation link that we have sent you via email" + + confirm_email + expect(page).to have_content "Your account has been confirmed" + + visit "/" + click_link "Sign in" + click_link "Sign in with Wordpress" + expect_to_be_signed_in + + click_link "My account" + expect(page).to have_field("account_username", with: "manuela") + + visit edit_user_registration_path + expect(page).to have_field("user_email", with: "manuelacarmena@example.com") + end + + scenario "Try to register with username and email of an already existing user" do + create(:user, username: "manuela", email: "manuelacarmena@example.com", password: "judgementday") + OmniAuth.config.add_mock(:wordpress_oauth2, wordpress_hash) + + visit "/" + click_link "Register" + click_link "Sign up with Wordpress" + + expect(page).to have_current_path(finish_signup_path) + + expect(page).to have_field("user_username", with: "manuela") + + click_button "Register" + + expect(page).to have_current_path(do_finish_signup_path) + + fill_in "Username", with: "manuela2" + fill_in "Email", with: "manuela@consul.dev" + click_button "Register" + + expect(page).to have_current_path(new_user_session_path) + expect(page).to have_content "To continue, please click on the confirmation link that we have sent you via email" + + confirm_email + expect(page).to have_content "Your account has been confirmed" + + visit "/" + click_link "Sign in" + click_link "Sign in with Wordpress" + + expect_to_be_signed_in + + click_link "My account" + expect(page).to have_field("account_username", with: "manuela2") + + visit edit_user_registration_path + expect(page).to have_field("user_email", with: "manuela@consul.dev") + end + end end scenario "Sign out" do