ability to manage user tokens via website

This commit is contained in:
Brad Rydzewski 2015-04-13 16:33:29 -07:00
parent 768b6c7e48
commit 6c3f99065a
7 changed files with 114 additions and 16 deletions

View file

@ -39,13 +39,14 @@ func main() {
user := api.Group("/user") user := api.Group("/user")
{ {
user.Use(server.MustUser()) user.Use(server.MustUser())
user.Use(server.SetSession(session))
user.GET("", server.GetUserCurr) user.GET("", server.GetUserCurr)
user.PUT("", server.PutUserCurr) user.PUT("", server.PutUserCurr)
user.GET("/repos", server.GetUserRepos) user.GET("/repos", server.GetUserRepos)
user.GET("/tokens", server.GetUserTokens) user.GET("/tokens", server.GetUserTokens)
user.POST("/tokens", server.PostToken) user.POST("/tokens", server.PostToken)
user.DELETE("/tokens", server.DelToken) user.DELETE("/tokens/:label", server.DelToken)
} }
users := api.Group("/users") users := api.Group("/users")

View file

@ -30,6 +30,7 @@
<script src="/static/scripts/services/tasks.js"></script> <script src="/static/scripts/services/tasks.js"></script>
<script src="/static/scripts/services/users.js"></script> <script src="/static/scripts/services/users.js"></script>
<script src="/static/scripts/services/logs.js"></script> <script src="/static/scripts/services/logs.js"></script>
<script src="/static/scripts/services/tokens.js"></script>
<script src="/static/scripts/filters/filter.js"></script> <script src="/static/scripts/filters/filter.js"></script>
<script src="/static/scripts/filters/gravatar.js"></script> <script src="/static/scripts/filters/gravatar.js"></script>

View file

@ -3,12 +3,32 @@
/** /**
* UserCtrl is responsible for managing user settings. * UserCtrl is responsible for managing user settings.
*/ */
function UserCtrl($scope, users) { function UserCtrl($scope, users, tokens) {
// Gets the currently authenticated user // Gets the currently authenticated user
users.getCurrent().then(function(payload){ users.getCurrent().then(function(payload){
$scope.user = payload.data; $scope.user = payload.data;
}); });
// Gets the user tokens
tokens.list().then(function(payload){
$scope.tokens = payload.data;
});
$scope.newToken={Label: ""};
$scope.createToken = function(newToken) {
tokens.post(newToken).then(function(payload) {
$scope.tokens.push(payload.data);
$scope.newToken={Label: ""};
});
}
$scope.revokeToken = function(token) {
tokens.delete(token).then(function() {
var index = $scope.tokens.indexOf(token);
$scope.tokens.splice(index, 1);
});
}
} }
/** /**
@ -40,9 +60,8 @@
$scope.remove = function(user) { $scope.remove = function(user) {
users.delete(user).then(function(){ users.delete(user).then(function(){
users.list().then(function(payload){ var index = $scope.users.indexOf(user);
$scope.users = payload.data; $scope.users.splice(index, 1);
});
}); });
} }
} }

View file

@ -0,0 +1,40 @@
'use strict';
(function () {
/**
* The TokenService provides access to user token
* data using REST API calls.
*/
function TokenService($http, $window) {
/**
* Gets a list of all repositories.
*/
this.list = function() {
return $http.get('/api/user/tokens');
};
/**
* Creates a new token.
*
* @param {object} JSON representation of a repository.
*/
this.post = function(token) {
return $http.post('/api/user/tokens', token);
};
/**
* Deletes a repository.
*
* @param {string} Name of the repository.
*/
this.delete = function(token) {
return $http.delete('/api/user/tokens/' + token.label);
};
}
angular
.module('drone')
.service('tokens', TokenService);
})();

View file

@ -23,4 +23,35 @@
<dt>Gravatar</dt> <dt>Gravatar</dt>
<dd><img ng-src="{{ user.gravatar_id | gravatar }}"</dd> <dd><img ng-src="{{ user.gravatar_id | gravatar }}"</dd>
</dl> </dl>
<form>
<input type="label" ng-model="newToken.label" />
<button ng-click="createToken(newToken)">Create</button>
</form>
<div class="alert" ng-if="tokens && tokens.length === 0">No Personal Tokens Exist</div>
<table ng-if="tokens && tokens.length !== 0">
<thead>
<tr>
<th>Label</th>
<th>Issued</th>
<th></th>
</tr>
</thead>
<tbody>
<tr ng-repeat-start="token in tokens">
<td>{{ token.label }}</td>
<td>{{ token.issued_at | fromNow }}</td>
<td><button ng-click="revokeToken(token)">delete</button></td>
</tr>
<tr ng-repeat-end ng-if="token.hash">
<td colspan="3">
<span>Make sure to copy your new personal access token now. You won't be able to see it again!</span>
<pre style="white-space: pre-line;overflow-wrap: break-word;">{{ token.hash }}</pre>
</td>
</tr>
</tbody>
</table>

View file

@ -1,6 +1,8 @@
package server package server
import ( import (
"time"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
"github.com/gin-gonic/gin/binding" "github.com/gin-gonic/gin/binding"
@ -24,6 +26,7 @@ func PostToken(c *gin.Context) {
token.Scopes = in.Scopes token.Scopes = in.Scopes
token.Login = user.Login token.Login = user.Login
token.Kind = common.TokenUser token.Kind = common.TokenUser
token.Issued = time.Now().UTC().Unix()
err := store.InsertToken(token) err := store.InsertToken(token)
if err != nil { if err != nil {
@ -34,10 +37,13 @@ func PostToken(c *gin.Context) {
if err != nil { if err != nil {
c.Fail(400, err) c.Fail(400, err)
} }
c.String(200, jwt) c.JSON(200, struct {
*common.Token
Hash string `json:"hash"`
}{token, jwt})
} }
// DELETE /api/user/tokens // DELETE /api/user/tokens/:label
func DelToken(c *gin.Context) { func DelToken(c *gin.Context) {
store := ToDatastore(c) store := ToDatastore(c)
user := ToUser(c) user := ToUser(c)

View file

@ -65,12 +65,12 @@ func GetUserRepos(c *gin.Context) {
// GET /api/user/tokens // GET /api/user/tokens
// //
func GetUserTokens(c *gin.Context) { func GetUserTokens(c *gin.Context) {
// ds := ToDatastore(c) ds := ToDatastore(c)
// me := ToUser(c) me := ToUser(c)
// tokens, err := ds.GetUserTokens(me.Login) tokens, err := ds.GetUserTokens(me.Login)
// if err != nil { if err != nil {
// c.Fail(400, err) c.Fail(400, err)
// } else { } else {
// c.JSON(200, &repos) c.JSON(200, &tokens)
// } }
} }