').addClass("center marg-top-15").text(key))
+
+ this.container.find("#api-key-popin-frame").empty().append(panel)
+ },
+
+ remove : function(id, row, trigger, container) {
+ var b = PeeringDB.confirm(gettext("Remove") + " " +row.data("edit-label"), "remove"); ///
+ var me = this;
+ $(this.target).on("success", function(ev, data) {
+ if(b)
+ me.listing_remove(id, row, trigger, container);
+ });
+ if(b) {
+ this.target.data = { prefix : id, org_id : this.org_id() };
+ this.target.execute("delete");
+ } else {
+ $(this.target).trigger("success", [gettext("Canceled")]); ///
+ }
+ },
+
+ execute_add : function(trigger, container) {
+ this.components.add.editable("export", this.target.data);
+ var data = this.target.data;
+ this.target.execute("add", this.components.add, function(response) {
+ if(response.readonly)
+ response.name = response.name + " (read-only)";
+ var row = this.add(data.entity, trigger, container, response);
+ console.log(data)
+ console.log(row)
+ this.api_key_popin(response.key)
+ }.bind(this));
+ },
+
+ add : function(rowId, trigger, container, data) {
+ var row = this.listing_add(data.prefix, trigger, container, data);
+ row.attr("data-edit-label", data.prefix + " - " + data.name)
+ row.data("edit-label", data.prefix + " - " + data.name)
+ var update_key_form = row.find(".update-key")
+ update_key_form.find(".popin, .loading-shim").detach()
+ update_key_form.editable()
+ return row
+ },
+
+ execute_update : function(trigger, container) {
+ var row = this.row(trigger);
+ row.editable("export", this.target.data);
+ var data = this.target.data;
+ var id = data.prefix = row.data("edit-id")
+ console.log(this.target, row)
+ this.target.execute("update", trigger, function(response) {
+ }.bind(this));
+ },
+
+ execute_revoke : function(trigger, container) {
+
+ var row = this.row(trigger);
+ var b = PeeringDB.confirm(gettext("Revoke key") + " " +row.data("edit-label"), "remove");
+
+ if(!b) {
+ container.editable("loading-shim", "hide")
+ return
+ }
+
+ this.components.add.editable("export", this.target.data);
+ var data = this.target.data;
+ var id = data.prefix = row.data("edit-id")
+ this.target.execute("revoke", trigger, function(response) {
+ this.listing_remove(id, row, trigger, container);
+ }.bind(this));
+ }
+
+ },
+ "listing"
+);
+
+
twentyc.editable.module.register(
"uoar_listing",
{
@@ -1566,7 +1865,13 @@ twentyc.editable.target.register(
else
me.trigger("success", {});
}
- ).fail(function(r) {
+ ).done(function(r) {
+ if (r.meta && r.meta.geovalidation_warning){
+ PeeringDB.add_geo_warning(r.meta, endpoint);
+ } else if (r.meta && r.meta.suggested_address){
+ PeeringDB.add_suggested_address(r, endpoint);
+ }
+ }).fail(function(r) {
if(r.status == 400) {
var k,i,info=[gettext("The server rejected your data")]; ///
for(k in r.responseJSON) {
diff --git a/peeringdb_server/static/site.css b/peeringdb_server/static/site.css
index 6565d127..bef16249 100644
--- a/peeringdb_server/static/site.css
+++ b/peeringdb_server/static/site.css
@@ -145,6 +145,10 @@ a.btn {
top: 0px;
}
+a.btn.suggestion-accept {
+ margin-top: 16px;
+}
+
h5 {
font-weight: bold;
}
diff --git a/peeringdb_server/templates/email/notify-pdb-admin-asnauto-skipvq-org-key.txt b/peeringdb_server/templates/email/notify-pdb-admin-asnauto-skipvq-org-key.txt
new file mode 100644
index 00000000..ad9cbee4
--- /dev/null
+++ b/peeringdb_server/templates/email/notify-pdb-admin-asnauto-skipvq-org-key.txt
@@ -0,0 +1,9 @@
+{% load i18n %}
+{% language 'en' %}
+
+{% blocktrans with prefix=org_key.prefix email=org_key.email n_name=net.name n_asn=net.asn n_id=net.id o_name=org.name o_id=org.id n_url=net.view_url o_url=org.view_url trimmed %}
+Organization API Key (prefix:{{ prefix }}) with email '{{ email }}' created Network {{ n_name }} AS{{ n_asn }} (
{{n_id}}) under organization {{ o_name }} (
{{ o_id }}).
+{% endblocktrans %}
+
+{% trans "As the key's email address was successfully matched against RiR entry data this network has skipped the verification queue." %}
+{% endlanguage %}
diff --git a/peeringdb_server/templates/email/notify-pdb-admin-deletion-prevented-org-key.txt b/peeringdb_server/templates/email/notify-pdb-admin-deletion-prevented-org-key.txt
new file mode 100644
index 00000000..1a38b11f
--- /dev/null
+++ b/peeringdb_server/templates/email/notify-pdb-admin-deletion-prevented-org-key.txt
@@ -0,0 +1,9 @@
+Organization APIKey (prefix: {{ org_key.prefix }}, email: {{ org_key.email }}) tried to delete the following object:
+
+{{ instance.HandleRef.tag }}-{{ instance.id }}: {{ instance }}
+
+The deletion was prevented because of the following reason(s):
+
+{{ instance.not_deletable_reason }}
+
+{{ admin_url }}
diff --git a/peeringdb_server/templates/email/notify-pdb-admin-rdap-error-org-key.txt b/peeringdb_server/templates/email/notify-pdb-admin-rdap-error-org-key.txt
new file mode 100644
index 00000000..0e32cb5d
--- /dev/null
+++ b/peeringdb_server/templates/email/notify-pdb-admin-rdap-error-org-key.txt
@@ -0,0 +1,5 @@
+Organization API Key (prefix: {{org_key.prefix}}) has run into an RDAP Lookup Error when trying to create a network under the org {{ org_key.org.name }}.
+
+ASN: {{ asn }}
+Error Details: {{ error_details }}
+Org APIKey Email: {{org_key.email}}
diff --git a/peeringdb_server/templates/email/notify-pdb-admin-vq-org-key.txt b/peeringdb_server/templates/email/notify-pdb-admin-vq-org-key.txt
new file mode 100644
index 00000000..78b9f9a3
--- /dev/null
+++ b/peeringdb_server/templates/email/notify-pdb-admin-vq-org-key.txt
@@ -0,0 +1,27 @@
+{% load i18n %}
+{% language 'en' %}
+{% blocktrans trimmed%}
+A new '{{ entity_type_name }}' has been created and requires your approval.
+{% endblocktrans %}
+
+{% if suggested %}
+{% blocktrans trimmed %}
+ This {{ entity_type_name }} has been submitted as a suggestion and will need to be assigned the appropriate organization after review
+{% endblocktrans %}
+{% endif %}
+
+{% if rdap %}
+ {% trans "We retrieved the RiR entry for the specified ASN" %} {{ item.asn }}
+ {% if not suggested %}
+ {% trans "but found no match with the requesting Organization API Key email. Here are the email addresses we gathered" %}:
+ {% endif %}
+ {% for email in rdap.emails %} - {{ email }} {% endfor %}
+{% endif %}
+
+{% trans "Name" %}:
{{ item }}
+{% trans "Requested by Organization API Key" %}:
+- {% trans "Organization" %}: {{ org_key.org.name }}
+- {% trans "API key prefix" %}: {{ org_key.prefix }}
+- {% trans "Email" %}: {{ org_key.email }}
+
+{% trans "You can go to" %}
{{ edit_url }} {% trans "to view and approve or deny this entry" %}{% endlanguage %}
diff --git a/peeringdb_server/templates/site/org_manage_key_permissions.html b/peeringdb_server/templates/site/org_manage_key_permissions.html
new file mode 100644
index 00000000..750531a1
--- /dev/null
+++ b/peeringdb_server/templates/site/org_manage_key_permissions.html
@@ -0,0 +1,116 @@
+{% load util %}
+{% load i18n %}
+
+
+ {%blocktrans trimmed %}
+ Here you can grant permissions to your organization API keys. In case your recently added api key does not show up in this listing, please reload the page.
+ {%endblocktrans%}
+
+
+
+
+
+ {% for kperms in key_perms.values %}
+
+
+
+
+
+
+ {% for entity, perm in kperms.perms.items %}
+
+
+
+
{{ kperms.prefix }}
+
{{ instance.id }}
+
{{ entity }}
+
+
+
×
+
{{ instance|org_permission_id_xl:entity }}
+
+
+
+
+
+
+
+
+ {% endfor %}
+
+
+
+
+
+
+
{{ instance.id }}
+
{{ kperms.prefix }}
+
+
+
+
+
+
+
+
+
+ {% endfor %}
+
+
+
+
+
+
diff --git a/peeringdb_server/templates/site/org_manage_keys.html b/peeringdb_server/templates/site/org_manage_keys.html
new file mode 100644
index 00000000..c6aa54cd
--- /dev/null
+++ b/peeringdb_server/templates/site/org_manage_keys.html
@@ -0,0 +1,111 @@
+{% load util %}
+{% load i18n %}
+
+ {%blocktrans trimmed %}
+ Here you can create new API keys for your organization or revoke existing keys.
+ {%endblocktrans%}
+
+
+
+
+
+
+
+
+ {% for key in instance.api_keys.all %}
+ {% if not key.revoked %}
+
+ {% endif %}
+ {% endfor %}
+
+
+
+
+
+
+
+
+
{% trans "Add Key" %}
+
+
+
+
+
+
+
diff --git a/peeringdb_server/templates/site/profile-api-keys.html b/peeringdb_server/templates/site/profile-api-keys.html
new file mode 100644
index 00000000..e7a9c78a
--- /dev/null
+++ b/peeringdb_server/templates/site/profile-api-keys.html
@@ -0,0 +1,86 @@
+{% load i18n %}
+
+
+
+
+ {% blocktrans trimmed %}
+ API Keys allow you to authenticate a client without providing your username and password.
+ {% endblocktrans %}
+
+
+
+
+
+
+
+ {% for key in user.api_keys.all %}
+ {% if not key.revoked %}
+
+
{{ key.prefix }}
+
+ {{ key.name }}
+ {% if key.readonly %}({% trans "read-only" %}){% endif %}
+
+
+
+ {% endif %}
+ {% endfor %}
+
+
+
+ {% if request.user.is_superuser %}
+
+ {% blocktrans trimmed %}
+ You are creating an API Key for a superuser account. Such API keys cannot be made
+ read only and will always have full access. Proceed with caution.
+ {% endblocktrans %}
+
+ {% endif %}
+
+
+
+
+
+
+
{% trans "Add Key" %}
+
+
+
+ {% if not request.user.is_superuser %}
+
{% trans "Read only" %}
+ {% endif %}
+
+
+
+
+
+
+
diff --git a/peeringdb_server/templates/site/verify.html b/peeringdb_server/templates/site/verify.html
index 81303613..2882da24 100644
--- a/peeringdb_server/templates/site/verify.html
+++ b/peeringdb_server/templates/site/verify.html
@@ -34,6 +34,9 @@
{% include "site/profile-change-password.html" %}
{% endif %}
+
+ {% include "site/profile-api-keys.html" %}
+