Commit d95e09e5 authored by Michael Rose's avatar Michael Rose

auth: Allow sign-in with DLP SSO

parent 629ec0f6
......@@ -12,6 +12,7 @@ gem 'activerecord-import'
# Auth
gem 'devise'
gem 'devise-async'
gem 'jwt'
gem 'rails_12factor'
......
......@@ -164,6 +164,7 @@ GEM
rails-dom-testing (>= 1, < 3)
railties (>= 4.2.0)
thor (>= 0.14, < 2.0)
jwt (2.1.0)
kaminari (1.0.1)
activesupport (>= 4.1.0)
kaminari-actionview (= 1.0.1)
......@@ -381,6 +382,7 @@ DEPENDENCIES
hashids_rails!
jbuilder (~> 2.0)
jquery-rails
jwt
kaminari
keen
letter_opener
......
require 'jwt'
class SsoController < DeviseController
skip_before_action :verify_authenticity_token
prepend_before_action :require_no_authentication, :only => [:create]
include Devise::Controllers::Helpers
before_action :decode_jwt
def create
if current_user and user.dlp_id == nil
merge_user_and_login current_user
else
create_or_login
end
end
def destroy
sign_out(resource_name)
end
protected
def decode_jwt
@jwt = (JWT.decode params[:auth_token], Rails.application.secrets.sso_key, true)[0]['message']
rescue JWT::ExpiredSignature
warden.custom_failure!
redirect_to root_path, alert: 'Auth token expired.'
end
def create_or_login
# Check for existing account with DLP id.
user = User.where(dlp_id: @jwt['dlp_id']).first
return sign_in(user, scope: :user) if user
# Check for existing account with DLP email.
user = User.where(email: @jwt['dlp_email']).first
if user
merge_user_and_login(user)
end
# Create a new user
user = create_user_from_jwt
sign_in(user, scope: :user)
redirect_to root_path, notice: 'Thanks for creating an account!'
end
def merge_user_and_login(user)
merge_user user
sign_in(user, scope: :user)
redirect_to root_path, notice: "Your DLP account #{@jwt['dlp_username']} was linked to this account."
end
def merge_user(user)
user.dlp_id = @jwt['dlp_id']
user.save!
end
def create_user_from_jwt
# TODO: Check if there's already a username.
user = User.new(:email => @jwt['dlp_email'], username: @jwt['dlp_username'], dlp_id: @jwt['dlp_id'], origin: 'sso')
user.save!
user
end
def invalid_login_attempt
warden.custom_failure!
redirect_to root_path, alert: 'Auth token expired.'
render :json => {:success => false, :message => "Error with your login or password"}, :status => 401
end
end
.page-header
%h1
Sign in
Have a DLP account? Sign in or create an account with DLP.
= form_tag('https://forums.darklordpotter.net/sso', authenticity_token: false) do |f|
%button.btn.btn-default{:type => 'submit'}
Sign in with DLP
%hr
= form_for(resource, :as => resource_name, :url => session_path(resource_name)) do |f|
.form-group
......
......@@ -6,6 +6,7 @@ Rails.application.routes.draw do
post 'login' => 'devise/sessions#create', :as => :user_session
delete 'logout' => 'devise/sessions#destroy', :as => :destroy_user_session
post 'api/login' => 'api_authentication#create'
get 'user/sso' => 'sso#create'
end
authenticate :user, lambda { |u| u.admin? } do
......
......@@ -23,3 +23,4 @@ test:
production:
secret_key_base: <%= ENV["SECRET_KEY_BASE"] %>
hash_id_salt: <%= ENV["HASH_ID_SALT"] %>
sso_key: <%= ENV["DLP_SSO_KEY"] %>
class AddDlpIdToUser < ActiveRecord::Migration[5.1]
def change
add_column :users, :dlp_id, :integer
add_column :users, :origin, :string, default: 'registration'
add_index :users, :dlp_id
end
end
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment