mirror of
https://github.com/scinote-eln/scinote-web.git
synced 2025-10-25 13:37:12 +08:00
sign up with linkedIn account
This commit is contained in:
parent
4d69636dbe
commit
08439e7f58
17 changed files with 206 additions and 7 deletions
1
Gemfile
1
Gemfile
|
|
@ -17,6 +17,7 @@ gem 'font-awesome-rails', '~> 4.7.0.2'
|
|||
gem 'recaptcha', require: 'recaptcha/rails'
|
||||
gem 'sanitize', '~> 4.4'
|
||||
gem 'omniauth'
|
||||
gem 'omniauth-linkedin-oauth2'
|
||||
|
||||
# Gems for API implementation
|
||||
gem 'jwt', '~> 1.5'
|
||||
|
|
|
|||
BIN
app/assets/images/linkedin/Sign-in-Small---Active.png
Normal file
BIN
app/assets/images/linkedin/Sign-in-Small---Active.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
BIN
app/assets/images/linkedin/Sign-in-Small---Default.png
Normal file
BIN
app/assets/images/linkedin/Sign-in-Small---Default.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
BIN
app/assets/images/linkedin/Sign-in-Small---Hover.png
Normal file
BIN
app/assets/images/linkedin/Sign-in-Small---Hover.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 2.4 KiB |
|
|
@ -1,6 +1,10 @@
|
|||
module Users
|
||||
class OmniauthCallbacksController < Devise::OmniauthCallbacksController
|
||||
include UsersGenerator
|
||||
|
||||
skip_before_action :verify_authenticity_token
|
||||
before_action :sign_up_with_provider_enabled?,
|
||||
only: :linkedin
|
||||
|
||||
# You should configure your model like this:
|
||||
# devise :omniauthable, omniauth_providers: [:twitter]
|
||||
|
|
@ -9,6 +13,55 @@ module Users
|
|||
# def twitter
|
||||
# end
|
||||
|
||||
def linkedin
|
||||
auth_hash = request.env['omniauth.auth']
|
||||
|
||||
@user = User.from_omniauth(auth_hash)
|
||||
if @user && @user.current_team_id?
|
||||
# User already exists and has been signed up with LinkedIn; just sign in
|
||||
set_flash_message(:notice,
|
||||
:success,
|
||||
kind: I18n.t('devise.linkedin.provider_name'))
|
||||
sign_in_and_redirect @user
|
||||
elsif @user
|
||||
# User already exists and has started sign up with LinkedIn;
|
||||
# but doesn't have team (needs to complete sign up - agrees to TOS)
|
||||
set_flash_message(:alert,
|
||||
:failure,
|
||||
kind: I18n.t('devise.linkedin.provider_name'),
|
||||
reason: I18n.t('devise.linkedin.complete_sign_up'))
|
||||
redirect_to users_sign_up_provider_path(user: @user)
|
||||
elsif User.find_by_email(auth_hash['info']['email'])
|
||||
# email is already taken, so sign up with Linked in is not allowed
|
||||
set_flash_message(:alert,
|
||||
:failure,
|
||||
kind: I18n.t('devise.linkedin.provider_name'),
|
||||
reason: I18n.t('devise.linkedin.email_already_taken',
|
||||
email: auth_hash['info']['email']))
|
||||
redirect_to after_omniauth_failure_path_for(resource_name)
|
||||
else
|
||||
# Create new user and identity; and redirect to complete sign up form
|
||||
@user = User.new(
|
||||
full_name: auth_hash['info']['name'],
|
||||
initials: generate_initials(auth_hash['info']['name']),
|
||||
email: auth_hash['info']['email'],
|
||||
password: generate_user_password
|
||||
)
|
||||
@user.avatar_remote_url = (auth_hash['info']['image'])
|
||||
user_identity = UserIdentity.new(user: @user,
|
||||
provider: auth_hash['provider'],
|
||||
uid: auth_hash['uid'])
|
||||
unless @user.save && user_identity.save
|
||||
set_flash_message(:alert,
|
||||
:failure,
|
||||
kind: I18n.t('devise.linkedin.provider_name'),
|
||||
reason: I18n.t('devise.linkedin.failed_to_save'))
|
||||
redirect_to after_omniauth_failure_path_for(resource_name) and return
|
||||
end
|
||||
redirect_to users_sign_up_provider_path(user: @user)
|
||||
end
|
||||
end
|
||||
|
||||
# More info at:
|
||||
# https://github.com/plataformatec/devise#omniauth
|
||||
|
||||
|
|
@ -28,5 +81,18 @@ module Users
|
|||
# def after_omniauth_failure_path_for(scope)
|
||||
# super(scope)
|
||||
# end
|
||||
|
||||
private
|
||||
|
||||
def sign_up_with_provider_enabled?
|
||||
render_403 unless Rails.configuration.x.enable_user_registration
|
||||
render_403 unless Rails.configuration.x.linkedin_signin_enabled
|
||||
end
|
||||
|
||||
def generate_initials(full_name)
|
||||
initials = full_name.titleize.scan(/[A-Z]+/).join
|
||||
initials = initials.strip.empty? ? 'PLCH' : initials[0..3]
|
||||
initials
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
class Users::RegistrationsController < Devise::RegistrationsController
|
||||
prepend_before_action :check_captcha, only: [:create]
|
||||
before_action :registration_enabled?,
|
||||
only: %i(new create new_with_provider create_with_provider)
|
||||
before_action :sign_up_with_provider_enabled?,
|
||||
only: %i(new_with_provider create_with_provider)
|
||||
|
||||
def avatar
|
||||
user = User.find_by_id(params[:id]) || current_user
|
||||
|
|
@ -122,12 +126,9 @@ class Users::RegistrationsController < Devise::RegistrationsController
|
|||
end
|
||||
end
|
||||
|
||||
def new
|
||||
render_403 && return unless Rails.configuration.x.enable_user_registration
|
||||
end
|
||||
def new; end
|
||||
|
||||
def create
|
||||
render_403 && return unless Rails.configuration.x.enable_user_registration
|
||||
build_resource(sign_up_params)
|
||||
valid_resource = resource.valid?
|
||||
# ugly checking if new team on sign up is enabled :(
|
||||
|
|
@ -174,6 +175,36 @@ class Users::RegistrationsController < Devise::RegistrationsController
|
|||
end
|
||||
end
|
||||
|
||||
def new_with_provider; end
|
||||
|
||||
def create_with_provider
|
||||
@user = User.find_by_id(user_provider_params['user'])
|
||||
# Create new team for the new user
|
||||
@team = Team.new(team_provider_params)
|
||||
@team.validate
|
||||
|
||||
if @team.valid? && Rails.configuration.x.new_team_on_signup
|
||||
# Set the confirmed_at == created_at IF not using email confirmations
|
||||
unless Rails.configuration.x.enable_email_confirmations
|
||||
@user.update!(confirmed_at: @user.created_at)
|
||||
end
|
||||
|
||||
@team.created_by = @user # set created_by for team
|
||||
@team.save!
|
||||
|
||||
# Add this user to the team as owner
|
||||
UserTeam.create(user: @user, team: @team, role: :admin)
|
||||
|
||||
# set current team to new user
|
||||
@user.current_team_id = @team.id
|
||||
@user.save!
|
||||
|
||||
sign_in_and_redirect @user
|
||||
else
|
||||
render :new_with_provider
|
||||
end
|
||||
end
|
||||
|
||||
protected
|
||||
|
||||
# Called upon creating User (before .save). Permits parameters and extracts
|
||||
|
|
@ -191,6 +222,14 @@ class Users::RegistrationsController < Devise::RegistrationsController
|
|||
tmp.merge(:initials => initials)
|
||||
end
|
||||
|
||||
def team_provider_params
|
||||
params.require(:team).permit(:name)
|
||||
end
|
||||
|
||||
def user_provider_params
|
||||
params.permit(:user)
|
||||
end
|
||||
|
||||
def account_update_params
|
||||
params.require(:user).permit(
|
||||
:full_name,
|
||||
|
|
@ -268,6 +307,14 @@ class Users::RegistrationsController < Devise::RegistrationsController
|
|||
end
|
||||
end
|
||||
|
||||
def registration_enabled?
|
||||
render_403 unless Rails.configuration.x.enable_user_registration
|
||||
end
|
||||
|
||||
def sign_up_with_provider_enabled?
|
||||
render_403 unless Rails.configuration.x.linkedin_signin_enabled
|
||||
end
|
||||
|
||||
# Redirect to login page after signing up
|
||||
def after_sign_up_path_for(resource)
|
||||
new_user_session_path
|
||||
|
|
|
|||
|
|
@ -217,6 +217,14 @@ class User < ApplicationRecord
|
|||
self.full_name = name
|
||||
end
|
||||
|
||||
def avatar_remote_url=(url_value)
|
||||
self.avatar = URI.parse(url_value)
|
||||
# Assuming url_value is http://example.com/photos/face.png
|
||||
# avatar_file_name == "face.png"
|
||||
# avatar_content_type == "image/png"
|
||||
@avatar_remote_url = url_value
|
||||
end
|
||||
|
||||
def current_team
|
||||
Team.find_by_id(self.current_team_id)
|
||||
end
|
||||
|
|
|
|||
37
app/views/users/registrations/new_with_provider.html.erb
Normal file
37
app/views/users/registrations/new_with_provider.html.erb
Normal file
|
|
@ -0,0 +1,37 @@
|
|||
<% provide(:head_title, t('users.registrations.new.head_title')) %>
|
||||
|
||||
<div class="center-block center-block-narrow">
|
||||
<h2><%= t 'users.registrations.new_with_provider.head_title' %></h2>
|
||||
<div data-hook="sign-up-form-hook">
|
||||
<%= form_for(:team, as: resource_name, url: users_complete_sign_up_provider_path, html: { id: "sign-up-provider-form" } ) do |f| %>
|
||||
<%= hidden_field_tag :user, params['user'] %>
|
||||
|
||||
<% if Rails.configuration.x.new_team_on_signup %>
|
||||
<div class="form-group" id="team_name_form">
|
||||
<%= f.label :name, t('users.registrations.new.team_name_label') %>
|
||||
<%= f.text_field :name, autofocus: true, class: 'form-control' %>
|
||||
<span><small><%= t 'users.registrations.new.team_name_help' %></small></span>
|
||||
</div>
|
||||
<% end %>
|
||||
|
||||
<div class="form-group" data-hook="sign-up-form-submit">
|
||||
<%= f.submit 'Sign up', class: 'btn btn-primary' %>
|
||||
</div>
|
||||
<% end %>
|
||||
</div>
|
||||
<%= render 'users/shared/links' %>
|
||||
</div>
|
||||
|
||||
<% if @team and not @team.errors.empty? %>
|
||||
<script>
|
||||
(function () {
|
||||
var formErrors = {};
|
||||
|
||||
<% @team.errors.each do |err, m| %>
|
||||
formErrors["<%= err %>"] =["<%= m %>"];
|
||||
<% end %>
|
||||
|
||||
$("form").renderFormErrors('team', formErrors, false);
|
||||
}());
|
||||
</script>
|
||||
<% end %>
|
||||
|
|
@ -1,5 +1,7 @@
|
|||
<%- if controller_name != 'sessions' %>
|
||||
<%= link_to t("devise.links.login"), new_session_path(resource_name) %><br />
|
||||
<% login = t("devise.links.login") %>
|
||||
<% login = t("devise.links.login_with_provider") if ['new_with_provider', 'create_with_provider'].include? action_name %>
|
||||
<%= link_to login, new_session_path(resource_name) %><br />
|
||||
<% end -%>
|
||||
|
||||
<%- if devise_mapping.registerable? && Rails.configuration.x.enable_user_registration && controller_name != 'registrations' %>
|
||||
|
|
@ -21,3 +23,14 @@
|
|||
<%- if devise_mapping.omniauthable? && resource_class.omniauth_providers.any? %>
|
||||
<div data-hook="omniauth-sign-in-links"></div>
|
||||
<% end -%>
|
||||
|
||||
<%- if Rails.configuration.x.enable_user_registration && Rails.configuration.x.linkedin_signin_enabled %>
|
||||
<%- if devise_mapping.omniauthable? && resource_class.omniauth_providers.any? && controller_name != 'registrations' %>
|
||||
<%= link_to omniauth_authorize_path(resource_name, :linkedin), :title => "Sign in with LinkedIn" do %>
|
||||
<%= image_tag 'linkedin/Sign-in-Small---Default.png', alt: "Sign in with LinkedIn",
|
||||
onmouseover: "src='#{image_path('linkedin/Sign-in-Small---Hover.png')}'",
|
||||
onmouseout: "src='#{image_path('linkedin/Sign-in-Small---Default.png')}'",
|
||||
onclick: "src='#{image_path('linkedin/Sign-in-Small---Active.png')}'" %>
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
<% end -%>
|
||||
|
|
|
|||
|
|
@ -102,6 +102,9 @@ Rails.application.configure do
|
|||
config.x.enable_user_registration =
|
||||
ENV['ENABLE_USER_REGISTRATION'] == 'false' ? false : true
|
||||
|
||||
# Enable sign in with LinkedIn account
|
||||
config.x.linkedin_signin_enabled = ENV['LINKEDIN_SIGNIN_ENABLED'] == 'true'
|
||||
|
||||
# Use an evented file watcher to asynchronously detect changes in source code,
|
||||
# routes, locales, etc. This feature depends on the listen gem.
|
||||
#config.file_watcher = ActiveSupport::EventedFileUpdateChecker
|
||||
|
|
|
|||
|
|
@ -116,6 +116,9 @@ Rails.application.configure do
|
|||
config.x.enable_user_registration =
|
||||
ENV['ENABLE_USER_REGISTRATION'] == 'false' ? false : true
|
||||
|
||||
# Enable sign in with LinkedIn account
|
||||
config.x.linkedin_signin_enabled = ENV['LINKEDIN_SIGNIN_ENABLED'] == 'true'
|
||||
|
||||
# Use a different logger for distributed setups.
|
||||
# require 'syslog/logger'
|
||||
# config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
|
||||
|
|
|
|||
|
|
@ -287,6 +287,8 @@ Devise.setup do |config|
|
|||
# Add a new OmniAuth provider. Check the wiki for more information on setting
|
||||
# up on your models and hooks.
|
||||
# config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo'
|
||||
config.omniauth :linkedin, ENV['LINKEDIN_KEY'], ENV['LINKEDIN_SECRET'],
|
||||
scope: %w(r_basicprofile r_emailaddress)
|
||||
|
||||
# ==> Warden configuration
|
||||
# If you want to use other strategies, that are not supported by Devise, or
|
||||
|
|
|
|||
|
|
@ -41,7 +41,8 @@ class Extends
|
|||
|
||||
# Data type name should match corresponding model's name
|
||||
REPOSITORY_DATA_TYPES = { RepositoryTextValue: 0,
|
||||
RepositoryDateValue: 1 }
|
||||
RepositoryDateValue: 1,
|
||||
RepositoryListValue: 2 }
|
||||
|
||||
# List of implemented core API versions
|
||||
API_VERSIONS = ['20170715']
|
||||
|
|
@ -49,7 +50,7 @@ class Extends
|
|||
# Array used for injecting names of additional authentication methods for API
|
||||
API_PLUGABLE_AUTH_METHODS = []
|
||||
|
||||
OMNIAUTH_PROVIDERS = []
|
||||
OMNIAUTH_PROVIDERS = [:linkedin, *(:developer if Rails.env.development?)]
|
||||
|
||||
INITIAL_USER_OPTIONS = {}
|
||||
end
|
||||
|
|
|
|||
|
|
@ -11,6 +11,8 @@ Paperclip::Attachment.default_options.merge!(
|
|||
url: '/system/:class/:attachment/:id_partition/:hash/:style/:filename'
|
||||
)
|
||||
|
||||
Paperclip::UriAdapter.register
|
||||
|
||||
if ENV['PAPERCLIP_STORAGE'] == "s3"
|
||||
|
||||
if ENV['S3_BUCKET'].nil? or ENV['AWS_REGION'].nil? or
|
||||
|
|
|
|||
|
|
@ -40,11 +40,17 @@ en:
|
|||
submit: "Resend unlock instructions"
|
||||
links:
|
||||
login: "Log in"
|
||||
login_with_provider: "Log in with SciNote account"
|
||||
signup: "Sign up"
|
||||
forgot: "Forgot your password?"
|
||||
not_receive_confirmation: "Didn't receive confirmation instructions?"
|
||||
not_receive_unlock: "Didn't receive unlock instructions?"
|
||||
sign_in_provider: "Sign in with %{provider}"
|
||||
linkedin:
|
||||
provider_name: "LinkedIn"
|
||||
complete_sign_up: "You have to complete the sign up process"
|
||||
email_already_taken: "SciNote account with email %{email} alreday exists"
|
||||
failed_to_save: "Failed to create new user"
|
||||
|
||||
helpers:
|
||||
label:
|
||||
|
|
@ -1272,6 +1278,8 @@ en:
|
|||
head_title: "Sign up"
|
||||
team_name_label: "Team name"
|
||||
team_name_help: "Team name is required in order to create your own Team. After you create your own Team, you will be able to join other Teams as well."
|
||||
new_with_provider:
|
||||
head_title: "Complete the Sign up"
|
||||
statistics:
|
||||
title: "My statistics"
|
||||
team: "Team"
|
||||
|
|
|
|||
|
|
@ -498,6 +498,8 @@ Rails.application.routes.draw do
|
|||
get 'avatar/:id/:style' => 'users/registrations#avatar', as: 'avatar'
|
||||
post 'avatar_signature' => 'users/registrations#signature'
|
||||
get 'users/auth_token_sign_in' => 'users/sessions#auth_token_create'
|
||||
get 'users/sign_up_provider' => 'users/registrations#new_with_provider'
|
||||
post 'users/complete_sign_up_provider' => 'users/registrations#create_with_provider'
|
||||
end
|
||||
|
||||
namespace :api, defaults: { format: 'json' } do
|
||||
|
|
|
|||
|
|
@ -69,6 +69,12 @@ namespace :data do
|
|||
.where.not(invitation_token: nil)
|
||||
.where("created_at < ?", Devise.invite_for.ago)
|
||||
destroy_users(users)
|
||||
|
||||
# Remove users who didn't finish signup with LinkedIn
|
||||
users = User.joins(:user_identities)
|
||||
.where(confirmed_at: nil)
|
||||
#.where('created_at < ?', Devise.confirm_within.ago)
|
||||
destroy_users(users)
|
||||
end
|
||||
|
||||
desc "Remove temporary and obsolete data"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue