Skip to content

Commit

Permalink
F OpenNebula#2497: two factor authentication
Browse files Browse the repository at this point in the history
Signed-off-by: Jorge Lobo <jlobo@opennebula.systems>
  • Loading branch information
Jorge Lobo committed Jul 1, 2019
1 parent e9c5290 commit a59c9cb
Show file tree
Hide file tree
Showing 9 changed files with 151 additions and 64 deletions.
3 changes: 1 addition & 2 deletions src/sunstone/etc/sunstone-server.conf
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,7 @@
:core_auth: cipher

# Two Factor Authentication Issuer Label
# JORGE
:two_factor_auth_issuer: Sunstone
:two_factor_auth_issuer: opennebula

################################################################################
# Check Upgrades
Expand Down
2 changes: 1 addition & 1 deletion src/sunstone/models/OpenNebulaJSON/UserJSON.rb
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ def disable_two_factor_auth(params=Hash.new)
sunstone_setting = params["current_sunstone_setting"]
sunstone_setting.delete("TWO_FACTOR_AUTH_SECRET")
sunstone_setting = { "sunstone" => sunstone_setting }
template_raw = template_to_str_sunstone_with_explicite_empty_value(sunstone_setting)
template_raw = template_to_str_sunstone_with_explicite_empty_value(sunstone_setting)
update_params = { "template_raw" => template_raw, "append" => true }
update(update_params)
end
Expand Down
2 changes: 1 addition & 1 deletion src/sunstone/public/app/login.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ define(function(require) {
var OpenNebulaAuth = require('opennebula/auth');

function auth_success(req, response) {
if (response.code === "two_factor_auth") {
if (response && response.code && response.code === "two_factor_auth") {
$("#login_form").fadeOut("slow");
$("#login_spinner").hide();
$("#two_factor_auth").fadeIn("slow");
Expand Down
73 changes: 73 additions & 0 deletions src/sunstone/public/scss/_login.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
body#login{

#wrapper{
margin-left: auto;
margin-right: auto;
width: 900px;
text-align: center;

div#logo_sunstone {
height: 200px;
width: 100%;
display: inline-block;
}

div#login {
background-color: #F5F5F5;
border-radius: 1rem;
padding: 2rem;
-webkit-box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.75);
-moz-box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.75);
box-shadow: 0px 0px 10px 0px rgba(0,0,0,0.75);

.buttons{
display: inline-flex;
width: 100%;
margin: 0;
align-items: center;
margin-top: 1rem;

button{
-webkit-box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.75);
-moz-box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.75);
box-shadow: 0px 0px 5px 0px rgba(0,0,0,0.75);
padding: .5rem 1rem;
border: 1px solid rgba(0, 0, 0, 0.2);
background-color: #F6F6F6;

&:after{
content: "Login";
font-weight: bold;
}
}
}

.box {
background: #FFFFFF;
border-radius: 0.5rem;
border: 1px solid grey;
}
}

#login_spinner {
display: inline-block;
padding-right: 10px;
}
}

#footer {
padding: 9px 10px 10px 10px;
text-align: center;
width: 100%;
position: fixed;
margin: 0px;
bottom: 0;

a {
color: #2ba6cb;
text-decoration: none;
line-height: inherit;
font-size: 13px;
}
}
}
1 change: 1 addition & 0 deletions src/sunstone/public/scss/app.scss
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
@import './tooltips';
@import './visjs';
@import './flot';
@import './login';



Expand Down
46 changes: 23 additions & 23 deletions src/sunstone/sunstone-server.rb
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,7 @@
require 'SunstoneServer'
require 'SunstoneViews'


##############################################################################
# Configuration
##############################################################################
Expand Down Expand Up @@ -310,7 +311,7 @@ def build_session
end

client = $cloud_auth.client(result)
user_id = OpenNebula::User::SELF
user_id = OpenNebula::User::SELF

user = OpenNebula::User.new_with_id(user_id, client)
rc = user.info
Expand All @@ -321,32 +322,12 @@ def build_session

# If active zone endpoint is not defined, pull it
# from user template if exists
unless user[DEFAULT_ZONE_ENDPOINT_XPATH].nil? or user[DEFAULT_ZONE_ENDPOINT_XPATH].empty?
unless user[DEFAULT_ZONE_ENDPOINT_XPATH].nil? or user[DEFAULT_ZONE_ENDPOINT_XPATH].empty?
session[:active_zone_endpoint] ||=
user[DEFAULT_ZONE_ENDPOINT_XPATH]
end
client_active_endpoint = $cloud_auth.client(result, session[:active_zone_endpoint])

# two factor_auth
two_factor_auth =
if user[TWO_FACTOR_AUTH_SECRET_XPATH]
user[TWO_FACTOR_AUTH_SECRET_XPATH] != ""
else
DEFAULT_TWO_FACTOR_AUTH
end

if two_factor_auth
two_factor_auth_token = params[:two_factor_auth_token]
if !two_factor_auth_token || two_factor_auth_token == ""
return [202, { code: "two_factor_auth" }.to_json]
else
unless TwoFactorAuth.authenticate(user[TWO_FACTOR_AUTH_SECRET_XPATH], two_factor_auth_token)
logger.info { "Unauthorized two factor authentication login attempt" }
return [401, ""]
end
end
end

session[:user] = user['NAME']
session[:user_id] = user['ID']
session[:user_gid] = user['GID']
Expand Down Expand Up @@ -429,6 +410,26 @@ def build_session
session[:federation_mode] = active_zone_configuration['FEDERATION/MODE'].upcase
session[:mode] = $conf[:mode]

