Skip to content

Commit 8811c0a

Browse files
authored
Feature/sup 303 ruby add mfa example app (#20)
* upgrades to ruby 2.7 and also adds most style changes with most session management in place * removes .DS_Store files * fully fleshed out app with styling * adds README with updated steps
1 parent 6bac676 commit 8811c0a

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

52 files changed

+1562
-272
lines changed

.DS_Store

6 KB
Binary file not shown.

ruby-admin-portal-example/app.rb

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
require 'sinatra'
33
require 'workos'
44
require 'json'
5+
require 'pry'
56

67
$organization
78

@@ -17,7 +18,7 @@
1718
organizations = WorkOS::Organizations.list_organizations(
1819
domains: domains
1920
)
20-
21+
binding.pry
2122
if organizations.data.length == 0
2223
$organization = WorkOS::Organizations.create_organization(
2324
name: organizationName,
@@ -36,7 +37,7 @@
3637
organization_id = $organization.id # ... The ID of the organization to start an Admin Portal session for
3738
link = WorkOS::Portal.generate_link(
3839
organization: organization_id,
39-
intent: 'sso',
40+
intent: 'dsync',
4041
)
4142
redirect link
4243
end

ruby-mfa-example/.env.example

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,2 @@
1+
WORKOS_API_KEY=<Replace with your key>
2+
WORKOS_CLIENT_ID=<Replace with your client ID>

ruby-mfa-example/.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.env

ruby-mfa-example/.ruby-version

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
2.7.1

ruby-mfa-example/Gemfile

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
# frozen_string_literal: true
2+
3+
source 'https://rubygems.org'
4+
5+
gem 'dotenv'
6+
gem 'sinatra'
7+
gem 'workos'
8+
gem 'pry'

ruby-mfa-example/Gemfile.lock

Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
GEM
2+
remote: https://rubygems.org/
3+
specs:
4+
coderay (1.1.3)
5+
dotenv (2.7.6)
6+
method_source (1.0.0)
7+
mustermann (1.1.1)
8+
ruby2_keywords (~> 0.0.1)
9+
pry (0.14.1)
10+
coderay (~> 1.1)
11+
method_source (~> 1.0)
12+
rack (2.2.3)
13+
rack-protection (2.2.0)
14+
rack
15+
ruby2_keywords (0.0.5)
16+
sinatra (2.2.0)
17+
mustermann (~> 1.0)
18+
rack (~> 2.2)
19+
rack-protection (= 2.2.0)
20+
tilt (~> 2.0)
21+
sorbet-runtime (0.5.9859)
22+
tilt (2.0.10)
23+
workos (2.2.0)
24+
sorbet-runtime (~> 0.5)
25+
26+
PLATFORMS
27+
ruby
28+
29+
DEPENDENCIES
30+
dotenv
31+
pry
32+
sinatra
33+
workos
34+
35+
BUNDLED WITH
36+
2.1.4

ruby-mfa-example/LICENSE

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
MIT License
2+
3+
Copyright (c) 2020 WorkOS
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

ruby-mfa-example/README.md

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
# ruby-mfa-example
2+
3+
An example Sinatra application demonstrating how Magic Link works with WorkOS and Ruby.
4+
5+
## Clone and Install
6+
7+
1. Clone the main repo:
8+
9+
```sh
10+
git clone https://github.com/workos-inc/ruby-example-applications.git
11+
```
12+
13+
2. Navigate to the MFA app within the main repo and install dependencies:
14+
15+
```sh
16+
cd ruby-example-applications/ruby-mfa-example && bundle install
17+
```
18+
19+
## Configure your environment
20+
21+
1. Grab your [API Key](https://dashboard.workos.com/api-keys) and your [Client ID](https://dashboard.workos.com/configuration).
22+
2. Run `cp .env.example .env` and add your API key and Client ID. The `workos` gem will read your API key from the ENV variable `WORKOS_API_KEY` and your Client ID from the ENV variable `WORKOS_CLIENT_ID`. You may also set the API key and Client ID yourself by adding `WorkOS.key = $YOUR_API_KEY` and `CLIENT_ID = $YOUR_CLIENT_ID` to `app.rb`.
23+
24+
## Run the app
25+
26+
```sh
27+
ruby app.rb
28+
```
29+
30+
Head to `http://localhost:4567` and you're all set!
31+
32+
For more information, see the [WorkOS Ruby SDK documentation](https://docs.workos.com/sdk/ruby).

ruby-mfa-example/app.rb

Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
# frozen_string_literal: true
2+
3+
require 'dotenv/load'
4+
require 'sinatra'
5+
require 'workos'
6+
require 'json'
7+
require 'pry'
8+
use Rack::Session::Pool
9+
10+
# Pull API key from ENV variable
11+
WorkOS.key = ENV['WORKOS_API_KEY']
12+
13+
# Configure your Redirect URIs on the dashboard configuration
14+
# page: https://dashboard.workos.com/sso/configuration
15+
16+
17+
get '/' do
18+
if session[:factor_list].nil?
19+
session[:factor_list] ||= []
20+
@factors = session[:factor_list]
21+
session[:current_factor_qr] = ''
22+
session[:phone_number] = ''
23+
erb :index, :layout => :layout
24+
else
25+
@factors=session[:factor_list]
26+
erb :index, :layout => :layout
27+
end
28+
end
29+
30+
31+
get '/enroll_factor_details' do
32+
erb :enroll_factor, :layout => :layout
33+
end
34+
35+
post '/enroll_factor' do
36+
factor_type = params[:type]
37+
totp_issuer = params[:totp_issuer]
38+
totp_user = params[:totp_user]
39+
phone_number = params[:phone_number]
40+
41+
42+
new_factor = WorkOS::MFA.enroll_factor(
43+
type: factor_type,
44+
phone_number: phone_number,
45+
totp_issuer: totp_issuer,
46+
totp_user: totp_user
47+
)
48+
session[:factor_list] << new_factor
49+
@factors = session[:factor_list]
50+
redirect '/'
51+
end
52+
53+
get '/factor_detail' do
54+
factors = session[:factor_list]
55+
@factor = factors.select {|factor| factor.id == params[:id] }.first
56+
if @factor.type == 'sms'
57+
@phone_number = @factor .sms[:phone_number]
58+
session[:phone_numer] = @phone_number
59+
elsif @factor.type == 'totp'
60+
@current_factor_qr = @factor.totp[:qr_code]
61+
session[:current_factor_qr] = @current_factor_qr
62+
end
63+
session[:current_factor] = @factor.id
64+
session[:current_factor_type] = @factor.type
65+
erb :factor_detail, :layout => :layout
66+
end
67+
68+
post '/challenge_factor' do
69+
if session[:current_factor_type] == 'sms'
70+
message = params[:sms_message]
71+
session[:message] = message
72+
challenge = WorkOS::MFA.challenge_factor(
73+
authentication_factor_id: session[:current_factor],
74+
sms_template: message,
75+
)
76+
else
77+
challenge = WorkOS::MFA.challenge_factor(
78+
authentication_factor_id: session[:current_factor],
79+
)
80+
end
81+
session[:challenge_id] = challenge.id
82+
83+
erb :challenge_factor, :layout => :layout
84+
end
85+
86+
post '/verify_factor' do
87+
code = params[:code]
88+
challenge_id = session[:challenge_id]
89+
verify_factor = WorkOS::MFA.verify_factor(
90+
authentication_challenge_id: challenge_id,
91+
code: code
92+
)
93+
@challenge = verify_factor.challenge
94+
@valid = verify_factor.valid
95+
@type = session[:type]
96+
erb :challenge_success, :layout => :layout
97+
end
98+
99+
get '/clear_session' do
100+
session.clear
101+
redirect '/'
102+
end

0 commit comments

Comments
 (0)