ability to manage user tokens via website
This commit is contained in:
parent
768b6c7e48
commit
6c3f99065a
7 changed files with 114 additions and 16 deletions
3
drone.go
3
drone.go
|
@ -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")
|
||||||
|
|
|
@ -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>
|
||||||
|
|
|
@ -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);
|
||||||
});
|
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
40
server/static/scripts/services/tokens.js
Normal file
40
server/static/scripts/services/tokens.js
Normal 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);
|
||||||
|
})();
|
|
@ -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>
|
|
@ -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)
|
||||||
|
|
|
@ -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)
|
||||||
// }
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue