Merge branch 'stable-3.0'

* stable-3.0:
  Upgrade bazlets to latest stable-3.0 to build with 3.0.5 API
  Allow HTML in success messages
  Upgrade bazlets to latest stable-3.0 to build with 3.0.4 API
  Upgrade bazlets to latest stable-2.16 to build with 2.16.13 API
  Upgrade bazlets to latest stable-3.0
  Upgrade bazlets to latest stable-2.16
  Upgrade bazlets to latest stable-2.15 to build with 2.15.18 API
  Bazel: Migrate workspace status script to python
  Upgrade bazlets to latest stable-2.15
  Upgrade bazlets to latest stable-2.14
  Upgrade bazlets to latest stable-2.16
  Upgrade bazlets to latest stable-2.15
  Upgrade bazlets to latest stable-2.14
  Bump Bazel version to 1.1.0
  Check if full name and email edit are allowed in realm
  Show success message in dialog
  Fix display of owner group input on details screen
  Make full name and email in details screen better readable
  Use on-click instead of on-tap
  Replace bazel-genfiles with bazel-bin in documentation
  Upgrade bazlets to latest stable-3.0 to build with 3.0.3 API
  Bump bazel version to 1.0.0
  Upgrade bazlets to latest stable-2.16 to build with 2.16.12 API
  Upgrade bazlets to latest stable-2.15 to build with 2.15.17 API

Change-Id: I5ad452358d11cc90359db5dded41a519ac50a6cb
diff --git a/.bazelrc b/.bazelrc
index 4ed16cf..3ae03ff 100644
--- a/.bazelrc
+++ b/.bazelrc
@@ -1,2 +1,2 @@
-build --workspace_status_command=./tools/workspace-status.sh
+build --workspace_status_command="python ./tools/workspace_status.py"
 test --build_tests_only
diff --git a/.bazelversion b/.bazelversion
index 25939d3..9084fa2 100644
--- a/.bazelversion
+++ b/.bazelversion
@@ -1 +1 @@
-0.29.1
+1.1.0
diff --git a/WORKSPACE b/WORKSPACE
index 44bb695..4005492 100644
--- a/WORKSPACE
+++ b/WORKSPACE
@@ -3,7 +3,7 @@
 load("//:bazlets.bzl", "load_bazlets")
 
 load_bazlets(
-    commit = "0ca51936ca46049cddd34e971a595d3baafe731b",
+    commit = "7111147b7cf9d9cd4d61f414c815f736f56f0de0",
     #local_path = "/home/<user>/projects/bazlets",
 )
 
diff --git a/src/main/resources/Documentation/build.md b/src/main/resources/Documentation/build.md
index ff88faf..40a9cc4 100644
--- a/src/main/resources/Documentation/build.md
+++ b/src/main/resources/Documentation/build.md
@@ -16,7 +16,7 @@
 The output is created in
 
 ```
-  bazel-genfiles/plugins/@PLUGIN@/@PLUGIN@.jar
+  bazel-bin/plugins/@PLUGIN@/@PLUGIN@.jar
 ```
 
 This project can be imported into the Eclipse IDE.
diff --git a/src/main/resources/static/gr-serviceuser-create.html b/src/main/resources/static/gr-serviceuser-create.html
index b6b71fe..763c47d 100644
--- a/src/main/resources/static/gr-serviceuser-create.html
+++ b/src/main/resources/static/gr-serviceuser-create.html
@@ -68,10 +68,23 @@
         </section>
       </fieldset>
       <gr-button id="createButton"
-                 on-tap="_handleCreateServiceUser"
+                 on-click="_handleCreateServiceUser"
                  disabled="[[!_enableButton]]">
         Create
       </gr-button>
+      <gr-overlay id="successDialogOverlay" with-backdrop>
+        <gr-dialog id="successDialog"
+                   confirm-label="OK"
+                   cancel-label=""
+                   on-confirm="_forwardToDetails"
+                   confirm-on-enter>
+          <div slot="header">
+            Success
+          </div>
+          <div id="successMessage" slot="main">
+          </div>
+        </gr-dialog>
+      </gr-overlay>
     </main>
   </template>
   <script src="gr-serviceuser-create.js"></script>
diff --git a/src/main/resources/static/gr-serviceuser-create.js b/src/main/resources/static/gr-serviceuser-create.js
index bc04de5..df5d9a6 100644
--- a/src/main/resources/static/gr-serviceuser-create.js
+++ b/src/main/resources/static/gr-serviceuser-create.js
@@ -52,12 +52,20 @@
         type: Boolean,
         value: false,
       },
+      _accountId: String,
     },
 
     attached() {
       this._getConfig();
     },
 
+    _forwardToDetails() {
+      page.show(
+          this.plugin.screenUrl()
+          + '/user/'
+          + this._accountId);
+    },
+
     _getConfig() {
       return this.plugin.restApi('/config/server/serviceuser~config/').get('')
           .then(config => {
@@ -74,6 +82,7 @@
             if (config.on_success && config.on_success != '') {
               this._successMessageEnabled = true;
               this._successMessage = config.on_success;
+              this.$.successMessage.innerHTML = this._successMessage;
             }
 
             this._emailEnabled = config.allow_email;
@@ -125,13 +134,12 @@
       return this.plugin.restApi('/config/server/serviceuser~serviceusers/')
           .post(this._newUsername, body)
           .then(response => {
+            this._accountId = response._account_id;
             if (this._successMessage) {
-              this.fire('show-alert', {message: this._successMessage});
+              this.$.successDialogOverlay.open();
+            } else {
+              this._forwardToDetails();
             }
-            page.show(
-                this.plugin.screenUrl()
-              + '/user/'
-              + response._account_id);
           }).catch(response => {
             this.fire('show-error', {message: response});
             this._isAdding = false;
diff --git a/src/main/resources/static/gr-serviceuser-detail.html b/src/main/resources/static/gr-serviceuser-detail.html
index 8dedf23..d5ba86e 100644
--- a/src/main/resources/static/gr-serviceuser-detail.html
+++ b/src/main/resources/static/gr-serviceuser-detail.html
@@ -46,6 +46,14 @@
         text-align: center;
       }
 
+      span.value {
+        width: 50%;
+      }
+
+      input.wide {
+        width: 100%;
+      }
+
       span.Active {
         background-color: #9fcc6b;
       }
@@ -74,7 +82,7 @@
                     [[_active(_serviceUser)]]
                   </span>
                 </section>
-                <gr-button id="statusToggleButton" on-tap="_toggleStatus" disabled="[[_loading]]">
+                <gr-button id="statusToggleButton" on-click="_toggleStatus" disabled="[[_loading]]">
                   [[_statusButtonText]]</gr-button>
               </fieldset>
               <fieldset>
@@ -85,32 +93,37 @@
                 </section>
                 <section>
                   <span class="title">Full Name</span>
-                  <span class="value">
-                    <input id="serviceUserFullNameInput" bind-value="{{_newFullName}}" is="iron-input" type="text"
-                      disabled="[[_changingPrefs]]" placeholder$="[[_serviceUser.name]]"
-                      on-keyup="_computePrefsChanged">
+                  <span class="value" hidden$="[[!_allowFullName]]">
+                    <input id="serviceUserFullNameInput" class="wide" bind-value="{{_newFullName}}"
+                      is="iron-input" type="text" disabled="[[_changingPrefs]]"
+                      placeholder$="[[_serviceUser.name]]" on-keyup="_computePrefsChanged">
                   </span>
+                  <span class="value" hidden$="[[_allowFullName]]">[[_serviceUser.name]]</span>
                 </section>
                 <section>
                   <span class="title">Email Address</span>
-                  <input id="serviceUserEmailInput" bind-value="{{_newEmail}}" is="iron-input" type="text"
-                    disabled="[[_changingPrefs]]" placeholder="[[_serviceUser.email]]" on-keyup="_computePrefsChanged"
-                    hidden$="[[!_allowEmail]]">
+                  <span class="value" hidden$="[[!_allowEmail]]">
+                    <input id="serviceUserEmailInput" class="wide" bind-value="{{_newEmail}}"
+                      is="iron-input" type="text" disabled="[[_changingPrefs]]"
+                      placeholder="[[_serviceUser.email]]" on-keyup="_computePrefsChanged">
+                  </span>
                   <span class="value" hidden$="[[_allowEmail]]">[[_serviceUser.email]]</span>
                 </section>
                 <section>
                   <span class="title">Owner Group</span>
-                  <gr-autocomplete id="serviceUserOwnerInput" text="{{_getOwnerGroup(_serviceUser)}}"
-                    value="{{_newOwner}}" query="[[_query]]" disabled="[[_changingPrefs]]"
-                    on-commit="_computePrefsChanged" on-keyup="_computePrefsChanged" hidden$="[[!_allowOwner]]">
-                    [[_getOwnerGroup(_serviceUser)]]
-                  </gr-autocomplete>
+                  <span class="value" hidden$="[[!_allowOwner]]">
+                    <gr-autocomplete id="serviceUserOwnerInput" text="{{_getOwnerGroup(_serviceUser)}}"
+                      value="{{_newOwner}}" query="[[_query]]" disabled="[[_changingPrefs]]"
+                      on-commit="_computePrefsChanged" on-keyup="_computePrefsChanged">
+                        [[_getOwnerGroup(_serviceUser)]]
+                    </gr-autocomplete>
+                  </span>
                   <span class="value" hidden$="[[_allowOwner]]">[[_getOwnerGroup(_serviceUser)]]</span>
                 </section>
                 <p id="ownerChangeWarning" class="style-scope gr-settings-view" hidden$="[[!_newOwner]]">
                   [[_ownerChangeWarning]]
                 </p>
-                <gr-button id="savePrefs" on-tap="_handleSavePreferences" disabled="[[!_prefsChanged]]">
+                <gr-button id="savePrefs" on-click="_handleSavePreferences" disabled="[[!_prefsChanged]]">
                   Save changes
                 </gr-button>
               </fieldset>
diff --git a/src/main/resources/static/gr-serviceuser-detail.js b/src/main/resources/static/gr-serviceuser-detail.js
index c2ea3e5..53ec980 100644
--- a/src/main/resources/static/gr-serviceuser-detail.js
+++ b/src/main/resources/static/gr-serviceuser-detail.js
@@ -25,6 +25,7 @@
       _restApi: Object,
       _serviceUserId: String,
       _serviceUser: Object,
+      _serverConfig: Object,
       _loading: {
         type: Boolean,
         value: true,
@@ -49,6 +50,10 @@
         type: Boolean,
         value: false,
       },
+      _allowFullName: {
+        type: Boolean,
+        value: false,
+      },
       _allowOwner: {
         type: Boolean,
         value: false,
@@ -75,8 +80,10 @@
     ],
 
     attached() {
-      this._extractUserId();
-      this._loadServiceUser();
+      this._getPermissions().then(() => {
+        this._extractUserId();
+        this._loadServiceUser();
+      });
     },
 
     _loadServiceUser() {
@@ -86,6 +93,7 @@
 
       promises.push(this._getPluginConfig());
       promises.push(this._getServiceUser());
+      promises.push(this._getServerConfig());
 
       Promise.all(promises).then(() => {
         this.$.sshEditor.loadData(this._restApi, this._serviceUser);
@@ -94,6 +102,13 @@
         this.fire('title-change', {title: this._serviceUser.name});
         this._computeStatusButtonText();
         this._loading = false;
+        this._newFullName = this._serviceUser.name;
+        this._newEmail = this._serviceUser.email;
+        this._allowFullName = this._serverConfig.auth.editable_account_fields
+          .includes('FULL_NAME');
+        this._allowEmail = this._allowEmail &&
+          this._serverConfig.auth.editable_account_fields
+            .includes('REGISTER_NEW_EMAIL');
       });
     },
 
@@ -113,17 +128,25 @@
     },
 
     _getPluginConfig() {
-      return Promise.resolve(this._getPermissions()).then(() => {
-        this.plugin.restApi('/config/server/serviceuser~config/').get('')
-            .then(config => {
-              if (!config) {
-                return;
-              }
-              this._allowEmail = config.allow_email || this._isAdmin;
-              this._allowOwner = config.allow_owner || this._isAdmin;
-              this._allowHttpPassword = config.allow_http_password
-                || this._isAdmin;
-            });
+      return this.plugin.restApi('/config/server/serviceuser~config/').get('')
+          .then(config => {
+            if (!config) {
+              return;
+            }
+            this._allowEmail = config.allow_email || this._isAdmin;
+            this._allowOwner = config.allow_owner || this._isAdmin;
+            this._allowHttpPassword = config.allow_http_password
+              || this._isAdmin;
+          });
+    },
+
+    _getServerConfig() {
+      return this.plugin.restApi().getConfig().then(cfg => {
+        if (!cfg) {
+          return;
+        }
+
+        this._serverConfig = cfg;
       });
     },
 
diff --git a/src/main/resources/static/gr-serviceuser-http-password.html b/src/main/resources/static/gr-serviceuser-http-password.html
index f2f5b3e..8cebbe5 100644
--- a/src/main/resources/static/gr-serviceuser-http-password.html
+++ b/src/main/resources/static/gr-serviceuser-http-password.html
@@ -54,9 +54,9 @@
           <span class="value">[[_serviceUser.username]]</span>
         </section>
         <gr-button id="generateButton"
-                   on-tap="_handleGenerateTap">Generate new password</gr-button>
+                   on-click="_handleGenerateTap">Generate new password</gr-button>
         <gr-button id="deleteButton"
-                   on-tap="_handleDelete">Delete password</gr-button>
+                   on-click="_handleDelete">Delete password</gr-button>
       </div>
     </div>
     <gr-overlay id="generatedPasswordOverlay"
@@ -73,7 +73,7 @@
         </section>
         <gr-button link
                    class="closeButton"
-                   on-tap="_closeOverlay">Close</gr-button>
+                   on-click="_closeOverlay">Close</gr-button>
       </div>
     </gr-overlay>
   </template>
diff --git a/src/main/resources/static/gr-serviceuser-list.html b/src/main/resources/static/gr-serviceuser-list.html
index 052e9f4..e927d63 100644
--- a/src/main/resources/static/gr-serviceuser-list.html
+++ b/src/main/resources/static/gr-serviceuser-list.html
@@ -42,7 +42,7 @@
         <gr-button primary
                    link
                    id="createNew"
-                   on-tap="_createNewServiceUser">
+                   on-click="_createNewServiceUser">
           Create New
         </gr-button>
       </div>
diff --git a/src/main/resources/static/gr-serviceuser-ssh-panel.html b/src/main/resources/static/gr-serviceuser-ssh-panel.html
index b7ed896..2906a10 100644
--- a/src/main/resources/static/gr-serviceuser-ssh-panel.html
+++ b/src/main/resources/static/gr-serviceuser-ssh-panel.html
@@ -74,14 +74,14 @@
                 <td>[[_getStatusLabel(key.valid)]]</td>
                 <td>
                   <gr-button link
-                             on-tap="_showKey"
+                             on-click="_showKey"
                              data-index$="[[index]]"
                              link>Click to View</gr-button>
                 </td>
                 <td>
                   <gr-button link
                              data-index$="[[index]]"
-                             on-tap="_handleDeleteKey">Delete</gr-button>
+                             on-click="_handleDeleteKey">Delete</gr-button>
                 </td>
               </tr>
             </template>
@@ -104,7 +104,7 @@
             </section>
           </fieldset>
           <gr-button class="closeButton"
-                     on-tap="_closeOverlay">Close</gr-button>
+                     on-click="_closeOverlay">Close</gr-button>
         </gr-overlay>
       </fieldset>
       <fieldset>
@@ -121,7 +121,7 @@
         <gr-button id="addButton"
                    link
                    disabled$="[[_computeAddButtonDisabled(_newKey)]]"
-                   on-tap="_handleAddKey">
+                   on-click="_handleAddKey">
           Add new SSH key
         </gr-button>
       </fieldset>
diff --git a/tools/workspace-status.sh b/tools/workspace-status.sh
deleted file mode 100755
index cb96138..0000000
--- a/tools/workspace-status.sh
+++ /dev/null
@@ -1,17 +0,0 @@
-#!/bin/bash
-
-# This script will be run by bazel when the build process starts to
-# generate key-value information that represents the status of the
-# workspace. The output should be like
-#
-# KEY1 VALUE1
-# KEY2 VALUE2
-#
-# If the script exits with non-zero code, it's considered as a failure
-# and the output will be discarded.
-
-function rev() {
-  cd $1; git describe --always --match "v[0-9].*" --dirty
-}
-
-echo STABLE_BUILD_SERVICEUSER_LABEL $(rev .)
diff --git a/tools/workspace_status.py b/tools/workspace_status.py
new file mode 100644
index 0000000..8574d17
--- /dev/null
+++ b/tools/workspace_status.py
@@ -0,0 +1,31 @@
+#!/usr/bin/env python
+
+# This script will be run by bazel when the build process starts to
+# generate key-value information that represents the status of the
+# workspace. The output should be like
+#
+# KEY1 VALUE1
+# KEY2 VALUE2
+#
+# If the script exits with non-zero code, it's considered as a failure
+# and the output will be discarded.
+
+from __future__ import print_function
+import subprocess
+import sys
+
+CMD = ['git', 'describe', '--always', '--match', 'v[0-9].*', '--dirty']
+
+
+def revision():
+    try:
+        return subprocess.check_output(CMD).strip().decode("utf-8")
+    except OSError as err:
+        print('could not invoke git: %s' % err, file=sys.stderr)
+        sys.exit(1)
+    except subprocess.CalledProcessError as err:
+        print('error using git: %s' % err, file=sys.stderr)
+        sys.exit(1)
+
+
+print("STABLE_BUILD_SERVICEUSER_LABEL %s" % revision())