]> source.dussan.org Git - sonarqube.git/commitdiff
SONAR-7184 Add the token management to the 'My Profile' page
authorStas Vilchik <vilchiks@gmail.com>
Fri, 15 Jan 2016 10:05:03 +0000 (11:05 +0100)
committerStas Vilchik <vilchiks@gmail.com>
Fri, 15 Jan 2016 10:05:03 +0000 (11:05 +0100)
server/sonar-web/src/main/js/apps/account/app.js
server/sonar-web/src/main/js/apps/account/templates/account-tokens.hbs [new file with mode: 0644]
server/sonar-web/src/main/js/apps/account/tokens-view.js [new file with mode: 0644]
server/sonar-web/src/main/webapp/WEB-INF/app/views/account/index.html.erb

index ace384412e046ca09bd524a7e5c32235eb286730..f2f87052d5e84ef4687b63d465879d8c09abc5ed 100644 (file)
@@ -18,7 +18,9 @@
  * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
  */
 import $ from 'jquery';
+import Backbone from 'backbone';
 import ChangePasswordView from './change-password-view';
+import TokensView from './tokens-view';
 import avatarHelper from '../../helpers/handlebars/avatarHelper';
 
 var shouldShowAvatars = window.SS && window.SS.lf && window.SS.lf.enableGravatar;
@@ -47,6 +49,15 @@ class App {
       e.preventDefault();
       new ChangePasswordView().render();
     });
+
+    const account = new Backbone.Model({
+      id: window.SS.user
+    });
+
+    new TokensView({
+      el: '#account-tokens',
+      model: account
+    }).render();
   }
 }
 
diff --git a/server/sonar-web/src/main/js/apps/account/templates/account-tokens.hbs b/server/sonar-web/src/main/js/apps/account/templates/account-tokens.hbs
new file mode 100644 (file)
index 0000000..3b0d29d
--- /dev/null
@@ -0,0 +1,75 @@
+<h2 class="spacer-bottom">Tokens</h2>
+
+{{#notNull tokens}}
+  <div class="abs-width-400">
+    <table class="data">
+      <thead>
+      <tr>
+        <th>Name</th>
+        <th class="text-right">Created</th>
+        <th>&nbsp;</th>
+      </tr>
+      </thead>
+      <tbody>
+      {{#each tokens}}
+        <tr>
+          <td>
+            {{name}}
+          </td>
+          <td class="thin nowrap text-right">
+            {{d createdAt}}
+          </td>
+          <td class="thin nowrap text-right">
+            <div class="big-spacer-left">
+              <form class="js-revoke-token-form" data-token="{{name}}">
+                {{#if deleting}}
+                  <button class="button-red input-small">Sure?</button>
+                {{else}}
+                  <button class="button-red input-small">Revoke</button>
+                {{/if}}
+              </form>
+            </div>
+          </td>
+        </tr>
+      {{else}}
+        <tr>
+          <td colspan="3">
+            <span class="note">No tokens</span>
+          </td>
+        </tr>
+      {{/each}}
+      </tbody>
+    </table>
+  </div>
+{{/notNull}}
+
+<h3 class="big-spacer-top spacer-bottom">Generate Tokens</h3>
+
+{{#each errors}}
+  <div class="alert alert-danger">{{msg}}</div>
+{{/each}}
+
+<form class="js-generate-token-form">
+  <input type="text" required maxlength="30" placeholder="Enter Token Name">
+  <button>Generate</button>
+</form>
+
+{{#if newToken}}
+  <div class="panel panel-white big-spacer-top">
+    <div class="alert alert-warning">
+      Make sure you copy the token now. You won’t be able to see it again!
+    </div>
+
+    <table class="data">
+      <tr>
+
+        <td class="thin">
+          <button class="js-copy-to-clipboard" data-clipboard-text="{{newToken}}">Copy</button>
+        </td>
+        <td class="nowrap">
+          <code class="text-success">{{newToken}}</code>
+        </td>
+      </tr>
+    </table>
+  </div>
+{{/if}}
diff --git a/server/sonar-web/src/main/js/apps/account/tokens-view.js b/server/sonar-web/src/main/js/apps/account/tokens-view.js
new file mode 100644 (file)
index 0000000..55beb56
--- /dev/null
@@ -0,0 +1,105 @@
+/*
+ * SonarQube
+ * Copyright (C) 2009-2016 SonarSource SA
+ * mailto:contact AT sonarsource DOT com
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License as published by the Free Software Foundation; either
+ * version 3 of the License, or (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public License
+ * along with this program; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ */
+import $ from 'jquery';
+import _ from 'underscore';
+import Marionette from 'backbone.marionette';
+import Clipboard from 'clipboard';
+
+import Template from './templates/account-tokens.hbs';
+import { getTokens, generateToken, revokeToken } from '../../api/user-tokens';
+
+
+export default Marionette.ItemView.extend({
+  template: Template,
+
+  events () {
+    return {
+      'submit .js-generate-token-form': 'onGenerateTokenFormSubmit',
+      'submit .js-revoke-token-form': 'onRevokeTokenFormSubmit'
+    };
+  },
+
+  initialize () {
+    this.tokens = null;
+    this.newToken = null;
+    this.errors = [];
+    this.requestTokens();
+  },
+
+  requestTokens () {
+    return getTokens(this.model.id).then(tokens => {
+      this.tokens = tokens;
+      this.render();
+    });
+  },
+
+  onGenerateTokenFormSubmit (e) {
+    e.preventDefault();
+    this.errors = [];
+    this.newToken = null;
+    let tokenName = this.$('.js-generate-token-form input').val();
+    generateToken(this.model.id, tokenName)
+        .then(response => {
+          this.newToken = response.token;
+          this.requestTokens();
+        })
+        .catch(error => {
+          error.response.json().then(response => {
+            this.errors = response.errors;
+            this.render();
+          });
+        });
+  },
+
+  onRevokeTokenFormSubmit(e) {
+    e.preventDefault();
+    let tokenName = $(e.currentTarget).data('token');
+    let token = _.findWhere(this.tokens, { name: `${tokenName}` });
+    if (token) {
+      if (token.deleting) {
+        revokeToken(this.model.id, tokenName).then(this.requestTokens.bind(this));
+      } else {
+        token.deleting = true;
+        this.render();
+      }
+    }
+  },
+
+  onRender () {
+    let copyButton = this.$('.js-copy-to-clipboard');
+    if (copyButton.length) {
+      let clipboard = new Clipboard(copyButton.get(0));
+      clipboard.on('success', () => {
+        copyButton.tooltip({ title: 'Copied!', placement: 'bottom', trigger: 'manual' }).tooltip('show');
+        setTimeout(() => copyButton.tooltip('hide'), 1000);
+      });
+    }
+    this.newToken = null;
+  },
+
+  serializeData() {
+    return _.extend(Marionette.ItemView.prototype.serializeData.apply(this, arguments), {
+      tokens: this.tokens,
+      newToken: this.newToken,
+      errors: this.errors
+    });
+  }
+
+});
index bbc906a0f3d172dd68a94d3100467b75e2852e2d..0c38691c0bf82825524ca96966b634a6c1fd7d5a 100644 (file)
@@ -65,6 +65,8 @@
         <input type="submit" value="<%= message('my_profile.notifications.submit') -%>" name="commit">
       </section>
     </form>
+
+    <section id="account-tokens" class="huge-spacer-top"></section>
   </div>
 </div>