Commit 94cb2770 authored by Leigh Stoller's avatar Leigh Stoller

Add new ssh key management page.

parent 1dae1a8a
require(window.APT_OPTIONS.configObject,
['underscore', 'js/quickvm_sup',
'js/lib/text!template/ssh-keys.html',
'js/lib/text!template/oops-modal.html',
'js/lib/text!template/waitwait-modal.html',
'filestyle',
],
function (_, sup, sshkeysString, oopsString, waitwaitString)
{
'use strict';
var embedded = 0;
var sshkeysTemplate = _.template(sshkeysString);
function initialize()
{
window.APT_OPTIONS.initialize(sup);
embedded = window.EMBEDDED;
var pubkeys = JSON.parse(_.unescape($('#sshkey-list')[0].textContent));
var html = sshkeysTemplate({
pubkeys: pubkeys,
});
$('#page-body').html(html);
$('#oops_div').html(oopsString);
$('#waitwait_div').html(waitwaitString);
//
// Fix for filestyle problem; not a real class I guess, it
// runs at page load, and so the filestyle'd button in the
// form is not as it should be.
//
$('#sshkey_file').each(function() {
$(this).filestyle({input : false,
buttonText : $(this).attr('data-buttonText'),
classButton: $(this).attr('data-classButton')});
});
//
// File upload handler.
//
$('#sshkey_file').change(function() {
var reader = new FileReader();
reader.onload = function(event) {
$('#sshkey_data').val(event.target.result);
};
reader.readAsText(this.files[0]);
});
// Handler for all of the delete buttons.
$('.delete_pubkey_button').click(function (event) {
event.preventDefault();
var index = $(this)[0].dataset['key'];
HandleDeleteKey(index);
});
// Add key button.
$('#ssh_addkey_button').click(function (event) {
event.preventDefault();
HandleAddKey();
});
}
/*
* Submit key, look for error.
*/
function HandleAddKey()
{
var keydata = $('#sshkey_data').val();
if (keydata == "") {
alert("Key cannot be blank!");
return;
}
var callback = function(json) {
console.info(json);
sup.HideModal("#waitwait-modal");
if (json.code) {
sup.SpitOops("oops", json.value);
return;
}
if (embedded) {
window.parent.location.replace("../ssh-keys.php");
}
else {
window.location.replace("ssh-keys.php");
}
}
sup.ShowModal("#waitwait-modal");
var xmlthing = sup.CallServerMethod(null, "ssh-keys", "addkey",
{"keydata" : keydata});
xmlthing.done(callback);
}
function HandleDeleteKey(index)
{
var callback = function(json) {
console.info(json);
sup.HideModal("#waitwait-modal");
if (json.code) {
sup.SpitOops("oops", json.value);
return;
}
$('#panel_' + index).remove();
}
sup.ShowModal("#waitwait-modal");
var xmlthing = sup.CallServerMethod(null, "ssh-keys", "deletekey",
{"index" : index});
xmlthing.done(callback);
}
$(document).ready(initialize);
});
<?php
#
# Copyright (c) 2000-2014 University of Utah and the Flux Group.
# Copyright (c) 2000-2015 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
......@@ -110,6 +110,13 @@ $routing = array("myprofiles" =>
"Do_ApproveDataset",
"extend" =>
"Do_ExtendDataset")),
"ssh-keys" =>
array("file" => "ssh-keys.ajax",
"guest" => false,
"methods" => array("addkey" =>
"Do_AddKey",
"deletekey" =>
"Do_DeleteKey")),
);
#
......
<?php
#
# Copyright (c) 2000-2015 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
# This file is part of the Emulab network testbed software.
#
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
#
# This file is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
# License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this file. If not, see <http://www.gnu.org/licenses/>.
#
# }}}
#
chdir("..");
chdir("apt");
#
# When there's a PubKeys class, this will be a Class function to edit them...
#
function AddKeyAux($uid, $keydata, &$error)
{
global $suexec_output, $suexec_output_array;
#
# Generate a temporary file and write in the XML goo.
#
$filename = tempnam("/tmp", "addpubkey");
if (! $filename) {
TBERROR("Could not create temporary filename", 0);
$error = "Transient error(1); please try again later.";
return false;
}
if (! ($fp = fopen($filename, "w"))) {
TBERROR("Could not open temp file $xmlname", 0);
$error = "Transient error(2); please try again later.";
return false;
}
fwrite($fp, $keydata);
fclose($fp);
chmod($filename, 0666);
# Invoke the back-end script as the user if an admin for permissions.
$retval = SUEXEC($uid, "nobody", "webaddpubkey -f -u $uid $filename",
SUEXEC_ACTION_IGNORE);
unlink($filename);
if ($retval) {
if ($retval < 0) {
$error = "Transient error(3, $retval); please try again later.";
SUEXECERROR(SUEXEC_ACTION_CONTINUE);
}
else {
$error = "Key could not be parsed";
}
return false;
}
return true;
}
#
# Add and Delete SSH keys
#
function Do_AddKey()
{
global $this_user;
global $ajax_args;
$error = "";
$this_idx = $this_user->uid_idx();
$this_uid = $this_user->uid();
$embedded = isset($ajax_args["embedded"]) && $ajax_args["embedded"];
if (!isset($ajax_args["keydata"])) {
SPITAJAX_ERROR(1, "Missing key data");
return;
}
if (!AddKeyAux($this_uid, $ajax_args["keydata"], $error)) {
SPITAJAX_ERROR(1, $error);
return;
}
SPITAJAX_RESPONSE(0);
return;
}
function Do_DeleteKey()
{
global $this_user;
global $ajax_args;
$this_idx = $this_user->uid_idx();
$this_uid = $this_user->uid();
$embedded = isset($ajax_args["embedded"]) && $ajax_args["embedded"];
if (!isset($ajax_args["index"])) {
SPITAJAX_ERROR(1, "Missing key index");
return;
}
$index = $ajax_args["index"];
if (!preg_match('/^\d*$/', $index)) {
SPITAJAX_ERROR(1, "Invalid key index");
return;
}
DBQueryFatal("delete from user_pubkeys ".
"where uid_idx='$this_idx' and idx='$index' and internal=0");
if (SUEXEC($this_uid, "nobody",
"webaddpubkey -w $this_uid", SUEXEC_ACTION_CONTINUE)) {
SPITAJAX_ERROR(-1, "Internal error regenerating keys file");
return;
}
SPITAJAX_RESPONSE(0);
return;
}
# Local Variables:
# mode:php
# End:
?>
<?php
#
# Copyright (c) 2000-2015 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
# This file is part of the Emulab network testbed software.
#
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
#
# This file is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
# License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this file. If not, see <http://www.gnu.org/licenses/>.
#
# }}}
#
chdir("..");
include("defs.php3");
chdir("apt");
include("quickvm_sup.php");
$page_title = "My SSH Keys";
#
# Get current user.
#
RedirectSecure();
$this_user = CheckLoginOrRedirect();
$this_idx = $this_user->idx();
SPITHEADER(1);
$query_result =
DBQueryFatal("select idx,comment,pubkey from user_pubkeys ".
"where uid_idx='$this_idx' and internal=0");
$pubkeys = array();
while ($row = mysql_fetch_array($query_result)) {
$pubkeys[] = array("index" => $row["idx"],
"pubkey" => $row["pubkey"],
"comment" => $row["comment"]);
}
echo "<script type='text/plain' id='sshkey-list'>\n";
echo htmlentities(json_encode($pubkeys));
echo "</script>\n";
# Place to hang the toplevel template.
echo "<div id='page-body'></div>\n";
echo "<script type='text/javascript'>\n";
echo " window.AJAXURL = 'server-ajax.php';\n";
echo "</script>\n";
echo "<script src='js/lib/jquery-2.0.3.min.js'></script>\n";
echo "<script src='js/lib/bootstrap.js'></script>\n";
echo "<script src='js/lib/require.js' data-main='js/ssh-keys'></script>\n";
SPITFOOTER();
?>
<div class='row'>
<div class='col-lg-12 col-lg-offset-0
col-md-12 col-md-offset-0
col-sm-12 col-sm-offset-0
col-xs-12 col-xs-offset-0'>
<div class='row'>
<div class='col-lg-10 col-lg-offset-1
col-md-10 col-md-offset-1
col-sm-12 col-sm-offset-0
col-xs-12 col-xs-offset-0'>
<!-- Collapsable panel -->
<% _.each(pubkeys, function(pubkey) {
var key_href = 'key_' + pubkey.index;
var key_title = pubkey.comment;
var delete_id = "delete_key_" + pubkey.index;
var panel_id = "panel_" + pubkey.index;
%>
<div class="panel panel-info" id='<%- panel_id %>'>
<div class="panel-heading clearfix">
<div class='button-group pull-right'>
<a class='btn btn-danger btn-sm delete_pubkey_button'
type='button'
data-key='<%- pubkey.index %>'>Delete</a>
</div>
<div style='padding-top: 7.5px;'>
<a data-toggle="collapse"
href='#<%- key_href %>'>
<span class="glyphicon glyphicon-chevron-right pull-left"
style='padding-right: 10px;'></span></a>
<h4 class='panel-title'><%- key_title %></h4>
</div>
</div>
<div id='<%- key_href %>' class="panel-collapse collapse">
<div class="panel-body">
<span style='word-wrap:break-word;'><%- pubkey.pubkey %></span>
</div>
</div>
</div>
<% }); %>
</div>
</div>
<div class='row'>
<div class='col-lg-10 col-lg-offset-1
col-md-10 col-md-offset-1
col-sm-12 col-sm-offset-0
col-xs-12 col-xs-offset-0'>
<div class="panel panel-info">
<div class="panel-heading">
<h4 class='panel-title'>Add Key</h4>
</div>
<div>
<div class="panel-body">
<form id='add_sshkey_form'
class='form-horizontal' role='form'>
<div class="form-group">
<label for="sshkey_data"
class="col-sm-2 control-label">Key</label>
<div class="col-sm-10">
<textarea name="sshkey_data" id='sshkey_data'
value=""
rows=5
class="form-control"
placeholder='public key'
type="textarea"></textarea>
</div>
</div>
<div class="form-group">
<div class='col-sm-offset-2 col-sm-10'>
<input class='filestyle' type='file'
name='sshkey_file' id='sshkey_file'
data-classButton='btn btn-primary btn-sm'
data-input='false'
data-buttonText='Load from file'>
</div>
</div>
<div class="form-group">
<div class="col-sm-offset-2 col-sm-10">
<button type="submit" id='ssh_addkey_button'
class="btn btn-primary btn-sm">Add Key</button>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div id='waitwait_div'></div>
<div id='oops_div'></div>
<?php
#
# Copyright (c) 2000-2015 University of Utah and the Flux Group.
#
# {{{EMULAB-LICENSE
#
# This file is part of the Emulab network testbed software.
#
# This file is free software: you can redistribute it and/or modify it
# under the terms of the GNU Affero General Public License as published by
# the Free Software Foundation, either version 3 of the License, or (at
# your option) any later version.
#
# This file is distributed in the hope that it will be useful, but WITHOUT
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU Affero General Public
# License for more details.
#
# You should have received a copy of the GNU Affero General Public License
# along with this file. If not, see <http://www.gnu.org/licenses/>.
#
# }}}
#
include("defs.php3");
#
# Only known and logged in users can do this.
#
$this_user = CheckLoginOrDie();
$uid = $this_user->uid();
$uid_idx = $this_user->uid_idx();
$isadmin = ISADMIN();
#
# Standard Testbed Header
#
PAGEHEADER("SSH Keys");
echo "<br>\n";
echo "<iframe src='apt/ssh-keys.php?embedded=1'
id='embedded' class='embedded'></iframe>";
$bodyclosestring =
"<script type='text/javascript'>ShowEmbedded('embedded')</script>\n";
#
# Standard Testbed Footer
#
PAGEFOOTER();
?>
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment