Update & Delete users, adds username to control requests

This commit is contained in:
Patrick McDonagh
2017-03-02 10:41:48 -06:00
parent 5e4a06ddf1
commit 082c13666b
5 changed files with 227 additions and 51 deletions

83
.idea/workspace.xml generated
View File

@@ -2,12 +2,10 @@
<project version="4">
<component name="ChangeListManager">
<list default="true" id="28cc251f-c94f-44ee-a66d-77aaab6e3483" name="Default" comment="">
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/src/main/java/com/henrypump/poc/WebServer.java" afterPath="$PROJECT_DIR$/src/main/java/com/henrypump/poc/WebServer.java" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/www/pocwww/pocwww/__init__.py" afterPath="$PROJECT_DIR$/www/pocwww/pocwww/__init__.py" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/www/pocwww/pocwww/json.py" afterPath="$PROJECT_DIR$/www/pocwww/pocwww/json.py" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/www/pocwww/pocwww/templates/layout.jinja2" afterPath="$PROJECT_DIR$/www/pocwww/pocwww/templates/layout.jinja2" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/www/pocwww/pocwww/view_helpers.py" afterPath="$PROJECT_DIR$/www/pocwww/pocwww/view_helpers.py" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/www/pocwww/pocwww/views.py" afterPath="$PROJECT_DIR$/www/pocwww/pocwww/views.py" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/www/pocwww/setup.py" afterPath="$PROJECT_DIR$/www/pocwww/setup.py" />
<change type="MODIFICATION" beforePath="$PROJECT_DIR$/www/pocwww/pocwww/templates/register.jinja2" afterPath="$PROJECT_DIR$/www/pocwww/pocwww/templates/register.jinja2" />
</list>
<ignored path="$PROJECT_DIR$/target/" />
<ignored path="$PROJECT_DIR$/.gradle/" />
@@ -176,8 +174,8 @@
<file leaf-file-name="WebServer.java" pinned="false" current-in-tab="true">
<entry file="file://$PROJECT_DIR$/src/main/java/com/henrypump/poc/WebServer.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="523">
<caret line="182" column="23" lean-forward="false" selection-start-line="182" selection-start-column="23" selection-end-line="182" selection-end-column="23" />
<state relative-caret-position="757">
<caret line="92" column="23" lean-forward="true" selection-start-line="92" selection-start-column="23" selection-end-line="92" selection-end-column="23" />
<folding>
<element signature="imports" expanded="true" />
</folding>
@@ -776,9 +774,10 @@
<treeState />
</component>
<component name="ProjectFrameBounds">
<option name="x" value="-3681" />
<option name="y" value="23" />
<option name="width" value="1680" />
<option name="height" value="1027" />
<option name="height" value="961" />
</component>
<component name="ProjectLevelVcsManager" settingsEditedManually="true" />
<component name="ProjectView">
@@ -849,6 +848,70 @@
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="poc-java" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="POC-Java" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="src" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="main" />
<option name="myItemType" value="org.jetbrains.plugins.gradle.projectView.GradleTreeStructureProvider$GradleSourceSetDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="java" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="poc" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="WebServer" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ClassTreeNode" />
</PATH_ELEMENT>
</PATH>
<PATH>
<PATH_ELEMENT>
<option name="myItemId" value="poc-java" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ProjectViewProjectNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="POC-Java" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="src" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="main" />
<option name="myItemType" value="org.jetbrains.plugins.gradle.projectView.GradleTreeStructureProvider$GradleSourceSetDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="java" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="poc" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="WebServer" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ClassTreeNode" />
</PATH_ELEMENT>
<PATH_ELEMENT>
<option name="myItemId" value="CommandHandler" />
<option name="myItemType" value="com.intellij.ide.projectView.impl.nodes.ClassTreeNode" />
</PATH_ELEMENT>
</PATH>
</subPane>
</pane>
<pane id="PackagesPane" />
@@ -1136,7 +1199,7 @@
</todo-panel>
</component>
<component name="ToolWindowManager">
<frame x="0" y="23" width="1680" height="1027" extended-state="6" />
<frame x="-3681" y="23" width="1680" height="961" extended-state="0" />
<editor active="true" />
<layout>
<window_info id="Palette" active="false" anchor="right" auto_hide="false" internal_type="DOCKED" type="DOCKED" visible="false" show_stripe_button="true" weight="0.33" sideWeight="0.5" order="4" side_tool="false" content_ui="tabs" />
@@ -1940,8 +2003,8 @@
</entry>
<entry file="file://$PROJECT_DIR$/src/main/java/com/henrypump/poc/WebServer.java">
<provider selected="true" editor-type-id="text-editor">
<state relative-caret-position="523">
<caret line="182" column="23" lean-forward="false" selection-start-line="182" selection-start-column="23" selection-end-line="182" selection-end-column="23" />
<state relative-caret-position="757">
<caret line="92" column="23" lean-forward="true" selection-start-line="92" selection-start-column="23" selection-end-line="92" selection-end-column="23" />
<folding>
<element signature="imports" expanded="true" />
</folding>

View File

@@ -49,37 +49,42 @@ public class WebServer{
public void handle(HttpExchange t) throws IOException {
JSONObject respJSON = new JSONObject();
Map<String, String> params = queryToMap(t.getRequestURI().getQuery());
String action = "";
String user = "";
for(Map.Entry<String, String> param_map : params.entrySet()){
String key = param_map.getKey();
String param = param_map.getValue();
switch (key){
case "start":
if(param.equals("true")) {
attachedPOC.thisWell.start("web");
respJSON.put("startCommand", "true");
respJSON.put("status", attachedPOC.thisWell.getRunStatusString());
} else {
respJSON.put("startCommand", "invalid value - " + param);
}
switch (key) {
case "cmd":
action = param;
break;
case "stop":
if(param.equals("true")) {
attachedPOC.thisWell.stop("web");
respJSON.put("stopCommand", "true");
respJSON.put("status", attachedPOC.thisWell.getRunStatusString());
} else {
respJSON.put("stopCommand", "invalid value - " + param);
}
case "user":
user = param;
break;
default:
respJSON.put(key, "not implemented");
}
}
if ((user.length() > 0) && (action.length() > 0)) {
switch (action) {
case "start":
attachedPOC.thisWell.start(user);
respJSON.put("startCommand", "true");
respJSON.put("status", attachedPOC.thisWell.getRunStatusString());
break;
case "stop":
attachedPOC.thisWell.stop(user);
respJSON.put("stopCommand", "true");
respJSON.put("status", attachedPOC.thisWell.getRunStatusString());
break;
default:
respJSON.put(action, "not implemented");
break;
}
} else {
respJSON.put("bad request", "cmd and user parameters required");
}
String response = respJSON.toJSONString();
t.sendResponseHeaders(200, response.getBytes().length);

View File

@@ -175,9 +175,8 @@ def main(global_config, **settings):
config.add_route("json_cmd_stop", "/json/cmd/stop", factory='pocwww.security.UserLoginFactory')
config.add_route("json_cmd_shake", "/json/cmd/shake", factory='pocwww.security.UserLoginFactory')
config.add_route("json_update_poc_address", "/json/updatepocaddress", factory='pocwww.security.UserLoginFactory')
config.add_route("json_newuser", "/json/newuser", factory='pocwww.security.UserLoginFactory')
config.add_route("json_getusers", "/json/users", factory='pocwww.security.UserLoginFactory')
config.add_route("json_users", "/json/users", factory='pocwww.security.UserLoginFactory')
config.scan()
return config.make_wsgi_app()

View File

@@ -133,7 +133,7 @@ def json_updateconfig(request):
jsb = request.json_body
new_config = {}
new_config['timestamp'] = datetime.utcnow()
new_config['storedBy'] = "web"
new_config['storedBy'] = request.authenticated_userid
new_config['wellName'] = jsb['wellName']
new_config['tapers'] = []
for p in conv_to_float:
@@ -163,7 +163,7 @@ def json_updateconfig(request):
@view_config(route_name="json_cmd_start", renderer="prettyjson", permission="control")
def json_start(request):
address = get_poc_address(request) or 'localhost'
start_url = "http://{}:8000/command?start=true".format(address)
start_url = "http://{}:8000/command?cmd=start&user={}".format(address, request.authenticated_userid)
r = requests.get(start_url)
return r.text if r.status_code == 200 else {"status": "failure sending command"}
@@ -171,7 +171,7 @@ def json_start(request):
@view_config(route_name="json_cmd_stop", renderer="prettyjson", permission="control")
def json_stop(request):
address = get_poc_address(request) or 'localhost'
stop_url = "http://{}:8000/command?stop=true".format(address)
stop_url = "http://{}:8000/command?cmd=stop&user={}".format(address, request.authenticated_userid)
r = requests.get(stop_url)
return r.text if r.status_code == 200 else {"status": "failure sending command"}
@@ -194,7 +194,7 @@ def json_update_poc_address(request):
return {"status": "failure"}
@view_config(route_name="json_newuser", renderer="prettyjson", request_method='POST', permission="edit")
@view_config(route_name="json_users", renderer="prettyjson", request_method='POST', permission="edit")
def json_newuser(request):
jsb = request.json_body
if request.db['users'].count({"username": jsb['username']}) > 0:
@@ -214,10 +214,35 @@ def json_newuser(request):
return {'status': "OK"}
@view_config(route_name="json_getusers", renderer="prettyjson", permission="edit")
@view_config(route_name="json_users", renderer="prettyjson", permission="edit", request_method='GET')
def json_getuser(request):
user_list = []
users = list(request.db['users'].find())
for user in users:
user_list.append(user['username'])
return {'users': user_list}
@view_config(route_name="json_users", renderer="prettyjson", permission="edit", request_method='DELETE')
def json_deleteuser(request):
request.db['users'].remove({'username': request.json_body['username']})
user_list = []
users = list(request.db['users'].find())
for user in users:
user_list.append(user['username'])
return {'users': user_list}
@view_config(route_name="json_users", renderer="prettyjson", request_method='PUT', permission="edit")
def json_newuser(request):
jsb = request.json_body
if len(jsb['username']) < 5:
fail_reason = "The username must be at least 5 characters"
return {"status": 'fail', "info": fail_reason}
elif len(jsb['password']) < 5:
fail_reason = "The password must be at least 5 characters"
return {"status": 'fail', "info": fail_reason}
else:
set_return = set_password(request, jsb['username'], jsb['password'])
return {'status': "OK"}

View File

@@ -15,23 +15,49 @@
<input type="password" name="password" class="form-control" id="password" placeholder="Password">
</div>
<div class="form-group">
<button id="submit" class="btn btn-default">Create User</button>
<button id="submitNewUser" class="btn btn-primary">Create User</button>
</div>
</form>
<hr />
<div class="alert alert-success alert-dismissable hidden" id="update-success">
<br />
<div class="alert alert-success alert-dismissable hidden" id="add-user-success">
<span>
<p>User successfully added!</p>
</span>
</div>
<div class="alert alert-danger alert-dismissable hidden" id="update-failed">
<div class="alert alert-danger alert-dismissable hidden" id="add-user-failed">
<span>
<p><span id="error-message"></span></p>
</span>
</div>
<hr />
<h2>Change Password</h2>
<form class="form-inline">
<div class="form-group">
<label for="newPassword">New Password</label>
<input type="password" name="newPassword" class="form-control" id="newPassword" placeholder="Password">
</div>
<div class="form-group">
<button id="submitNewPassword" class="btn btn-primary">Update Password</button>
</div>
</form>
<br />
<div class="alert alert-success alert-dismissable hidden" id="update-password-success">
<span>
<p>Password successfully updated!</p>
</span>
</div>
<div class="alert alert-danger alert-dismissable hidden" id="update-password-failed">
<span>
<p><span id="error-message"></span></p>
</span>
</div>
<hr />
<h2>All Users</h2>
<div class="table-reponsive">
<table class="table">
@@ -50,9 +76,20 @@
function addedUser(data){
if (data.status == "OK"){
$('#update-success').removeClass('hidden');
$('#add-user-success').removeClass('hidden');
} else {
$('#update-failed').removeClass('hidden');
$('#add-user-failed').removeClass('hidden');
$('#error-message').text(data.info);
}
getAllUsers();
};
function updatedUserPassword(data){
if (data.status == "OK"){
$('#update-password-success').removeClass('hidden');
} else {
$('#update-password-failed').removeClass('hidden');
$('#error-message').text(data.info);
}
@@ -69,25 +106,57 @@
dataType: 'json',
data: JSON.stringify(newUser),
contentType: "application/json; charset=utf-8",
url: "/json/newuser",
url: "/json/users",
success: addedUser
});
};
$("#submit").click(function(event){
function sendUpdateUser(){
var newUser = {
username: '{{request.authenticated_userid}}',
password: $("#newPassword").val()
};
$.ajax({
type: "PUT",
dataType: 'json',
data: JSON.stringify(newUser),
contentType: "application/json; charset=utf-8",
url: "/json/users",
success: updatedUserPassword
});
};
$("#submitNewUser").click(function(event){
event.preventDefault();
$('#update-success').addClass('hidden');
$('#update-failed').addClass('hidden');
$('#add-user-success').addClass('hidden');
$('#add-user-failed').addClass('hidden');
sendNewUser();
});
$("#submitNewPassword").click(function(event){
event.preventDefault();
$('#update-password-success').addClass('hidden');
$('#update-password-failed').addClass('hidden');
sendUpdateUser();
});
function showAllUsers(data){
$('tbody').empty();
for(var i = 0; i < data.users.length; i++){
$('tbody').append("<tr><td>" + data.users[i] + '</td><td><button class="btn btn-danger">Delete</button></td></tr>');
if (data.users[i] == "admin"){
$('tbody').append("<tr><td>" + data.users[i] + '</td><td><button type="button" class="btn btn-disabled" title="What are you doing?" data-container="body" data-toggle="popover" data-trigger="focus" data-placement="right" data-content="You cannot delete the admin user">Delete</button></td></tr>');
} else if (data.users[i] == '{{request.authenticated_userid}}'){
$('tbody').append("<tr><td>" + data.users[i] + '</td><td><button type="button" class="btn btn-disabled" title="What are you doing?" data-container="body" data-toggle="popover" data-trigger="focus" data-placement="right" data-content="You cannot delete yourself. It doesn\'t work like that... ">Delete</button></td></tr>');
} else {
$('tbody').append("<tr><td>" + data.users[i] + '</td><td><button class="btn btn-danger" onclick="deleteUser(\'' + data.users[i] + '\')">Delete</button></td></tr>');
}
$(function () {
$('[data-toggle="popover"]').popover({html: true})
})
}
}
'<button type="button" class="btn btn-default" title="What are you doing?" data-container="body" data-toggle="popover" data-trigger="focus" data-placement="right" data-content="You cannot delete the admin user">Delete</button>'
function getAllUsers(){
$.ajax({
@@ -98,6 +167,21 @@
}
getAllUsers();
function deleteUser(username){
$.ajax({
type:'DELETE',
dataType: 'json',
data: JSON.stringify({"username": username}),
contentType: "application/json; charset=utf-8",
url: "/json/users",
success: getAllUsers
})
}
$(function () {
$('[data-toggle="popover"]').popover({html: true})
})
</script>
{% endif %}
{% endblock content %}