infinum_id 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.gitignore +12 -0
- data/.rspec +3 -0
- data/.rubocop.yml +40 -0
- data/.travis.yml +7 -0
- data/CODE_OF_CONDUCT.md +74 -0
- data/Gemfile +6 -0
- data/Gemfile.lock +262 -0
- data/LICENSE.txt +21 -0
- data/README.md +43 -0
- data/Rakefile +21 -0
- data/app/controllers/api/base_controller.rb +6 -0
- data/app/controllers/api/webhooks_controller.rb +42 -0
- data/app/controllers/infinum_id/application_controller.rb +6 -0
- data/app/controllers/infinum_id/users/omniauth_callbacks_controller.rb +30 -0
- data/app/controllers/infinum_id/users_controller.rb +9 -0
- data/app/helpers/infinum_id/path_helper.rb +7 -0
- data/app/mailers/application_mailer.rb +4 -0
- data/app/mailers/user_mailer.rb +20 -0
- data/app/models/infinum_id/application_record.rb +5 -0
- data/app/services/infinum_id/after_user_update.rb +5 -0
- data/app/services/infinum_id/requests/invite_sender.rb +90 -0
- data/app/services/infinum_id/users/finder.rb +9 -0
- data/app/services/infinum_id/users/invite.rb +29 -0
- data/app/services/infinum_id/users/updater.rb +31 -0
- data/app/views/user_mailer/invite_email.html.erb +8 -0
- data/app/views/user_mailer/invite_email.text.erb +5 -0
- data/app/views/user_mailer/welcome_email.html.erb +8 -0
- data/app/views/user_mailer/welcome_email.text.erb +5 -0
- data/app/workers/infinum_id/users/invite_worker.rb +11 -0
- data/bin/console +15 -0
- data/bin/setup +8 -0
- data/config/initializers/devise.rb +22 -0
- data/config/initializers/sidekiq.rb +7 -0
- data/config/routes.rb +11 -0
- data/infinum_id.gemspec +56 -0
- data/lib/generators/infinum_id/install_generator.rb +58 -0
- data/lib/generators/templates/migration.rb +25 -0
- data/lib/generators/templates/user.rb +19 -0
- data/lib/infinum_id/engine.rb +4 -0
- data/lib/infinum_id/version.rb +3 -0
- data/lib/infinum_id.rb +27 -0
- metadata +380 -0
@@ -0,0 +1,90 @@
|
|
1
|
+
module InfinumId
|
2
|
+
module Requests
|
3
|
+
class InviteSender
|
4
|
+
def initialize(user_id, current_user_uid)
|
5
|
+
@user = User.find(user_id)
|
6
|
+
@current_user_uid = current_user_uid
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.call(user_id, current_user_uid)
|
10
|
+
new(user_id, current_user_uid).call
|
11
|
+
end
|
12
|
+
|
13
|
+
def call
|
14
|
+
send_invite_request
|
15
|
+
handle_response
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
attr_reader :user, :current_user_uid, :response
|
21
|
+
|
22
|
+
def send_invite_request
|
23
|
+
@response = HTTP.headers(headers).post(invitation_url, json: invitation_params)
|
24
|
+
end
|
25
|
+
|
26
|
+
def handle_response
|
27
|
+
case response.code
|
28
|
+
when 200
|
29
|
+
update_user
|
30
|
+
send_email if Rails.configuration.infinum_id_send_email
|
31
|
+
when 400, 403, 404
|
32
|
+
return response.to_s
|
33
|
+
when 401..599
|
34
|
+
raise response.to_s
|
35
|
+
end
|
36
|
+
end
|
37
|
+
|
38
|
+
def update_user
|
39
|
+
user.update(user_params)
|
40
|
+
end
|
41
|
+
|
42
|
+
def send_email
|
43
|
+
params[:invitation_accept_path].blank? ? send_welcome_email : send_invite_email
|
44
|
+
end
|
45
|
+
|
46
|
+
def send_invite_email
|
47
|
+
UserMailer.with(
|
48
|
+
user_id: user.id, invited_by_uid: current_user_uid,
|
49
|
+
accept_path: params[:invitation_accept_path]
|
50
|
+
).invite_email.deliver_later
|
51
|
+
end
|
52
|
+
|
53
|
+
def send_welcome_email
|
54
|
+
UserMailer.with(
|
55
|
+
user_id: user.id, invited_by_uid: current_user_uid
|
56
|
+
).welcome_email.deliver_later
|
57
|
+
end
|
58
|
+
|
59
|
+
def params
|
60
|
+
@params ||= ActionController::Parameters.new(response.parse)
|
61
|
+
end
|
62
|
+
|
63
|
+
def user_params
|
64
|
+
params.require(:user).permit(
|
65
|
+
:uid, :email, :first_name, :last_name, :slack_username,
|
66
|
+
:time_zone, :deactivated_at, :avatar_url
|
67
|
+
)
|
68
|
+
end
|
69
|
+
|
70
|
+
def headers
|
71
|
+
{
|
72
|
+
client_id: InfinumId.client_id,
|
73
|
+
client_secret: InfinumId.client_secret
|
74
|
+
}
|
75
|
+
end
|
76
|
+
|
77
|
+
def invitation_params
|
78
|
+
{
|
79
|
+
user: user.as_json,
|
80
|
+
invited_by_uid: current_user_uid,
|
81
|
+
send_invitation: !Rails.configuration.infinum_id_send_email
|
82
|
+
}
|
83
|
+
end
|
84
|
+
|
85
|
+
def invitation_url
|
86
|
+
"#{InfinumId.url}/api/invitations"
|
87
|
+
end
|
88
|
+
end
|
89
|
+
end
|
90
|
+
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module InfinumId
|
2
|
+
module Users
|
3
|
+
class Invite
|
4
|
+
def initialize(user_params, current_user)
|
5
|
+
@user_params = user_params
|
6
|
+
@current_user = current_user
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.call(user_params, current_user)
|
10
|
+
new(user_params, current_user).call
|
11
|
+
end
|
12
|
+
|
13
|
+
def call
|
14
|
+
@user = User.create(@user_params)
|
15
|
+
|
16
|
+
send_invite_request if @user.errors.empty?
|
17
|
+
@user
|
18
|
+
end
|
19
|
+
|
20
|
+
private
|
21
|
+
|
22
|
+
attr_reader :current_user, :user
|
23
|
+
|
24
|
+
def send_invite_request
|
25
|
+
InfinumId::Users::InviteWorker.perform_async(@user.id, current_user.uid)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,31 @@
|
|
1
|
+
module InfinumId
|
2
|
+
module Users
|
3
|
+
class Updater
|
4
|
+
def initialize(params, user)
|
5
|
+
@user_params = params.slice(*user_column_names).deep_symbolize_keys
|
6
|
+
@user = user
|
7
|
+
end
|
8
|
+
|
9
|
+
def self.call(params, user)
|
10
|
+
new(params, user).call
|
11
|
+
end
|
12
|
+
|
13
|
+
def call
|
14
|
+
update_user
|
15
|
+
InfinumId::AfterUserUpdate.call(user)
|
16
|
+
end
|
17
|
+
|
18
|
+
private
|
19
|
+
|
20
|
+
attr_reader :user_params, :user
|
21
|
+
|
22
|
+
def update_user
|
23
|
+
user.update(user_params)
|
24
|
+
end
|
25
|
+
|
26
|
+
def user_column_names
|
27
|
+
User.column_names
|
28
|
+
end
|
29
|
+
end
|
30
|
+
end
|
31
|
+
end
|
data/bin/console
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
|
3
|
+
require "bundler/setup"
|
4
|
+
require 'rails/all'
|
5
|
+
require "infinum_id"
|
6
|
+
|
7
|
+
# You can add fixtures and/or initialization code here to make experimenting
|
8
|
+
# with your gem easier. You can also use a different console, if you like.
|
9
|
+
|
10
|
+
# (If you use this, don't forget to add pry to your Gemfile!)
|
11
|
+
require "pry"
|
12
|
+
Pry.start
|
13
|
+
|
14
|
+
# require "irb"
|
15
|
+
# IRB.start(__FILE__)
|
data/bin/setup
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Devise.setup do |config|
|
2
|
+
require 'devise/orm/active_record'
|
3
|
+
|
4
|
+
config.case_insensitive_keys = [:email]
|
5
|
+
config.strip_whitespace_keys = [:email]
|
6
|
+
|
7
|
+
config.skip_session_storage = [:http_auth]
|
8
|
+
|
9
|
+
config.stretches = Rails.env.test? ? 1 : 11
|
10
|
+
|
11
|
+
config.reconfirmable = true
|
12
|
+
|
13
|
+
config.expire_all_remember_me_on_sign_out = true
|
14
|
+
|
15
|
+
config.email_regexp = /\A[^@\s]+@[^@\s]+\z/
|
16
|
+
|
17
|
+
config.sign_out_via = :get
|
18
|
+
|
19
|
+
# ==> OmniAuth
|
20
|
+
config.omniauth :infinum_id, InfinumId.client_id, InfinumId.client_secret,
|
21
|
+
client_options: { site: InfinumId.url }
|
22
|
+
end
|
data/config/routes.rb
ADDED
data/infinum_id.gemspec
ADDED
@@ -0,0 +1,56 @@
|
|
1
|
+
lib = File.expand_path('lib', __dir__)
|
2
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
3
|
+
require 'infinum_id/version'
|
4
|
+
|
5
|
+
Gem::Specification.new do |spec|
|
6
|
+
spec.name = 'infinum_id'
|
7
|
+
spec.version = InfinumId::VERSION
|
8
|
+
spec.authors = ['Dajana Jeroncic']
|
9
|
+
spec.email = ['dajana.jeroncic@infinum.hr']
|
10
|
+
|
11
|
+
spec.summary = 'Write a short summary, because RubyGems requires one.'
|
12
|
+
spec.description = 'Write a longer description or delete this line.'
|
13
|
+
spec.homepage = 'https://github.com/infinum/rails-infinum-id-engine'
|
14
|
+
spec.license = 'MIT'
|
15
|
+
|
16
|
+
# Prevent pushing this gem to RubyGems.org. To allow pushes either set the 'allowed_push_host'
|
17
|
+
# to allow pushing to a single host or delete this section to allow pushing to any host.
|
18
|
+
if spec.respond_to?(:metadata)
|
19
|
+
spec.metadata['allowed_push_host'] = 'https://rubygems.org'
|
20
|
+
else
|
21
|
+
raise 'RubyGems 2.0 or newer is required to protect against ' \
|
22
|
+
'public gem pushes.'
|
23
|
+
end
|
24
|
+
|
25
|
+
# Specify which files should be added to the gem when it is released.
|
26
|
+
# The `git ls-files -z` loads the files in the RubyGem that have been added into git.
|
27
|
+
spec.files = Dir.chdir(File.expand_path(__dir__)) do
|
28
|
+
`git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
|
29
|
+
end
|
30
|
+
spec.bindir = 'exe'
|
31
|
+
spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
|
32
|
+
spec.require_paths = ['lib']
|
33
|
+
|
34
|
+
spec.add_development_dependency 'bundler'
|
35
|
+
spec.add_development_dependency 'pry'
|
36
|
+
spec.add_development_dependency 'factory_bot_rails'
|
37
|
+
spec.add_development_dependency 'faker'
|
38
|
+
spec.add_development_dependency 'pry-rails'
|
39
|
+
spec.add_development_dependency 'pry-byebug'
|
40
|
+
spec.add_development_dependency 'rake', '~> 10.0'
|
41
|
+
spec.add_development_dependency 'rspec', '~> 3.0'
|
42
|
+
spec.add_development_dependency 'rspec-rails'
|
43
|
+
spec.add_development_dependency 'rails'
|
44
|
+
spec.add_development_dependency 'simplecov'
|
45
|
+
spec.add_development_dependency 'sqlite3'
|
46
|
+
spec.add_development_dependency 'webmock'
|
47
|
+
|
48
|
+
spec.add_dependency 'bundler'
|
49
|
+
spec.add_dependency 'devise'
|
50
|
+
spec.add_dependency 'http'
|
51
|
+
spec.add_dependency 'omniauth-infinum_id'
|
52
|
+
spec.add_dependency 'redis'
|
53
|
+
spec.add_dependency 'redis-namespace'
|
54
|
+
spec.add_dependency 'responders'
|
55
|
+
spec.add_dependency 'sidekiq'
|
56
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require 'rails/generators/active_record'
|
2
|
+
|
3
|
+
module InfinumId
|
4
|
+
module Generators
|
5
|
+
class InstallGenerator < ::Rails::Generators::Base
|
6
|
+
include Rails::Generators::Migration
|
7
|
+
|
8
|
+
source_root File.expand_path('../templates', __dir__)
|
9
|
+
|
10
|
+
def inject_secrets
|
11
|
+
insert_into_file 'config/secrets.yml', secrets_template,
|
12
|
+
after: "bugsnag_api_key: <%= Figaro.env.bugsnag_api_key! %>\n"
|
13
|
+
end
|
14
|
+
|
15
|
+
def copy_migration
|
16
|
+
migration_template 'migration.rb', 'db/migrate/create_users.rb'
|
17
|
+
end
|
18
|
+
|
19
|
+
def copy_model
|
20
|
+
template 'user.rb', 'app/models/user.rb'
|
21
|
+
end
|
22
|
+
|
23
|
+
def inject_routes
|
24
|
+
insert_into_file 'config/routes.rb', routes_template,
|
25
|
+
after: "Rails.application.routes.draw do\n"
|
26
|
+
end
|
27
|
+
|
28
|
+
def self.next_migration_number(dirname)
|
29
|
+
ActiveRecord::Generators::Base.next_migration_number(dirname)
|
30
|
+
end
|
31
|
+
|
32
|
+
def migration_version
|
33
|
+
"[#{Rails::VERSION::MAJOR}.#{Rails::VERSION::MINOR}]"
|
34
|
+
end
|
35
|
+
|
36
|
+
private
|
37
|
+
|
38
|
+
def routes_template
|
39
|
+
<<RUBY
|
40
|
+
devise_for :users, controllers: {
|
41
|
+
omniauth_callbacks: 'infinum_id/users/omniauth_callbacks'
|
42
|
+
}
|
43
|
+
RUBY
|
44
|
+
end
|
45
|
+
|
46
|
+
def secrets_template
|
47
|
+
<<RUBY
|
48
|
+
redis_server_url: <%= Figaro.env.redis_server_url %>
|
49
|
+
redis_client_url: <%= Figaro.env.redis_client_url %>
|
50
|
+
infinum_id:
|
51
|
+
client_id: <%= Figaro.env.infinum_id_client_id %>
|
52
|
+
client_secret: <%= Figaro.env.infinum_id_client_secret %>
|
53
|
+
url: <%= Figaro.env.infinum_id_client_url %>
|
54
|
+
RUBY
|
55
|
+
end
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
@@ -0,0 +1,25 @@
|
|
1
|
+
class CreateUsers < ActiveRecord::Migration<%= migration_version %>
|
2
|
+
def change # rubocop:disable Metrics/MethodLength
|
3
|
+
create_table :users do |t|
|
4
|
+
t.string :email, null: false, default: ''
|
5
|
+
|
6
|
+
t.string :first_name
|
7
|
+
t.string :last_name
|
8
|
+
|
9
|
+
t.string :slack_username
|
10
|
+
t.string :time_zone
|
11
|
+
|
12
|
+
t.string :avatar_url
|
13
|
+
|
14
|
+
# Omniauth
|
15
|
+
t.string :provider
|
16
|
+
t.string :uid
|
17
|
+
|
18
|
+
t.datetime :deactivated_at
|
19
|
+
|
20
|
+
t.timestamps null: false
|
21
|
+
end
|
22
|
+
|
23
|
+
add_index :users, :email, unique: true
|
24
|
+
end
|
25
|
+
end
|
@@ -0,0 +1,19 @@
|
|
1
|
+
class User < ApplicationRecord
|
2
|
+
devise :omniauthable, omniauth_providers: [:infinum_id]
|
3
|
+
|
4
|
+
validates :email, uniqueness: true
|
5
|
+
|
6
|
+
def active_for_authentication?
|
7
|
+
super && !deactivated_at
|
8
|
+
end
|
9
|
+
|
10
|
+
def as_json
|
11
|
+
{
|
12
|
+
email: email,
|
13
|
+
first_name: first_name,
|
14
|
+
last_name: last_name,
|
15
|
+
slack_username: slack_username,
|
16
|
+
time_zone: time_zone
|
17
|
+
}
|
18
|
+
end
|
19
|
+
end
|
data/lib/infinum_id.rb
ADDED
@@ -0,0 +1,27 @@
|
|
1
|
+
require 'infinum_id/version'
|
2
|
+
require 'omniauth/infinum_id'
|
3
|
+
require 'infinum_id/engine'
|
4
|
+
require 'devise'
|
5
|
+
require 'sidekiq'
|
6
|
+
|
7
|
+
module InfinumId
|
8
|
+
def self.url
|
9
|
+
dig_secret(:url)
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.client_id
|
13
|
+
dig_secret(:client_id)
|
14
|
+
end
|
15
|
+
|
16
|
+
def self.client_secret
|
17
|
+
dig_secret(:client_secret)
|
18
|
+
end
|
19
|
+
|
20
|
+
def self.dig_secret(key)
|
21
|
+
if Rails::VERSION::MAJOR >= 5
|
22
|
+
Rails.application.secrets.dig(:infinum_id, key)
|
23
|
+
else
|
24
|
+
Rails.application.secrets.dig(:infinum_id, key.to_s)
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|