# two factor_auth
two_factor_auth =
if user[TWO_FACTOR_AUTH_SECRET_XPATH]
user[TWO_FACTOR_AUTH_SECRET_XPATH] != ""
else
DEFAULT_TWO_FACTOR_AUTH
end
binding.pry
if two_factor_auth
two_factor_auth_token = params[:two_factor_auth_token]
if !two_factor_auth_token || two_factor_auth_token == ""
return [202, { code: "two_factor_auth" }.to_json]
else
unless TwoFactorAuth.authenticate(user[TWO_FACTOR_AUTH_SECRET_XPATH], two_factor_auth_token)
logger.info { "Unauthorized two factor authentication login attempt" }
return [401, ""]
end
end
end

[204, ""]
end

Expand Down Expand Up @@ -569,7 +570,6 @@ def destroy_session

get '/two_factor_auth_hotp_qr_code' do
content_type 'image/svg+xml'

totp = MyTotp.build(params[:secret], $conf[:two_factor_auth_issuer])
totp_uri = totp.provisioning_uri(session[:user])
qr_code = MyQrCode.build(totp_uri)
Expand Down
27 changes: 17 additions & 10 deletions src/sunstone/views/_login_standard.erb
Original file line number Diff line number Diff line change
@@ -1,17 +1,24 @@
<form id="login_form" method="post">
<div class="border" id="login">
<div class="content">
Username
<input type="text" size="15" name="username" id="username" class="box"/>
Password
<input type="password" size="15" name="password" id="password" class="box"/>
<br />
<div class="border columns small-6 small-centered small-offset-3 text-center" id="login">
<div class="content">
<label class="text-left">
Username
<input type="text" size="15" name="username" id="username" class="box"/>
</label>
<label class="text-left">
Password
<input type="password" size="15" name="password" id="password" class="box"/>
</label>
<div class="row buttons small-collapse">
<div class="columns small-6 text-left">
<% if $conf[:keep_me_logged] %>
<input type="checkbox" id="check_remember" />
<label id="label_remember" for="check_remember">Keep me logged in</label>
<% end %>
<input type="submit" id="login_btn" value="" />
</div>
<div class="columns small-6 text-right">
<img src="images/ajax-loader.gif" alt="retrieving" id="login_spinner" />
<button type="submit" id="login_btn"></button>
</div>
</div>
</div>
</form>
</div>
13 changes: 8 additions & 5 deletions src/sunstone/views/_login_x509.erb
Original file line number Diff line number Diff line change
@@ -1,11 +1,14 @@
<form id="login_form" method="post">
<div class="border" id="login" style='height:169px;background:url("../images/panel_short.png") no-repeat scroll center transparent'>
<div class="content">
<input style="float:left;" type="submit" id="login_btn" value="" />
<div class="border columns small-6 small-centered small-offset-3 text-center" id="login" style='height:169px;background:url("../images/panel_short.png") no-repeat scroll center transparent'>
<div class="content">
<div class="row buttons small-collapse">
<div class="columns small-6 text-left">
<% if $conf[:keep_me_logged] %>
<input type="checkbox" id="check_remember" />
<label id="label_remember" for="check_remember">Keep me logged in</label>
<% end %>
</div>
<div class="columns small-6 text-right">
<button type="submit" id="login_btn"></button>
</div>
</div>
</form>
</div>
48 changes: 26 additions & 22 deletions src/sunstone/views/login.erb
Original file line number Diff line number Diff line change
Expand Up @@ -3,43 +3,47 @@
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />

<title>OpenNebula Sunstone Login</title>

<!--[if IE]><link rel="shortcut icon" href="images/favicon.ico"><![endif]-->
<link rel="apple-touch-icon-precomposed" href="images/apple-touch-icon-precomposed.png">
<link rel="icon" href="images/favicon.png">

<link rel="stylesheet" type="text/css" href="css/login.css" />

<link rel="stylesheet" type="text/css" href="css/app.css" />
<% if $conf[:env] == 'dev' %>
<script src="bower_components/requirejs/require.js" data-main="app/login"></script>
<% else %>
<script src="dist/login.js"></script>
<% end %>
</head>

<body>

<body id="login">
<div id="wrapper">
<div id="logo_sunstone" style="
background: url(<%=$views_config.logo%>) no-repeat center;
background-size: 355px;">
<div class="row">
<div class="columns small-6 small-centered small-offset-3 text-center">
<div id="logo_sunstone" style="
background: url(<%=$views_config.logo%>) no-repeat center;
background-size: 100%;"></div>
</div>
</div>

<% if (settings.config[:auth] == "x509") || (settings.config[:auth] == "remote") %>
<%= erb :_login_x509 %>
<% else %>
<%= erb :_login_standard %>
<% end %>

<form id="login_form" method="post" class="row">
<% if (settings.config[:auth] == "x509") || (settings.config[:auth] == "remote") %>
<%= erb :_login_x509 %>
<% else %>
<%= erb :_login_standard %>
<% end %>
</form>
<div id="two_factor_auth" class="border" style="display: none;">
<div class="border" id="login">
<div class="border columns small-6 small-centered small-offset-3 text-center" id="login">
<div class="content">
Two Factor Token
<input value="" type="text" size="15" name="two_factor_auth_token" id="two_factor_auth_token" class="box"/>
<button id="two_factor_auth_login" type="button"></button>
</div>
<label class="text-left">
Two Factor Token
<input value="" type="text" size="15" name="two_factor_auth_token" id="two_factor_auth_token" class="box"/>
</label>
<div class="row buttons small-collapse">
<div class="columns small-offset-6 small-6 text-right">
<button id="two_factor_auth_login" type="button"></button>
</div>
</div>
</div>
</div>
</div>
<div id="error_box" class="hidden alert-box alert" style="display: none">
Expand Down

0 comments on commit a59c9cb

Please sign in to comment.