Add "Admin" tab to the registrar console

This tab will set the "allowedTlds", but might have other functionality in the
future.

It is based on (branches from) the security-settings tab, because I'm copying the functionality of the "whitelisted IPs" to the "allowed TLDs": they are both lists of "arbitrary" strings that you can remove from and add to.

There are a lot of moving parts in this CL, because of how all the different elements need to interact, and how intertwined they are (for example, we need to disable the admin-settings view for non admins both in the soy and in the JS code)

It's really time to refactor the console given all we've learned... :/

-------------
Created by MOE: https://github.com/google/moe
MOE_MIGRATED_REVID=220373443
This commit is contained in:
guyben 2018-11-06 16:23:46 -08:00 committed by jianglai
parent 9b10c116f3
commit 61a5cf307e
11 changed files with 274 additions and 4 deletions

View file

@ -0,0 +1,106 @@
// Copyright 2017 The Nomulus Authors. All Rights Reserved.
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
goog.provide('registry.registrar.AdminSettings');
goog.require('goog.array');
goog.require('goog.dom');
goog.require('goog.dom.classlist');
goog.require('goog.events');
goog.require('goog.events.EventType');
goog.require('goog.soy');
goog.require('registry.Resource');
goog.require('registry.ResourceComponent');
goog.require('registry.soy.registrar.admin');
goog.forwardDeclare('registry.registrar.Console');
/**
* Admin Settings page, such as allowed TLDs for this registrar.
* @param {!registry.registrar.Console} console
* @param {!registry.Resource} resource the RESTful resource for the registrar.
* @constructor
* @extends {registry.ResourceComponent}
* @final
*/
registry.registrar.AdminSettings = function(console, resource) {
registry.registrar.AdminSettings.base(
this, 'constructor', console, resource,
registry.soy.registrar.admin.settings, null);
};
goog.inherits(registry.registrar.AdminSettings, registry.ResourceComponent);
/** @override */
registry.registrar.AdminSettings.prototype.bindToDom = function(id) {
registry.registrar.AdminSettings.base(this, 'bindToDom', 'fake');
goog.dom.removeNode(goog.dom.getRequiredElement('reg-app-btn-back'));
};
/** @override */
registry.registrar.AdminSettings.prototype.setupEditor =
function(objArgs) {
goog.dom.classlist.add(goog.dom.getRequiredElement('tlds'),
goog.getCssName('editing'));
var tlds = goog.dom.getElementsByClass(goog.getCssName('tld'),
goog.dom.getRequiredElement('tlds'));
goog.array.forEach(tlds, function(tld) {
var remBtn = goog.dom.getChildren(tld)[0];
goog.events.listen(remBtn,
goog.events.EventType.CLICK,
goog.bind(this.onTldRemove_, this, remBtn));
}, this);
this.typeCounts['reg-tlds'] = objArgs.allowedTlds ?
objArgs.allowedTlds.length : 0;
goog.events.listen(goog.dom.getRequiredElement('btn-add-tld'),
goog.events.EventType.CLICK,
this.onTldAdd_,
false,
this);
};
/**
* Click handler for TLD add button.
* @private
*/
registry.registrar.AdminSettings.prototype.onTldAdd_ = function() {
const tldInputElt = goog.dom.getRequiredElement('newTld');
const tldElt = goog.soy.renderAsFragment(registry.soy.registrar.admin.tld, {
name: 'allowedTlds[' + this.typeCounts['reg-tlds'] + ']',
tld: tldInputElt.value,
});
goog.dom.appendChild(goog.dom.getRequiredElement('tlds'), tldElt);
var remBtn = goog.dom.getFirstElementChild(tldElt);
goog.dom.classlist.remove(remBtn, goog.getCssName('hidden'));
goog.events.listen(remBtn, goog.events.EventType.CLICK,
goog.bind(this.onTldRemove_, this, remBtn));
this.typeCounts['reg-tlds']++;
tldInputElt.value = '';
};
/**
* Click handler for TLD remove button.
* @param {!Element} remBtn The remove button.
* @private
*/
registry.registrar.AdminSettings.prototype.onTldRemove_ =
function(remBtn) {
goog.dom.removeNode(goog.dom.getParentElement(remBtn));
};

View file

@ -21,6 +21,7 @@ goog.require('goog.dom.classlist');
goog.require('goog.net.XhrIo');
goog.require('registry.Console');
goog.require('registry.Resource');
goog.require('registry.registrar.AdminSettings');
goog.require('registry.registrar.Contact');
goog.require('registry.registrar.ContactSettings');
goog.require('registry.registrar.ContactUs');
@ -76,20 +77,43 @@ registry.registrar.Console = function(params) {
this.lastActiveNavElt;
/**
* A map from the URL fragment to the component to show.
*
* @type {!Object.<string, function(new:registry.Component,
* !registry.registrar.Console,
* !registry.Resource)>}
*/
this.pageMap = {};
// Homepage. Displayed when there's no fragment, or when the fragment doesn't
// correspond to any view
this.pageMap[''] = registry.registrar.Dashboard;
// Updating the Registrar settings
this.pageMap['security-settings'] = registry.registrar.SecuritySettings;
this.pageMap['contact-settings'] = registry.registrar.ContactSettings;
this.pageMap['whois-settings'] = registry.registrar.WhoisSettings;
this.pageMap['contact-us'] = registry.registrar.ContactUs;
this.pageMap['resources'] = registry.registrar.Resources;
// For admin use. The relevant tab is only shown in Console.soy for admins,
// but we also need to remove it here, otherwise it'd still be accessible if
// the user manually puts '#admin-settings' in the URL.
//
// Both the Console.soy and here, the "hiding the admin console for non
// admins" is purely for "aesthetic / design" reasons and have NO security
// implications.
//
// The security implications are only in the backend where we make sure all
// changes are made by users with the correct access (in other words - we
// don't trust the client-side to secure our application anyway)
if (this.params.isAdmin) {
this.pageMap['admin-settings'] = registry.registrar.AdminSettings;
}
// sending EPPs through the console. Currently hidden (doesn't have a "tab")
// but still accessible if the user manually puts #domain (or other) in the
// fragment
this.pageMap['contact'] = registry.registrar.Contact;
this.pageMap['domain'] = registry.registrar.Domain;
this.pageMap['host'] = registry.registrar.Host;
this.pageMap[''] = registry.registrar.Dashboard;
};
goog.inherits(registry.registrar.Console, registry.Console);

View file

@ -28,6 +28,7 @@ goog.require('registry.registrar.Console');
*
* @param {string} xsrfToken populated by server-side soy template.
* @param {string} clientId The registrar clientId.
* @param {boolean} isAdmin
* @param {string} productName the product name displayed by the UI.
* @param {string} integrationEmail
* @param {string} supportEmail
@ -36,13 +37,14 @@ goog.require('registry.registrar.Console');
* @param {string} technicalDocsUrl
* @export
*/
registry.registrar.main = function(xsrfToken, clientId, productName,
registry.registrar.main = function(xsrfToken, clientId, isAdmin, productName,
integrationEmail, supportEmail,
announcementsEmail, supportPhoneNumber,
technicalDocsUrl) {
new registry.registrar.Console({
xsrfToken: xsrfToken,
clientId: clientId,
isAdmin: isAdmin,
productName: productName,
integrationEmail: integrationEmail,
supportEmail: supportEmail,

View file

@ -103,5 +103,4 @@ registry.registrar.SecuritySettings.prototype.onIpAdd_ = function() {
registry.registrar.SecuritySettings.prototype.onIpRemove_ =
function(remBtn) {
goog.dom.removeNode(goog.dom.getParentElement(remBtn));
this.typeCounts['reg-ips']--;
};