Commit cfbbe603 authored by Sven Franck's avatar Sven Franck

custom handler: add/remove SSL, update server configuration/scope

parent 652ffa20
{
"portal_type_source": "Computer",
"portal_type_title": "computer",
"portal_type_fields": "computer_fieldlist",
"portal_type_mapper": "servers",
"initial_query": {"include_docs": true, "limit":[0,1]},
"form": true,
"view": "web_view",
"property_dict": {
"initial_query_url_identifier": "_id",
"dynamic_children": [0],
"requires_authentication": true,
"depends_on": "login_state"
},
"scheme": [
{
"position": "left",
"fieldlist": [
{"field": "title", "overrides": {"properties": {"editable": false, "required": false}}},
{"field": "reference", "overrides": {"properties": {"editable": false, "required": false}}}
]
},{
"position": "center",
"fieldlist": [
{"type": "textarea", "direct": {"name": "certificate", "id": "certificate", "className": ""}, "attributes": {"data-enhanced":"true"}, "logic": {"setFlux": "certificate", "label":"computer.crt", "label_i18n":"portal_type_dict.computer_dict.text_dict.crt", "skip":false}},
{"type": "textarea", "direct": {"name": "key", "id": "key", "className": ""}, "attributes": {"data-enhanced":"true"}, "logic": {"setFlux": "key", "label":"computer.key", "label_i18n":"portal_type_dict.computer_dict.text_dict.key", "skip":false}}
]
}
],
"children": [{
"generate": "widget",
"type": "form",
"class_list": "responsive",
"property_dict": {
"editable": true,
"secure": "default",
"secret_hash": "foo",
"public_key": "6Ldpb-oSAAAAAGwriKpk4ol1n4yjN_as6M4xv0zA"
},
"children": []
}
]
}
...@@ -163,6 +163,96 @@ ...@@ -163,6 +163,96 @@
} }
} }
}, },
"subject_list": {
"type":"TextareaField",
"widget": {
"id": "subject_list",
"title": "Friends (Email)",
"title_i18n": "portal_type_dict.computer_dict.field_dict.subjects.title",
"description": "Email adresses that should be authenticated to foo this server.",
"description_i18n": "portal_type_dict.computer_dict.field_dict.subjects.description",
"alternate_name": "subject_list",
"css_class": null,
"hidden": null,
"width":null,
"height":null,
"extra":null
},
"properties": {
"enabled": true,
"editable": true,
"external_validator": null,
"required": null,
"preserve_whitespace": null,
"unicode": null,
"maximum_lines": null,
"maximum_length_of_line": null,
"maximum_characters": null
},
"message": {
"external_validator_failed": {
"message": "The input failed the external validator.",
"i18n": "validation_dict.external"
},
"required_not_found": {
"message": "Input required but not found.",
"i18n": "validation_dict.required"
},
"too_many_lines": {
"message": "You have entered too many lines.",
"i18n": "validation_dict.too_many_lines"
},
"line_too_long": {
"message": "One or more lines you have entered are too long.",
"i18n": "validation_dict.too_long_lines"
},
"too_long": {
"message": "You have entered too many characters.",
"i18n": "validation_dict.too_many_chars"
}
}
},
"allocation_scope": {
"type": "ListField",
"widget": {
"id": "allocation_scope",
"title": "Allocation Scope",
"title_i18n": "portal_type_dict.computer_dict.field_dict.scope.title",
"description": "To scope to set for this computer.",
"description_i18n": "portal_type_dict.computer_dict.field_dict.scope.description",
"alternate_name": "allocation_scope",
"default_value": null,
"css_class": null,
"hidden": false,
"size": 1,
"items": "getAllocationScope",
"select_first_item": true,
"extra_per_item": null,
"extra": null
},
"properties": {
"enabled": true,
"editable": true,
"external_validator": null,
"required": null,
"preserve_whitespace": null,
"unicode": null
},
"messages": {
"external_validator_failed": {
"message": "The input failed the external validator.",
"i18n": "validation_dict.external"
},
"required_not_found": {
"message": "Input is required but no input given.",
"i18n": "validation_dict.required"
},
"unknown_selection": {
"message":"You selected on option not on the menu",
"i18n": "validation_dict.option_not_available"
}
}
},
"region": { "region": {
"type": "ListField", "type": "ListField",
"widget": { "widget": {
......
{
"portal_type_source": "Computer",
"portal_type_title": "computer",
"portal_type_fields": "computer_fieldlist",
"portal_type_mapper": "servers",
"initial_query": {"include_docs": true, "limit":[0,1]},
"form": true,
"view": "web_view",
"property_dict": {
"initial_query_url_identifier": "_id",
"dynamic_children": [1],
"requires_authentication": true,
"depends_on": "login_state",
"wrap_gadget": 2,
"submit_to": "#servers/__id__/ssl"
},
"scheme": [],
"children": [{
"type": "p",
"direct": {"className": "translate"},
"attributes": {"data-i18n": "portal_type_dict.computer_dict.text_dict.ssl_request_info"},
"logic": {"text": "Here you can request a new SSL certificate for computer.\nAfter presenting it please copy key and certificate and store in secure place.\nIn case of certificate compromise or lost please request it again.\nCertificate is not stored on Vifib.net servers"}
},{
"generate": "widget",
"type": "form",
"class_list": "responsive",
"property_dict": {
"editable": true,
"secure": "default",
"secret_hash": "foo",
"public_key": "6Ldpb-oSAAAAAGwriKpk4ol1n4yjN_as6M4xv0zA"
},
"children": [{
"generate": "widget",
"type": "controlgroup",
"class_list": "center",
"property_dict": {
"direction": "horizontal"
},
"children": [
{"type": "input", "direct": {"value": "Request SSL", "className": "action translate"}, "attributes": {"type": "submit", "data-action":"request_ssl", "data-icon":"lock", "data-i18n":"[value]portal_type_dict.computer_dict.text_dict.request_ssl", "data-theme": "slapos-black"}}
]
}]
}
]
}
...@@ -41,7 +41,7 @@ ...@@ -41,7 +41,7 @@
{"type": "a", "direct": {"href": "#servers/__id__/scope", "className": "ui-btn-slapos-black"}, "attributes": {"data-i18n":"portal_type_dict.computer_dict.text_dict.scope", "data-icon":"globe"}, "logic": {"text":"Set Server Scope"}}, {"type": "a", "direct": {"href": "#servers/__id__/scope", "className": "ui-btn-slapos-black"}, "attributes": {"data-i18n":"portal_type_dict.computer_dict.text_dict.scope", "data-icon":"globe"}, "logic": {"text":"Set Server Scope"}},
{"type": "a", "direct": {"href": "#servers/__id__/config", "className": "ui-btn-slapos-black"}, "attributes": {"data-i18n":"portal_type_dict.computer_dict.text_dict.config", "data-icon":"cogs"}, "logic": {"text":"Set Configuration"}}, {"type": "a", "direct": {"href": "#servers/__id__/config", "className": "ui-btn-slapos-black"}, "attributes": {"data-i18n":"portal_type_dict.computer_dict.text_dict.config", "data-icon":"cogs"}, "logic": {"text":"Set Configuration"}},
{"type": "a", "direct": {"href": "#servers/__id__/ssl_on", "className": "ui-btn-slapos-black"}, "attributes": {"data-i18n":"portal_type_dict.computer_dict.text_dict.ssl_on", "data-icon":"lock"}, "logic": {"text":"Request SSL"}}, {"type": "a", "direct": {"href": "#servers/__id__/ssl_on", "className": "ui-btn-slapos-black"}, "attributes": {"data-i18n":"portal_type_dict.computer_dict.text_dict.ssl_on", "data-icon":"lock"}, "logic": {"text":"Request SSL"}},
{"type": "a", "direct": {"href": "#servers/__id__/ssl_off", "className": "ui-btn-slapos-black"}, "attributes": {"data-i18n":"portal_type_dict.computer_dict.text_dict.ssl_off", "data-icon":"unlock"}, "logic": {"text":"Revoke SSL"}}, {"type": "a", "direct": {"href": "#", "className": "action ui-btn-slapos-black"}, "attributes": {"data-i18n":"portal_type_dict.computer_dict.text_dict.ssl_off", "data-icon":"unlock", "data-action":"revoke_ssl"}, "logic": {"text":"Revoke SSL"}},
{"type": "a", "direct": {"href": "#", "className": "action translate error status ui-btn ui-shadow ui-corner-all ui-btn-icon-left ui-icon-trash" }, "attributes": {"data-i18n":"portal_type_dict.computer_dict.text_dict.delete", "data-action": "destroy"}, "logic": {"text":"Delete"}} {"type": "a", "direct": {"href": "#", "className": "action translate error status ui-btn ui-shadow ui-corner-all ui-btn-icon-left ui-icon-trash" }, "attributes": {"data-i18n":"portal_type_dict.computer_dict.text_dict.delete", "data-action": "destroy"}, "logic": {"text":"Delete"}}
] ]
}] }]
......
{
"portal_type_source": "Computer",
"portal_type_title": "computer",
"portal_type_fields": "computer_fieldlist",
"portal_type_mapper": "servers",
"initial_query": {"include_docs": true, "limit":[0,1]},
"form": true,
"view": "web_view",
"property_dict": {
"initial_query_url_identifier": "_id",
"dynamic_children": [0],
"requires_authentication": true,
"depends_on": "login_state",
"wrap_gadget": 2,
"submit_to": "#servers/__id__"
},
"scheme": [
{
"position": "left",
"fieldlist": [
{"field": "allocation_scope"},
{"field": "subject_list"}
]
},
{
"position": "right",
"fieldlist": []
}
],
"children": [{
"generate": "widget",
"type": "form",
"class_list": "responsive",
"property_dict": {
"editable": true,
"secure": "default",
"secret_hash": "foo",
"public_key": "6Ldpb-oSAAAAAGwriKpk4ol1n4yjN_as6M4xv0zA"
},
"children": [{
"generate": "widget",
"type": "controlgroup",
"class_list": "center",
"property_dict": {
"direction": "horizontal"
},
"children": [
{"type": "input", "direct": {"value": "Reset", "className": "translate"}, "attributes": {"type": "reset", "data-i18n":"[value]portal_type_dict.computer_dict.text_dict.cancel"}},
{"type": "input", "direct": {"value": "Submit", "className": "action translate"}, "attributes": {"type": "submit", "data-action":"update_scope", "data-icon":"save", "data-i18n":"[value]portal_type_dict.computer_dict.text_dict.submit", "data-theme": "slapos-black"}}
]
}]
}
]
}
...@@ -6,6 +6,7 @@ ...@@ -6,6 +6,7 @@
"form": true, "form": true,
"view": "web_view_category", "view": "web_view_category",
"property_dict": { "property_dict": {
"submit_to": "#servers/__id__",
"initial_query_url_identifier": "_id", "initial_query_url_identifier": "_id",
"dynamic_children": [0], "dynamic_children": [0],
"requires_authentication": true, "requires_authentication": true,
...@@ -15,7 +16,7 @@ ...@@ -15,7 +16,7 @@
{ {
"position": "left", "position": "left",
"fieldlist": [ "fieldlist": [
{"field": "title"}, {"field": "title", "overrides": {"properties": {"editable": false}}},
{"field": "reference", "overrides": {"properties": {"editable": false}}}, {"field": "reference", "overrides": {"properties": {"editable": false}}},
{"field": "url_string"}, {"field": "url_string"},
{"field": "region"}, {"field": "region"},
......
...@@ -17,7 +17,7 @@ ...@@ -17,7 +17,7 @@
{ {
"position": "center", "position": "center",
"fieldlist": [ "fieldlist": [
{"type": "input", "direct": {"disabled": true, "className":"progress_notifier", "name": "status", "id": "status", "value": "Preparing instance..."}, "attributes": {"data-i18n":"[value]portal_type_dict.release_dict.text_dict.prepare_instance", "disabled": "disabled"}} {"type": "input", "direct": {"className":"progress_notifier", "name": "status", "id": "status", "value": "Preparing instance..."}, "attributes": {"data-i18n":"[value]portal_type_dict.release_dict.text_dict.prepare_instance"}, "logic":{"disabled": "disabled"}}
] ]
}, },
{ {
......
...@@ -59,9 +59,27 @@ ...@@ -59,9 +59,27 @@
"href": "computer_view" "href": "computer_view"
} }
], ],
"scope": [], "scope": [
"ssl_on": [], {
"ssl_off": [] "generate": "gadget",
"type": "fieldlist",
"href": "computer_users"
}
],
"ssl_on": [
{
"generate": "gadget",
"type": "fieldlist",
"href": "computer_ssl_request"
}
],
"ssl": [
{
"generate": "gadget",
"type": "fieldlist",
"href": "computer_certificate"
}
]
} }
} }
] ]
......
...@@ -21,7 +21,7 @@ ...@@ -21,7 +21,7 @@
"message_i18n":"portal_type_dict.software_dict.text_dict.no_software", "message_i18n":"portal_type_dict.software_dict.text_dict.no_software",
"children": [ "children": [
{ {
"href": "#software/new", "href": "#services/add",
"text": "Add Software", "text": "Add Software",
"text_i18n": "portal_type_dict.software_dict.text_dict.add_software", "text_i18n": "portal_type_dict.software_dict.text_dict.add_software",
"class_list": "translate ui-btn-slapos-black" "class_list": "translate ui-btn-slapos-black"
......
...@@ -2,6 +2,8 @@ ...@@ -2,6 +2,8 @@
/*global console, window, jIO, complex_queries, FormData, RSVP, document, /*global console, window, jIO, complex_queries, FormData, RSVP, document,
jQuery, i18n, hello, Recaptcha, XMLHttpRequest, Modernizr */ jQuery, i18n, hello, Recaptcha, XMLHttpRequest, Modernizr */
// WARNING: HACKED TOGETHER SO IT WORKS FOR DEMO PURPOSE ONLY!!!
(function (window, document, $) { (function (window, document, $) {
"use strict"; "use strict";
...@@ -18,6 +20,19 @@ ...@@ -18,6 +20,19 @@
map = {}; map = {};
map.options = { map.options = {
"getAllocationScope": function () {
return [
{"text": "", "text_i18n":null, "class":"translate", "value":""},
{"text": "Close", "text_i18n":null, "class":"translate", "value":"close"},
{"text": "Close/Closed for maintenance", "text_i18n":null, "class":"translate", "value":"close/maintenance"},
{"text": "Close/Closed for termination", "text_i18n":null, "class":"translate", "value":"close/termination"},
{"text": "Close/Closed forever", "text_i18n":null, "class":"translate", "value":"close/forever"},
{"text": "Open", "text_i18n":null, "class":"translate", "value":"open"},
{"text": "Open/Friend", "text_i18n":null, "class":"translate", "value":"open/friend"},
{"text": "Open/Personal", "text_i18n":null, "class":"translate", "value":"open/personal"},
{"text": "Open/Public", "text_i18n":null, "class":"translate", "value":"open/public"}
];
},
"getWANType": function () { "getWANType": function () {
return [ return [
{"text": "", "text_i18n":null, "class":"translate", "value":""} {"text": "", "text_i18n":null, "class":"translate", "value":""}
...@@ -913,6 +928,124 @@ ...@@ -913,6 +928,124 @@
.fail(util.error); .fail(util.error);
}, },
/**
* Start a software instance
* @method start_instance
* @param {object} obj Action Object
**/
"update_scope": function (obj) {
var element = obj.element, formData, valid, replace, property, value, id,
decode;
id = obj.state.fragment_list[1];
formData = new FormData();
valid = storage.validate(obj.gadget);
decode = /^[^\/]*%2[^\/]*$/.test(id);
if (valid === undefined) {
util.loader("", "validation_dict.general", "ban-circle");
// form is valid and not "spam"
} else {
replace = obj.gadget.id + "_";
for (property in valid) {
if (valid.hasOwnProperty(property)) {
value = valid[property];
// prepare to store
// TODO: add id to captcha fields missing it...
if (property !== "undefined") {
if (property !== "identifier") {
formData.append(property.replace(replace, ""), value);
}
}
}
}
util.loader("", "status_dict.updating");
storage["items"].get({"_id": obj.state.fragment_list[1]},{"_view": "web_view"})
.then(function(response) {
return jIO.util.ajax({
"url": util.parse(response).data._actions.update_allocation_scope.href,
"type": "POST",
"data": formData
});
})
.then(function (answer) {
util.loader("", "status_dict.success", "check");
$.mobile.changePage("#services");
})
.fail(function(error) {
util.error(error);
if (util.parse(error.target).responseText === "" && id && obj.state.callback) {
$.mobile.changePage(obj.state.callback.replace("__id__", decode ? id : window.encodeURIComponent(id)));
}
});
}
},
/**
* Start a software instance
* @method start_instance
* @param {object} obj Action Object
**/
"request_ssl": function (obj) {
var element, formData, decode, id;
id = obj.state.fragment_list[1];
element = obj.element;
formData = new FormData();
decode = /^[^\/]*%2[^\/]*$/.test(id);
util.loader("", "status_dict.updating");
storage["items"].get({"_id": obj.state.fragment_list[1]},{"_view": "web_view"})
.then(function(response) {
return jIO.util.ajax({
"url": util.parse(response).data._actions.generate_certificate.href,
"type": "POST",
"data": formData
});
})
.then(function (answer) {
// store answer in flux
flux = flux || {};
flux.cert = util.parse(answer.target.responseText);
if (id && obj.state.callback) {
$.mobile.changePage(obj.state.callback.replace("__id__", decode ? id : window.encodeURIComponent(id)));
}
})
.fail(function (error){
util.error(error);
util.loader("", "status_dict.ssl_error", "ban-circle");
});
},
"revoke_ssl": function (obj) {
var element, formData, decode, id;
id = obj.state.fragment_list[1];
element = obj.element;
formData = new FormData();
decode = /^[^\/]*%2[^\/]*$/.test(id);
util.loader("", "status_dict.updating");
storage["items"].get({"_id": obj.state.fragment_list[1]},{"_view": "web_view"})
.then(function(response) {
return jIO.util.ajax({
"url": util.parse(response).data._actions.revoke_certificate.href,
"type": "POST",
"data": formData
});
})
.then(function (answer) {
util.loader("", "status_dict.ssl_revoked", "check");
})
.fail(function (error){
util.error(error);
util.loader("", "status_dict.ssl_no", "ban-circle");
});
},
/** /**
* Start a software instance * Start a software instance
* @method start_instance * @method start_instance
...@@ -1887,6 +2020,7 @@ ...@@ -1887,6 +2020,7 @@
} }
// options // options
// TODO: async... pff
option_list = null; option_list = null;
if (prevail.widget.items || spec.widget.items) { if (prevail.widget.items || spec.widget.items) {
option_list = map.options[prevail.widget.items || spec.widget.items](); option_list = map.options[prevail.widget.items || spec.widget.items]();
...@@ -1926,7 +2060,7 @@ ...@@ -1926,7 +2060,7 @@
prevail.widget.size || spec.widget.size || undefined, prevail.widget.size || spec.widget.size || undefined,
"rows": prevail.widget.width || spec.widget.width || undefined, "rows": prevail.widget.width || spec.widget.width || undefined,
"cols": prevail.widget.height || spec.widget.height || undefined, "cols": prevail.widget.height || spec.widget.height || undefined,
"disabled": (prevail.properties.enabled || spec.properties.enabled) ? "disabled": (spec.properties.enabled || prevail.properties.enabled) ?
undefined : true, undefined : true,
"value": field_value, "value": field_value,
"text": textarea_value, "text": textarea_value,
...@@ -3570,7 +3704,7 @@ ...@@ -3570,7 +3704,7 @@
// TODO: can we also generate a field from another portal_type here? // TODO: can we also generate a field from another portal_type here?
if (field.type) { if (field.type) {
input_config = field; input_config = field;
setter = input_config.logic ? input_config.logic.setValue : undefined; setter = input_config.logic ? (input_config.logic.setValue || input_config.logic.setFlux) : undefined;
// make sure value is set correctly // make sure value is set correctly
if (input_config.logic && setter) { if (input_config.logic && setter) {
...@@ -3583,8 +3717,12 @@ ...@@ -3583,8 +3717,12 @@
input_config.logic[setter_list[l]] = spec.data[setter]; input_config.logic[setter_list[l]] = spec.data[setter];
} }
} else { } else {
input_config.direct.value = spec.data[setter] || if (input_config.logic.setFlux) {
input_config.direct.value = flux.cert[setter] || "Certificate is still active, please revoke existing one.";
} else {
input_config.direct.value = spec.data[setter] ||
(setter + util.uuid()); (setter + util.uuid());
}
} }
} }
} else { } else {
...@@ -4822,11 +4960,12 @@ ...@@ -4822,11 +4960,12 @@
if (config.direct.checked) { if (config.direct.checked) {
active = "on"; active = "on";
} }
if (config.attributes.disabled) { // NOTE: this is in logic, because it can be NULL, too!!!!
if (config.logic.disabled) {
disabled = " ui-disabled"; disabled = " ui-disabled";
mask_set = true; mask_set = true;
} }
if (config.attributes.readonly) { if (config.logic.readonly) {
readonly = " ui-readonly"; readonly = " ui-readonly";
mask_set = true; mask_set = true;
} }
...@@ -5409,7 +5548,8 @@ ...@@ -5409,7 +5548,8 @@
// TODO: make form validation and captcha generic // TODO: make form validation and captcha generic
storage.add = function (config) { storage.add = function (config) {
var property, replace, obj, value, form_to_submit, formData, var property, replace, obj, value, form_to_submit, formData,
valid, pass_id, validate_portal_type_fields, form_data_set; valid, pass_id, validate_portal_type_fields, form_data_set, decode;
form_to_submit = document.getElementById(config.id); form_to_submit = document.getElementById(config.id);
formData = new FormData(); formData = new FormData();
...@@ -5493,8 +5633,9 @@ ...@@ -5493,8 +5633,9 @@
} }
}) })
.then(function (id) { .then(function (id) {
decode = /^[^\/]*%2[^\/]*$/.test(id);
if (id && config.state.callback) { if (id && config.state.callback) {
$.mobile.changePage(config.state.callback.replace("__id__", window.encodeURIComponent(id))); $.mobile.changePage(config.state.callback.replace("__id__", decode ? id : window.encodeURIComponent(id)));
} }
}) })
.fail(util.error); .fail(util.error);
...@@ -6458,10 +6599,13 @@ ...@@ -6458,10 +6599,13 @@
backup = 1; backup = 1;
break; break;
case "add": case "add":
config.mode = "add";
break;
case "config": case "config":
config.mode = "config"; case "scope":
case "ssl_on":
case "ssl_off":
case "ssl":
case "request":
config.mode = query[i];
break; break;
} }
} }
......
...@@ -49,6 +49,9 @@ ...@@ -49,6 +49,9 @@
"find_out_more": "To find out more, please refer to:" "find_out_more": "To find out more, please refer to:"
}, },
"status_dict": { "status_dict": {
"ssl_error": "Please revoke existing certificate first",
"ssl_no": "Certificate does not exist",
"ssl_revoked": "Certificate revoked",
"not_found": "Page not found", "not_found": "Page not found",
"uploading": "Uploading", "uploading": "Uploading",
"fetching": "Fetching Data", "fetching": "Fetching Data",
...@@ -222,6 +225,10 @@ ...@@ -222,6 +225,10 @@
}, },
"computer_dict": { "computer_dict": {
"text_dict": { "text_dict": {
"crt": "computer.crt",
"key": "computer.key",
"request_ssl": "Request SSL",
"ssl_request_info": "Here you can request a new SSL certificate for computer.\nAfter presenting it please copy key and certificate and store in secure place.\nIn case of certificate compromise or lost please request it again.\nCertificate is not stored on Vifib.net servers",
"submit": "Submit", "submit": "Submit",
"cancel": "Cancel", "cancel": "Cancel",
"status": "Status", "status": "Status",
...@@ -241,9 +248,19 @@ ...@@ -241,9 +248,19 @@
"server_instance": "Server Instance", "server_instance": "Server Instance",
"instance_configuration": "Instance Configuration", "instance_configuration": "Instance Configuration",
"installed_services": "Installed Services", "installed_services": "Installed Services",
"title": "Computer Title" "title": "Computer Title",
"update": "Update Server",
"instance_certificate": "Instance Certificate"
}, },
"field_dict": { "field_dict": {
"subjects": {
"title": "Friends (Email)",
"description": "Email adresses that should be authenticated to foo this server."
},
"scope": {
"title": "Allocation Scope",
"description": "The allocation scope for this computer."
},
"network": { "network": {
"title": "Network", "title": "Network",
"description": "The network this computer should be associated to." "description": "The network this computer should be associated to."
......
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