Skip to content

Commit 41de7c0

Browse files
committed
Initial commit
1 parent 77d0661 commit 41de7c0

4 files changed

Lines changed: 204 additions & 0 deletions

File tree

APITokens/api/module.php

Lines changed: 83 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,83 @@
1+
<?php namespace pineapple;
2+
3+
require_once('DatabaseConnection.php');
4+
5+
class APITokens extends Module
6+
{
7+
private $dbConnection;
8+
9+
const DATABASE = "/etc/pineapple/nano.db";
10+
11+
public function __construct($request)
12+
{
13+
parent::__construct($request, __CLASS__);
14+
$this->dbConnection = new DatabaseConnection(self::DATABASE);
15+
$this->dbConnection->exec("CREATE TABLE IF NOT EXISTS api_tokens (token VARCHAR NOT NULL, name VARCHAR NOT NULL);");
16+
}
17+
18+
public function getApiTokens()
19+
{
20+
$this->response = array("tokens" => $this->dbConnection->query("SELECT ROWID, token, name FROM api_tokens;"));
21+
}
22+
23+
public function checkApiToken()
24+
{
25+
if (isset($this->request->token)) {
26+
$token = $this->request->token;
27+
$result = $this->dbConnection->query("SELECT token FROM api_tokens WHERE token='%s';", $token);
28+
if (!empty($result) && isset($result[0]["token"]) && $result[0]["token"] === $token) {
29+
$this->response = array("valid" => true);
30+
}
31+
}
32+
$this->response = array("valid" => false);
33+
}
34+
35+
public function addApiToken()
36+
{
37+
if (isset($this->request->name)) {
38+
$token = hash('sha512', openssl_random_pseudo_bytes(32));
39+
$name = $this->request->name;
40+
$this->dbConnection->exec("INSERT INTO api_tokens(token, name) VALUES('%s','%s');", $token, $name);
41+
$this->response = array("success" => true, "token" => $token);
42+
} else {
43+
$this->error = "Missing token name";
44+
}
45+
}
46+
47+
public function revokeApiToken()
48+
{
49+
if (isset($this->request->id)) {
50+
$this->dbConnection->exec("DELETE FROM api_tokens WHERE ROWID='%s'", $this->request->id);
51+
} elseif (isset($this->request->token)) {
52+
$this->dbConnection->exec("DELETE FROM api_tokens WHERE token='%s'", $this->request->token);
53+
} elseif (isset($this->request->name)) {
54+
$this->dbConnection->exec("DELETE FROM api_tokens WHERE name='%s'", $this->request->name);
55+
} else {
56+
$this->error = "The revokeApiToken API call requires either a 'id', 'token', or 'name' parameter";
57+
}
58+
}
59+
60+
public function route()
61+
{
62+
switch ($this->request->action) {
63+
case 'checkApiToken':
64+
$this->checkApiToken();
65+
break;
66+
67+
case 'addApiToken':
68+
$this->addApiToken();
69+
break;
70+
71+
case 'getApiTokens':
72+
$this->getApiTokens();
73+
break;
74+
75+
case 'revokeApiToken':
76+
$this->revokeApiToken();
77+
break;
78+
79+
default:
80+
$this->error = "Unknown action";
81+
}
82+
}
83+
}

APITokens/js/module.js

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
registerController("APITokenController", ['$api', '$scope', function($api, $scope) {
2+
$scope.apiTokens = [];
3+
$scope.newToken = {
4+
name: "",
5+
token: ""
6+
};
7+
8+
$scope.getApiTokens = function(){
9+
$api.request({
10+
'module': 'APITokens',
11+
'action': 'getApiTokens'
12+
}, function(response){
13+
$scope.apiTokens = response.tokens;
14+
console.log(document.getElementById($scope.newToken.token));
15+
});
16+
};
17+
18+
$scope.genApiToken = function(){
19+
$api.request({
20+
'module': 'APITokens',
21+
'action': 'addApiToken',
22+
'name': $scope.newToken.name
23+
}, function(response){
24+
$scope.newToken.name = "";
25+
$scope.newToken.token = response.token;
26+
$scope.getApiTokens();
27+
});
28+
};
29+
30+
$scope.revokeApiToken = function($event){
31+
var id = $event.target.getAttribute('tokenid');
32+
$api.request({
33+
'module': 'APITokens',
34+
'action': 'revokeApiToken',
35+
'id': id
36+
}, function(){
37+
$scope.getApiTokens();
38+
});
39+
};
40+
41+
$scope.selectElem = function(elem){
42+
var selectRange = document.createRange();
43+
selectRange.selectNodeContents(elem);
44+
var selection = window.getSelection();
45+
selection.removeAllRanges();
46+
selection.addRange(selectRange);
47+
}
48+
49+
$scope.selectOnClick = function($event){
50+
var elem = $event.target;
51+
$scope.selectElem(elem);
52+
};
53+
54+
$scope.getApiTokens();
55+
}]);

APITokens/module.html

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<style type="text/css">
2+
.panel {
3+
width: 90%;
4+
float:right;
5+
margin-right: 5%;
6+
}
7+
.table {
8+
table-layout:fixed;
9+
}
10+
.table td {
11+
white-space: nowrap;
12+
overflow: scroll;
13+
text-overflow: ellipsis
14+
}
15+
</style>
16+
<div class="row" ng-controller="APITokenController">
17+
<div class="panel panel-default">
18+
<div class="panel-heading">
19+
<h3 class="panel-title">
20+
Manage API Tokens
21+
<span class="pull-right"><button class="btn btn-primary" style="padding: 0px 5px;" ng-click="getApiTokens();">Refresh</button></span>
22+
</h3>
23+
</div>
24+
<table class="table table-hover table-responsive table-condensed" ng-show="apiTokens.length">
25+
<thead>
26+
<th>ID</th>
27+
<th>Name</th>
28+
<th>Token</th>
29+
</thead>
30+
<tbody>
31+
<tr ng-repeat="apiToken in apiTokens">
32+
<td class="col-md-1">{{ apiToken.rowid }}</td>
33+
<td class="col-md-3">{{ apiToken.name }}</td>
34+
<td class="col-md-5 token" ng-click="selectOnClick($event);">{{ apiToken.token }}</td>
35+
<td class="col-md-3"><span class="pull-right"><button tokenid="{{ apiToken.rowid }}" class="btn btn-danger btn-sm" ng-click="revokeApiToken($event);">Revoke</button></span></td>
36+
</tr>
37+
</tbody>
38+
</table>
39+
40+
<div class="panel-body" ng-hide="apiTokens.length">
41+
<center><i>No API Tokens</i></center>
42+
</div>
43+
44+
</div>
45+
<div class="panel panel-default">
46+
<div class="panel-heading">
47+
<h3 class="panel-title">
48+
Generate New Token
49+
</h3>
50+
</div>
51+
<div class="panel-body">
52+
<form class="form-inline" role="form" ng-submit="genApiToken()" novalidate>
53+
<div class="form-group">
54+
<label for="tokenName">Token Name:</label>
55+
<input name="tokenName" type="text" class="form-control" id="tokenName" ng-model="newToken.name" autofocus>
56+
</div>
57+
<button type="submit" class="btn btn-success" ng-click="console.log(0);">Generate</button>
58+
</form>
59+
</div>
60+
</div>
61+
</div>

APITokens/module.info

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
{
2+
"title": "APITokens",
3+
"version": "1.1",
4+
"author": "Tesla"
5+
}

0 commit comments

Comments
 (0)