onelogin 1.3.0 → 1.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +70 -0
- data/examples/events-to-csv.rb +2 -2
- data/examples/rails-custom-login-page/app/assets/stylesheets/application.css +3 -3
- data/examples/rails-custom-login-page/app/controllers/sessions_controller.rb +26 -0
- data/examples/rails-custom-login-page/app/helpers/sessions_helper.rb +27 -0
- data/examples/rails-custom-login-page/app/views/dashboard/index.html.erb +41 -28
- data/examples/rails-custom-login-page/app/views/home/index.html.erb +136 -33
- data/examples/rails-custom-login-page/app/views/layouts/application.html.erb +1 -0
- data/examples/rails-custom-login-page/app/views/users/index.html.erb +7 -7
- data/examples/rails-custom-login-page/app/views/users/show.html.erb +6 -4
- data/examples/rails-custom-login-page/config/routes.rb +2 -0
- data/lib/onelogin/api/client.rb +455 -4
- data/lib/onelogin/api/cursor.rb +16 -5
- data/lib/onelogin/api/models.rb +2 -0
- data/lib/onelogin/api/models/privilege.rb +51 -0
- data/lib/onelogin/api/models/statement.rb +36 -0
- data/lib/onelogin/api/util/constants.rb +86 -0
- data/lib/onelogin/api/util/parser.rb +24 -10
- data/lib/onelogin/version.rb +1 -1
- metadata +5 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b149586910635855872b58c39e17cecf82dbf489
|
4
|
+
data.tar.gz: 1886b20c18c654706ba9b815187a1ab33bb9f5ab
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 9786512a9794cdc1e267436ed1021d275ab05c147b4f80e01a5a6add0027abb12a9fac0148877cfe91ac099ce46c7d6e4ece02a25555ae0dfcbe51910b3dd054
|
7
|
+
data.tar.gz: 2f5aa83177a386e77c256ad884e4bd1fbdcf945f7c42f32a82b6d09cbdb3abbc38404abbf6728137369784eb88f96077d3c58648ba7b2555ca1e5a13812edf00
|
data/README.md
CHANGED
@@ -341,6 +341,76 @@ sent = client.send_invite_link("user@example.com")
|
|
341
341
|
#Get Apps to Embed for a User
|
342
342
|
embed_token = "30e256c101cd0d2e731de1ec222e93c4be8a1572"
|
343
343
|
apps = client.get_embed_apps("30e256c101cd0d2e731de1ec222e93c4be8a1572", "user@example.com")
|
344
|
+
|
345
|
+
# Get Privileges
|
346
|
+
privileges = client.get_privileges()
|
347
|
+
|
348
|
+
# Create Privilege
|
349
|
+
name = "privilege_example"
|
350
|
+
version = "2018-05-18"
|
351
|
+
|
352
|
+
statement1 = OneLogin::Api::Models::Statement.new(
|
353
|
+
"Allow",
|
354
|
+
[
|
355
|
+
"users:List",
|
356
|
+
"users:Get",
|
357
|
+
],
|
358
|
+
["*"]
|
359
|
+
)
|
360
|
+
|
361
|
+
statement2 = OneLogin::Api::Models::Statement.new(
|
362
|
+
"Allow",
|
363
|
+
[
|
364
|
+
"apps:List",
|
365
|
+
"apps:Get",
|
366
|
+
],
|
367
|
+
["*"]
|
368
|
+
)
|
369
|
+
|
370
|
+
statements = [
|
371
|
+
statement1,
|
372
|
+
statement2
|
373
|
+
]
|
374
|
+
privilege = client.create_privilege(name, version, statements)
|
375
|
+
|
376
|
+
# Update Privilege
|
377
|
+
name = "privilege_example_updated"
|
378
|
+
statement2 = OneLogin::Api::Models::Statement.new(
|
379
|
+
"Allow",
|
380
|
+
[
|
381
|
+
"apps:List",
|
382
|
+
],
|
383
|
+
["*"]
|
384
|
+
)
|
385
|
+
statements = [
|
386
|
+
statement1,
|
387
|
+
statement2
|
388
|
+
]
|
389
|
+
privilege = client.update_privilege(privilege.id, name, version, statements)
|
390
|
+
|
391
|
+
# Get Privilege
|
392
|
+
privileges = client.get_privilege(privilege.id)
|
393
|
+
|
394
|
+
# Delete Privilege
|
395
|
+
result = client.delete_privilege(privilege.id)
|
396
|
+
|
397
|
+
# Gets a list of the roles assigned to a privilege
|
398
|
+
assigned_roles = client.get_roles_assigned_to_privilege(privilege.id)
|
399
|
+
|
400
|
+
# Assign roles to a privilege
|
401
|
+
result = client.assign_roles_to_privilege(privilege.id, [role_id1, role_id2])
|
402
|
+
|
403
|
+
# Remove role from a privilege
|
404
|
+
result = client.remove_role_from_privilege(privilege.id, role_id_1)
|
405
|
+
|
406
|
+
# Gets a list of the users assigned to a privilege
|
407
|
+
assigned_users = client.get_users_assigned_to_privilege(privilege.id)
|
408
|
+
|
409
|
+
# Assign users to a privilege
|
410
|
+
result = client.assign_users_to_privilege(privilege.id, [user_id1, user_id2])
|
411
|
+
|
412
|
+
# Remove user from a privilege
|
413
|
+
result = client.remove_user_from_privilege(privilege.id, user_id2)
|
344
414
|
```
|
345
415
|
|
346
416
|
## Proxy Servers
|
data/examples/events-to-csv.rb
CHANGED
@@ -24,13 +24,13 @@ OptionParser.new do |opts|
|
|
24
24
|
options[:since] = s.iso8601
|
25
25
|
end
|
26
26
|
|
27
|
-
opts.on("-lLAST", "--
|
27
|
+
opts.on("-lLAST", "--last=LAST", Integer, "Events since this many days ago") do |d|
|
28
28
|
now = Date.today
|
29
29
|
days_ago = (now - d)
|
30
30
|
options[:since] = days_ago.strftime('%Y-%m-%dT%H:%M:%SZ')
|
31
31
|
end
|
32
32
|
|
33
|
-
opts.on("-
|
33
|
+
opts.on("-bUNTIL", "--until=UNTIL", Time, "Events before this date") do |u|
|
34
34
|
options[:until] = u.iso8601
|
35
35
|
end
|
36
36
|
|
@@ -33,7 +33,7 @@ body {
|
|
33
33
|
font-weight: bold;
|
34
34
|
}
|
35
35
|
|
36
|
-
.
|
36
|
+
.form {
|
37
37
|
width: 300px;
|
38
38
|
margin: 0 auto;
|
39
39
|
text-align: center;
|
@@ -45,13 +45,13 @@ body {
|
|
45
45
|
background: linear-gradient(to right, orange , yellow, green, cyan, blue, violet); /* Standard syntax (must be last) */
|
46
46
|
}
|
47
47
|
|
48
|
-
.
|
48
|
+
.form input {
|
49
49
|
width: 90%;
|
50
50
|
padding: 5px;
|
51
51
|
margin: 5px;
|
52
52
|
}
|
53
53
|
|
54
|
-
.
|
54
|
+
.form h1 {
|
55
55
|
color: #fff;
|
56
56
|
}
|
57
57
|
|
@@ -13,6 +13,32 @@ class SessionsController < ApplicationController
|
|
13
13
|
render json: response, status: status
|
14
14
|
end
|
15
15
|
|
16
|
+
# Checks for user and gets MFA devices
|
17
|
+
# available to verify token before
|
18
|
+
# password reset is completed
|
19
|
+
def forgot_password
|
20
|
+
user = validate_user(params['username'])
|
21
|
+
|
22
|
+
devices = get_mfa_devices(user.id)
|
23
|
+
|
24
|
+
status = user ? :ok : :not_found
|
25
|
+
|
26
|
+
render json: devices, status: status
|
27
|
+
end
|
28
|
+
|
29
|
+
# Verify MFA token and then update password
|
30
|
+
def reset_password
|
31
|
+
if verify_token(params['device_id'], params['otp_token'])
|
32
|
+
status = :ok
|
33
|
+
response = set_password(session[:user_id], params['password'])
|
34
|
+
else
|
35
|
+
status = :unauthorized
|
36
|
+
response = 'Invalid token'
|
37
|
+
end
|
38
|
+
|
39
|
+
render json: response, status: status
|
40
|
+
end
|
41
|
+
|
16
42
|
def destroy
|
17
43
|
log_out
|
18
44
|
redirect_to root_url
|
@@ -57,4 +57,31 @@ module SessionsHelper
|
|
57
57
|
def current_user_id
|
58
58
|
session[:user]['id'] if current_user
|
59
59
|
end
|
60
|
+
|
61
|
+
def validate_user(username)
|
62
|
+
user = api_client.get_users(username: username).first
|
63
|
+
|
64
|
+
if user
|
65
|
+
session[:user_id] = user.id
|
66
|
+
end
|
67
|
+
|
68
|
+
user
|
69
|
+
end
|
70
|
+
|
71
|
+
def get_mfa_devices(user_id)
|
72
|
+
devices = api_client.get_enrolled_factors(user_id)
|
73
|
+
|
74
|
+
# only return devices that dont need a trigger.
|
75
|
+
# i.e. this sample does not support push yet
|
76
|
+
devices.select {|d| d.needs_trigger == true }
|
77
|
+
end
|
78
|
+
|
79
|
+
def verify_token(device_id, mfa_token)
|
80
|
+
puts "VERIFY MFA TOKEN User:#{session[:user_id]}, Device:#{device_id}, Token:#{mfa_token}"
|
81
|
+
api_client.verify_factor(session[:user_id], device_id, mfa_token)
|
82
|
+
end
|
83
|
+
|
84
|
+
def set_password(user_id, password)
|
85
|
+
api_client.set_password_using_clear_text(user_id, password, password)
|
86
|
+
end
|
60
87
|
end
|
@@ -1,37 +1,50 @@
|
|
1
|
-
<
|
2
|
-
<
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
<p>
|
8
|
-
|
9
|
-
</p>
|
10
|
-
|
11
|
-
|
12
|
-
|
1
|
+
<div class="jumbotron">
|
2
|
+
<h1>Dashboard</h1>
|
3
|
+
<p>
|
4
|
+
You must be authenticated to see this page so if you're seeing it then
|
5
|
+
everything worked as expected 🎉
|
6
|
+
</p>
|
7
|
+
<p>
|
8
|
+
<a href="/users">List Users</a> | <a href="/logout">Log Out</a>
|
9
|
+
</p>
|
10
|
+
</div>
|
11
|
+
|
12
|
+
<div class="container">
|
13
13
|
<div class="row">
|
14
|
-
<
|
14
|
+
<div class="col-sm">
|
15
|
+
<h2>Apps</h2>
|
16
|
+
<ul class="list-group">
|
17
|
+
<%@apps.each do |app|%>
|
18
|
+
<li class="list-group-item"><a href="https://<%= ONELOGIN_SUBDOMAIN %>.onelogin.com/launch/<%= app.id %>"><%= app.name %></a></li>
|
19
|
+
<%end%>
|
20
|
+
</ul>
|
21
|
+
</div>
|
22
|
+
<div class="col-sm">
|
23
|
+
<h2>Roles</h2>
|
24
|
+
<ul class="list-group">
|
25
|
+
<%@roles.each do |role|%>
|
26
|
+
<li class="list-group-item"><%= role.name %></li>
|
27
|
+
<%end%>
|
28
|
+
</ul>
|
29
|
+
|
30
|
+
<br/>
|
31
|
+
|
32
|
+
<h2>Profile</h2>
|
33
|
+
<ul class="list-group">
|
34
|
+
<%current_user.each do |k, v|%>
|
35
|
+
<li class="list-group-item">
|
36
|
+
<b><%= k%>:</b> <%= v%>
|
37
|
+
</li>
|
38
|
+
<%end%>
|
39
|
+
</ul>
|
40
|
+
</div>
|
15
41
|
</div>
|
16
|
-
|
42
|
+
</div>
|
43
|
+
|
17
44
|
|
18
|
-
<hr>
|
19
45
|
|
20
|
-
<h2>Roles</h2>
|
21
|
-
<%@roles.each do |role|%>
|
22
|
-
<div class="row">
|
23
|
-
<span><%= role.name %></span>
|
24
|
-
</div>
|
25
|
-
<%end%>
|
26
46
|
|
27
|
-
<hr>
|
28
47
|
|
29
|
-
<h2>Profile</h2>
|
30
48
|
|
31
|
-
<%current_user.each do |k, v|%>
|
32
|
-
<div class="row">
|
33
|
-
<span><%= k%>:</span> <%= v%>
|
34
|
-
</div>
|
35
|
-
<%end%>
|
36
49
|
|
37
50
|
|
@@ -1,33 +1,73 @@
|
|
1
|
-
<div class="
|
2
|
-
This is a simple demo of how to authenticate
|
3
|
-
a user and handle MFA when required
|
1
|
+
<div class="jumbotron">
|
2
|
+
<p>This is a simple demo of how to authenticate a user and handle MFA when required</p>
|
4
3
|
</div>
|
5
|
-
|
6
|
-
<div class="
|
7
|
-
<
|
8
|
-
|
9
|
-
<div>
|
10
|
-
<%= text_field_tag :username, nil, placeholder: 'Enter Username' %>
|
11
|
-
</div>
|
12
|
-
<div>
|
13
|
-
<%= password_field_tag :password, nil, placeholder: 'Enter Password' %>
|
4
|
+
|
5
|
+
<div class="container">
|
6
|
+
<div class="row">
|
7
|
+
<div class="col-sm">
|
14
8
|
</div>
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
9
|
+
<div class="col-sm">
|
10
|
+
|
11
|
+
<div class="alert alert-danger message" role="alert">
|
12
|
+
</div>
|
13
|
+
|
14
|
+
<%= form_tag("/login", method: "post", class: 'login-form') do %>
|
15
|
+
<div class="form-group">
|
16
|
+
<label for="username">Username</label>
|
17
|
+
<%= text_field_tag :username, nil, placeholder: 'Enter Username', class: 'form-control' %>
|
18
|
+
</div>
|
19
|
+
<div class="form-group">
|
20
|
+
<label for="password">Password</label>
|
21
|
+
<%= password_field_tag :password, nil, placeholder: 'Enter Password', class: 'form-control' %>
|
22
|
+
</div>
|
23
|
+
<button type="submit" class="btn btn-primary">Login</button> or <a href="#" class="forgot">Forgot Password</a>
|
24
|
+
<% end %>
|
25
|
+
|
26
|
+
<%= form_tag("/verify_mfa", method: "post", class: 'mfa-form') do %>
|
27
|
+
<div class="form-group">
|
28
|
+
<label for="device_id">MFA Device</label>
|
29
|
+
<%= select_tag :device_id, nil, {:class => 'form-control'} %>
|
30
|
+
</div>
|
31
|
+
<div class="form-group">
|
32
|
+
<label for="otp_token">Token</label>
|
33
|
+
<%= text_field_tag :otp_token, nil, placeholder: 'Enter Token', class: 'form-control' %>
|
34
|
+
</div>
|
35
|
+
<button type="submit" class="btn btn-primary">Verify Token</button>
|
36
|
+
<% end %>
|
37
|
+
|
38
|
+
<%= form_tag("/forgot_password", method: "post", class: 'forgot-password-form') do %>
|
39
|
+
<div class="form-group">
|
40
|
+
<label for="username">Username</label>
|
41
|
+
<%= text_field_tag :username, nil, placeholder: 'Enter Username', class: 'form-control' %>
|
42
|
+
</div>
|
43
|
+
<button type="submit" class="btn btn-primary">Reset Password</button> or <a href="/">Login</a>
|
44
|
+
<% end %>
|
45
|
+
|
46
|
+
<%= form_tag("/reset_password", method: "post", class: 'reset-password-form') do %>
|
47
|
+
<div class="form-group">
|
48
|
+
<label for="device_id">MFA Device</label>
|
49
|
+
<%= select_tag :device_id, nil, {:class => 'form-control'} %>
|
50
|
+
</div>
|
51
|
+
<div class="form-group">
|
52
|
+
<label for="otp_token">Token</label>
|
53
|
+
<%= text_field_tag :otp_token, nil, placeholder: 'Enter Token', class: 'form-control' %>
|
54
|
+
</div>
|
55
|
+
<div class="form-group">
|
56
|
+
<label for="password">New Password</label>
|
57
|
+
<%= password_field_tag :password, nil, placeholder: 'Enter New Password', class: 'form-control' %>
|
58
|
+
</div>
|
59
|
+
<button type="submit" class="btn btn-primary">Save Password</button>
|
60
|
+
<% end %>
|
61
|
+
|
23
62
|
</div>
|
24
|
-
<div>
|
25
|
-
<%= text_field_tag :otp_token, nil, placeholder: 'Enter token' %>
|
63
|
+
<div class="col-sm">
|
26
64
|
</div>
|
27
|
-
|
28
|
-
<% end %>
|
65
|
+
</div>
|
29
66
|
</div>
|
30
67
|
|
68
|
+
|
69
|
+
|
70
|
+
|
31
71
|
<script type="text/javascript">
|
32
72
|
|
33
73
|
var ONELOGIN_SUBDOMAIN = "<%= ONELOGIN_SUBDOMAIN %>"
|
@@ -43,11 +83,29 @@
|
|
43
83
|
xhr.send(JSON.stringify(body));
|
44
84
|
};
|
45
85
|
|
86
|
+
function showAlert(type, message){
|
87
|
+
$(".message").removeClass("alert-danger").removeClass("alert-success");
|
88
|
+
$(".message").addClass("alert-" + type).text(message).show();
|
89
|
+
$(".message").show();
|
90
|
+
}
|
91
|
+
function hideAlert(){
|
92
|
+
$(".message").hide();
|
93
|
+
}
|
94
|
+
|
46
95
|
$(function(){
|
96
|
+
hideAlert();
|
47
97
|
$(".login-form").show();
|
48
98
|
$(".mfa-form").hide();
|
99
|
+
$(".forgot-password-form").hide();
|
100
|
+
$(".reset-password-form").hide();
|
49
101
|
|
50
|
-
$(".
|
102
|
+
$(".forgot").click(function(e){
|
103
|
+
e.preventDefault();
|
104
|
+
$(".forgot-password-form").show();
|
105
|
+
$(".login-form").hide();
|
106
|
+
});
|
107
|
+
|
108
|
+
$(".login-form").on("submit", function(event){
|
51
109
|
$.ajax({
|
52
110
|
type: "POST",
|
53
111
|
url: this.action,
|
@@ -56,8 +114,10 @@
|
|
56
114
|
console.log(res);
|
57
115
|
if(res.requires_mfa){
|
58
116
|
console.log('requires mfa')
|
117
|
+
showAlert('danger', 'MFA Required')
|
118
|
+
|
59
119
|
for(var i=0; i<res.devices.length; i++){
|
60
|
-
$('select').append('<option value="' + res.devices[i].id + '">' + res.devices[i].type + '</option>');
|
120
|
+
$('.mfa-form select').append('<option value="' + res.devices[i].id + '">' + res.devices[i].type + '</option>');
|
61
121
|
}
|
62
122
|
$(".login-form").hide();
|
63
123
|
$(".mfa-form").show();
|
@@ -69,14 +129,14 @@
|
|
69
129
|
},
|
70
130
|
error: function(xhr, status, err) {
|
71
131
|
console.log(err);
|
72
|
-
|
73
|
-
$(".login-form
|
132
|
+
showAlert('danger','Login Failed');
|
133
|
+
$(".login-form input[type=submit]").removeAttr("disabled");
|
74
134
|
},
|
75
135
|
});
|
76
136
|
event.preventDefault();
|
77
137
|
});
|
78
138
|
|
79
|
-
$(".mfa-form
|
139
|
+
$(".mfa-form").on("submit", function(event){
|
80
140
|
$.ajax({
|
81
141
|
type: "POST",
|
82
142
|
url: this.action,
|
@@ -89,15 +149,58 @@
|
|
89
149
|
},
|
90
150
|
error: function(xhr, status, err) {
|
91
151
|
console.log(err);
|
92
|
-
|
152
|
+
showAlert("danger", "MFA Verification Failed");
|
93
153
|
$(".login-form").show();
|
94
154
|
$(".mfa-form").hide();
|
95
|
-
$(".login-form
|
96
|
-
$(".mfa-form
|
155
|
+
$(".login-form input[type=submit]").removeAttr("disabled");
|
156
|
+
$(".mfa-form input[type=submit]").removeAttr("disabled");
|
97
157
|
},
|
98
158
|
});
|
99
159
|
event.preventDefault();
|
100
160
|
});
|
101
|
-
})
|
102
161
|
|
162
|
+
$(".forgot-password-form").on("submit", function(event){
|
163
|
+
$.ajax({
|
164
|
+
type: "POST",
|
165
|
+
url: this.action,
|
166
|
+
data: $(this).serialize(),
|
167
|
+
success: function(res, status, xhr) {
|
168
|
+
console.log(res);
|
169
|
+
|
170
|
+
for(var i=0; i<res.length; i++){
|
171
|
+
$('.reset-password-form select').append('<option value="' + res[i].id + '">' + res[i].auth_factor_name + '</option>');
|
172
|
+
}
|
173
|
+
|
174
|
+
$(".forgot-password-form").hide();
|
175
|
+
$(".reset-password-form").show();
|
176
|
+
},
|
177
|
+
error: function(xhr, status, err) {
|
178
|
+
console.log(err);
|
179
|
+
showAlert("danger", "User not found");
|
180
|
+
},
|
181
|
+
});
|
182
|
+
event.preventDefault();
|
183
|
+
});
|
184
|
+
|
185
|
+
$(".reset-password-form").on("submit", function(event){
|
186
|
+
$.ajax({
|
187
|
+
type: "POST",
|
188
|
+
url: this.action,
|
189
|
+
data: $(this).serialize(),
|
190
|
+
success: function(res, status, xhr) {
|
191
|
+
console.log(res);
|
192
|
+
|
193
|
+
$(".login-form").show();
|
194
|
+
$(".forgot-password-form").hide();
|
195
|
+
$(".reset-password-form").hide();
|
196
|
+
showAlert("success", "Password changed");
|
197
|
+
},
|
198
|
+
error: function(xhr, status, err) {
|
199
|
+
console.log(err);
|
200
|
+
showAlert("danger", err);
|
201
|
+
},
|
202
|
+
});
|
203
|
+
event.preventDefault();
|
204
|
+
});
|
205
|
+
})
|
103
206
|
</script>
|