bullet_train-integrations 1.0.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml ADDED
@@ -0,0 +1,7 @@
1
+ ---
2
+ SHA256:
3
+ metadata.gz: 16735ab9ebdc283b4d51ce3c48e3f9d8e4bdc1a948830a169d219dc5ceae43ad
4
+ data.tar.gz: 05ea064e531b662ca8bfc40ebd3666c587cc0c72a3760a1f26fd0132c27739e2
5
+ SHA512:
6
+ metadata.gz: 6e096a839a8c54573c3f9b55af8cea1416a7691eeb71547f2c4432297e1e6c7b6212f2c0889de41c67c804eb433b511c38cd809f522a37363b16b6ba8238d0d2
7
+ data.tar.gz: bfe3ad11d10c9ae465f95568fbe0e6e0ca505bd84dd9065c50402dba7942e0894e1cc44f5e7df8154aaec9fcdd6b80b68923a9322759dcdde282eca6cdd93b4a
data/MIT-LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright 2022 Andrew Culver
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining
4
+ a copy of this software and associated documentation files (the
5
+ "Software"), to deal in the Software without restriction, including
6
+ without limitation the rights to use, copy, modify, merge, publish,
7
+ distribute, sublicense, and/or sell copies of the Software, and to
8
+ permit persons to whom the Software is furnished to do so, subject to
9
+ the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be
12
+ included in all copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,28 @@
1
+ # BulletTrain::Integrations
2
+ Short description and motivation.
3
+
4
+ ## Usage
5
+ How to use my plugin.
6
+
7
+ ## Installation
8
+ Add this line to your application's Gemfile:
9
+
10
+ ```ruby
11
+ gem "bullet_train-integrations"
12
+ ```
13
+
14
+ And then execute:
15
+ ```bash
16
+ $ bundle
17
+ ```
18
+
19
+ Or install it yourself as:
20
+ ```bash
21
+ $ gem install bullet_train-integrations
22
+ ```
23
+
24
+ ## Contributing
25
+ Contribution directions go here.
26
+
27
+ ## License
28
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
data/Rakefile ADDED
@@ -0,0 +1,8 @@
1
+ require "bundler/setup"
2
+
3
+ APP_RAKEFILE = File.expand_path("test/dummy/Rakefile", __dir__)
4
+ load "rails/tasks/engine.rake"
5
+
6
+ load "rails/tasks/statistics.rake"
7
+
8
+ require "bundler/gem_tasks"
@@ -0,0 +1,152 @@
1
+ module Account::Oauth::OmniauthCallbacks::ControllerBase
2
+ extend ActiveSupport::Concern
3
+
4
+ def team_id_from_env
5
+ request.env.dig("omniauth.params", "team_id")&.to_i
6
+ end
7
+
8
+ def failure
9
+ flash[:danger] = "Failed to sign in"
10
+ redirect_to root_path
11
+ end
12
+
13
+ def callback(class_name, team_id)
14
+ oauth_account_class = "Oauth::#{class_name}Account".constantize
15
+ # oauth_accounts_collection = "oauth_#{class_name.underscore}_accounts".to_sym
16
+ oauth_accounts_attribute = "oauth_#{class_name.underscore}_account".to_sym
17
+ integrations_installations_class = "::Integrations::#{class_name}Installation".constantize
18
+ integrations_installations_collection = "integrations_#{class_name.underscore}_installations".to_sym
19
+
20
+ auth = request.env["omniauth.auth"]
21
+
22
+ # if the user didn't click "authorize" on the providers confirmation page, just show them an error.
23
+ if params[:denied]
24
+ message = t("omniauth.team.denied", provider: t(auth.provider))
25
+
26
+ # redirect them to either the integrations page or the registration page.
27
+ path = if team_id
28
+ [:account, team, integrations_installations_collection]
29
+ elsif current_user
30
+ [:account, current_user]
31
+ else
32
+ new_user_registration_path
33
+ end
34
+
35
+ redirect_to path, notice: message
36
+ end
37
+
38
+ # first, keep a record of the oauth account.
39
+ # this belongs to the system, and sometimes becomes associated with a user.
40
+ begin
41
+ oauth_account = oauth_account_class.find_or_create_by(uid: auth.uid)
42
+ oauth_account.update_from_oauth(auth)
43
+ rescue PG::UniqueViolation
44
+ retry
45
+ end
46
+
47
+ # if they're trying to use this account to add an integration to a team.
48
+ if team_id
49
+
50
+ # they must be signed in.
51
+ authenticate_user!
52
+
53
+ unless (team = current_user.teams.find_by(id: team_id))
54
+ raise "user is adding an integration to a team they don't belong to?"
55
+ end
56
+
57
+ # now we check whether they're able to install new integrations for this team.
58
+ if can? :create, integrations_installations_class.new(:team => team, oauth_accounts_attribute => oauth_account)
59
+
60
+ # if the oauth account is already present for the team ..
61
+ if team.send(integrations_installations_collection).find_by(oauth_accounts_attribute => oauth_account)
62
+ message = t("omniauth.team.already_present", provider: t(auth.provider))
63
+
64
+ else
65
+ # otherwise, create a new integration for this team.
66
+ team.send(integrations_installations_collection).create(:name => oauth_account.name, oauth_accounts_attribute => oauth_account)
67
+ message = t("omniauth.team.connected", provider: t(auth.provider))
68
+
69
+ end
70
+
71
+ else
72
+
73
+ # if they don't have access to add integrations to the team, show them an error.
74
+ message = t("omniauth.team.not_allowed", provider: t(auth.provider))
75
+
76
+ end
77
+
78
+ # in all of these situations, we take them back to the team's oauth accounts index page for this provider.
79
+ redirect_to [:account, team, integrations_installations_collection], notice: message
80
+
81
+ # if they're already signed in, they're trying to add it to their account.
82
+ elsif current_user
83
+
84
+ # if the account is already connected to a user, we can't connect it again.
85
+ # this would potentially lock someone else out of their account.
86
+ if oauth_account.user
87
+ message_key = oauth_account.user == current_user ? "omniauth.user.reconnected" : "omniauth.user.already_registered"
88
+ redirect_to edit_account_user_path(current_user), notice: t(message_key, provider: t(auth.provider))
89
+ else
90
+ oauth_account.update(user: current_user)
91
+ redirect_to edit_account_user_path(current_user), notice: t("omniauth.user.connected", provider: t(auth.provider))
92
+ end
93
+
94
+ # if they're not trying to add it to a team, they're trying to sign in or sign up.
95
+ # if they're already associated with a user record, just sign them in.
96
+ elsif oauth_account.user
97
+
98
+ sign_in oauth_account.user
99
+ handle_outstanding_invitation
100
+ redirect_to account_dashboard_path
101
+
102
+ # if they're not associated with a user and they're allowed to sign up.
103
+ elsif show_sign_up_options?
104
+
105
+ # we're going to try to create a new user account.
106
+ # if the oauth provider gave us an email address, use that, otherwise use a
107
+ # temporary email placeholder. (we'll never show the temporary to the user.)
108
+ # this has to be a "real" email address so we don't trip up any email validators.
109
+ # however, this is secure because even if someone controlled `bullettrain.co`,
110
+ # they would never be able to guess the hex code to reset the password.
111
+ # even that is a rare edge case, because we force people to update this in onboarding.
112
+ email = auth.info.email.present? ? auth.info.email : "noreply+#{SecureRandom.hex}@bullettrain.co"
113
+
114
+ # if the user already exists with the email address on the account ..
115
+ if User.find_by(email: email)
116
+
117
+ # we can't sign them in, because they haven't added the oauth account to
118
+ # their account yet for sign in. there is a potential security loophole
119
+ # here if you allow them to do this at worst, and at best you're
120
+ # depending on the security of the oauth provider to have verified the
121
+ # email address on the account.
122
+ redirect_to new_user_session_path(user: {email: email}, email_exists: true), notice: "Sorry, there is already a user registered with the email address #{email}, but this #{t(auth.provider)} account isn't configured for login with that account. Please sign in using your password and then add this account."
123
+
124
+ else
125
+
126
+ # if the user doesn't exist in the database yet, great!
127
+ # let's create it and sign them in.
128
+ password = Devise.friendly_token[0, 20]
129
+ user = User.create(email: email, password: password, password_confirmation: password)
130
+
131
+ oauth_account.update(user: user)
132
+
133
+ sign_in user
134
+ handle_outstanding_invitation
135
+
136
+ # if the user doesn't have a team at this point, create one.
137
+ unless user.teams.any?
138
+ user.create_default_team
139
+
140
+ # if a user is signing up for the first time *and* creating their own team,
141
+ # this is a ux shortcut that makes sense: automatically install their oauth account as an integration.
142
+ user.teams.first.send(integrations_installations_collection).create(:name => oauth_account.name, oauth_accounts_attribute => oauth_account)
143
+ end
144
+
145
+ redirect_to account_dashboard_path
146
+ end
147
+
148
+ else
149
+ redirect_to new_user_session_path, notice: t("omniauth.user.account_not_found", provider: t(auth.provider))
150
+ end
151
+ end
152
+ end
data/config/routes.rb ADDED
@@ -0,0 +1,2 @@
1
+ Rails.application.routes.draw do
2
+ end
@@ -0,0 +1,6 @@
1
+ module BulletTrain
2
+ module Integrations
3
+ class Engine < ::Rails::Engine
4
+ end
5
+ end
6
+ end
@@ -0,0 +1,5 @@
1
+ module BulletTrain
2
+ module Integrations
3
+ VERSION = "1.0.0"
4
+ end
5
+ end
@@ -0,0 +1,8 @@
1
+ require "bullet_train/integrations/version"
2
+ require "bullet_train/integrations/engine"
3
+
4
+ module BulletTrain
5
+ module Integrations
6
+ # Your code goes here...
7
+ end
8
+ end
@@ -0,0 +1,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :bullet_train_integrations do
3
+ # # Task goes here
4
+ # end
metadata ADDED
@@ -0,0 +1,69 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: bullet_train-integrations
3
+ version: !ruby/object:Gem::Version
4
+ version: 1.0.0
5
+ platform: ruby
6
+ authors:
7
+ - Andrew Culver
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+ date: 2022-03-04 00:00:00.000000000 Z
12
+ dependencies:
13
+ - !ruby/object:Gem::Dependency
14
+ name: rails
15
+ requirement: !ruby/object:Gem::Requirement
16
+ requirements:
17
+ - - ">="
18
+ - !ruby/object:Gem::Version
19
+ version: 6.0.0
20
+ type: :runtime
21
+ prerelease: false
22
+ version_requirements: !ruby/object:Gem::Requirement
23
+ requirements:
24
+ - - ">="
25
+ - !ruby/object:Gem::Version
26
+ version: 6.0.0
27
+ description: Bullet Train Integrations
28
+ email:
29
+ - andrew.culver@gmail.com
30
+ executables: []
31
+ extensions: []
32
+ extra_rdoc_files: []
33
+ files:
34
+ - MIT-LICENSE
35
+ - README.md
36
+ - Rakefile
37
+ - app/assets/config/bullet_train_integrations_manifest.js
38
+ - app/controllers/concerns/account/oauth/omniauth_callbacks/controller_base.rb
39
+ - config/routes.rb
40
+ - lib/bullet_train/integrations.rb
41
+ - lib/bullet_train/integrations/engine.rb
42
+ - lib/bullet_train/integrations/version.rb
43
+ - lib/tasks/bullet_train/integrations_tasks.rake
44
+ homepage: https://github.com/bullet-train-co/bullet_train-integrations
45
+ licenses:
46
+ - MIT
47
+ metadata:
48
+ homepage_uri: https://github.com/bullet-train-co/bullet_train-integrations
49
+ source_code_uri: https://github.com/bullet-train-co/bullet_train-integrations
50
+ post_install_message:
51
+ rdoc_options: []
52
+ require_paths:
53
+ - lib
54
+ required_ruby_version: !ruby/object:Gem::Requirement
55
+ requirements:
56
+ - - ">="
57
+ - !ruby/object:Gem::Version
58
+ version: '0'
59
+ required_rubygems_version: !ruby/object:Gem::Requirement
60
+ requirements:
61
+ - - ">="
62
+ - !ruby/object:Gem::Version
63
+ version: '0'
64
+ requirements: []
65
+ rubygems_version: 3.2.22
66
+ signing_key:
67
+ specification_version: 4
68
+ summary: Bullet Train Integrations
69
+ test_files: []