Browse Source

Initial drop

Bernhard Fröhlich 1 year ago
parent
commit
beefe3cfab

+ 1
- 1
LICENSE View File

@@ -1,6 +1,6 @@
1 1
 BSD 2-Clause License
2 2
 
3
-Copyright (c) 2017, Bernhard Fröhlich
3
+Copyright (c) 2017, Bernhard Foehlich <decke@bluelife.at>
4 4
 All rights reserved.
5 5
 
6 6
 Redistribution and use in source and binary forms, with or without

+ 35
- 0
README.md View File

@@ -1,2 +1,37 @@
1 1
 # nodeman
2 2
 FunkFeuer Node Manager
3
+
4
+## Setup
5
+
6
+Nodeman is using composer for the PHP dependencies so they
7
+need to be downloaded and installed first.
8
+
9
+<code>
10
+composer install
11
+</code>
12
+
13
+Then we also need to create the SQLite Database tables and
14
+add some configuration.
15
+
16
+<code>
17
+sqlite share/nodeman.db
18
+> .read share/schema.sql
19
+> .q
20
+</code>
21
+
22
+
23
+For testing and development you can use the builtin php
24
+webserver but beware it's not safe because anybody could
25
+access your sqlite databse.
26
+
27
+<code>
28
+php -S localhost:80
29
+</code>
30
+
31
+For a production system please use nginx and the example
32
+config in `share/nodeman.conf`.
33
+
34
+
35
+Then you can access nodeman via `http://localhost/` and login
36
+as user `admin` with password `admin`.
37
+

+ 18
- 0
composer.json View File

@@ -0,0 +1,18 @@
1
+{
2
+   "name": "ffgraz/nodeman",
3
+   "description": "FunkFeuer Node Manager",
4
+   "homepage": "https://github.com/decke/nodeman",
5
+   "license": "BSD-2-Clause",
6
+   "require": {
7
+      "slim/slim": "^3.0",
8
+      "slim/flash": "^0.2.0",
9
+      "slim/php-view": "~2.0",
10
+      "php": ">=5.5.0"
11
+   },
12
+   "autoload": {
13
+      "psr-0": {
14
+         "FunkFeuer": "lib"
15
+      },
16
+      "files": ["lib/functions.php"]
17
+   }
18
+}

+ 411
- 0
composer.lock View File

@@ -0,0 +1,411 @@
1
+{
2
+    "_readme": [
3
+        "This file locks the dependencies of your project to a known state",
4
+        "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5
+        "This file is @generated automatically"
6
+    ],
7
+    "content-hash": "bf8b1548b18b7e6051fd4442624c8ea8",
8
+    "packages": [
9
+        {
10
+            "name": "container-interop/container-interop",
11
+            "version": "1.2.0",
12
+            "source": {
13
+                "type": "git",
14
+                "url": "https://github.com/container-interop/container-interop.git",
15
+                "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8"
16
+            },
17
+            "dist": {
18
+                "type": "zip",
19
+                "url": "https://api.github.com/repos/container-interop/container-interop/zipball/79cbf1341c22ec75643d841642dd5d6acd83bdb8",
20
+                "reference": "79cbf1341c22ec75643d841642dd5d6acd83bdb8",
21
+                "shasum": ""
22
+            },
23
+            "require": {
24
+                "psr/container": "^1.0"
25
+            },
26
+            "type": "library",
27
+            "autoload": {
28
+                "psr-4": {
29
+                    "Interop\\Container\\": "src/Interop/Container/"
30
+                }
31
+            },
32
+            "notification-url": "https://packagist.org/downloads/",
33
+            "license": [
34
+                "MIT"
35
+            ],
36
+            "description": "Promoting the interoperability of container objects (DIC, SL, etc.)",
37
+            "homepage": "https://github.com/container-interop/container-interop",
38
+            "time": "2017-02-14T19:40:03+00:00"
39
+        },
40
+        {
41
+            "name": "nikic/fast-route",
42
+            "version": "v1.2.0",
43
+            "source": {
44
+                "type": "git",
45
+                "url": "https://github.com/nikic/FastRoute.git",
46
+                "reference": "b5f95749071c82a8e0f58586987627054400cdf6"
47
+            },
48
+            "dist": {
49
+                "type": "zip",
50
+                "url": "https://api.github.com/repos/nikic/FastRoute/zipball/b5f95749071c82a8e0f58586987627054400cdf6",
51
+                "reference": "b5f95749071c82a8e0f58586987627054400cdf6",
52
+                "shasum": ""
53
+            },
54
+            "require": {
55
+                "php": ">=5.4.0"
56
+            },
57
+            "type": "library",
58
+            "autoload": {
59
+                "psr-4": {
60
+                    "FastRoute\\": "src/"
61
+                },
62
+                "files": [
63
+                    "src/functions.php"
64
+                ]
65
+            },
66
+            "notification-url": "https://packagist.org/downloads/",
67
+            "license": [
68
+                "BSD-3-Clause"
69
+            ],
70
+            "authors": [
71
+                {
72
+                    "name": "Nikita Popov",
73
+                    "email": "nikic@php.net"
74
+                }
75
+            ],
76
+            "description": "Fast request router for PHP",
77
+            "keywords": [
78
+                "router",
79
+                "routing"
80
+            ],
81
+            "time": "2017-01-19T11:35:12+00:00"
82
+        },
83
+        {
84
+            "name": "pimple/pimple",
85
+            "version": "v3.2.2",
86
+            "source": {
87
+                "type": "git",
88
+                "url": "https://github.com/silexphp/Pimple.git",
89
+                "reference": "4d45fb62d96418396ec58ba76e6f065bca16e10a"
90
+            },
91
+            "dist": {
92
+                "type": "zip",
93
+                "url": "https://api.github.com/repos/silexphp/Pimple/zipball/4d45fb62d96418396ec58ba76e6f065bca16e10a",
94
+                "reference": "4d45fb62d96418396ec58ba76e6f065bca16e10a",
95
+                "shasum": ""
96
+            },
97
+            "require": {
98
+                "php": ">=5.3.0",
99
+                "psr/container": "^1.0"
100
+            },
101
+            "require-dev": {
102
+                "symfony/phpunit-bridge": "^3.2"
103
+            },
104
+            "type": "library",
105
+            "extra": {
106
+                "branch-alias": {
107
+                    "dev-master": "3.2.x-dev"
108
+                }
109
+            },
110
+            "autoload": {
111
+                "psr-0": {
112
+                    "Pimple": "src/"
113
+                }
114
+            },
115
+            "notification-url": "https://packagist.org/downloads/",
116
+            "license": [
117
+                "MIT"
118
+            ],
119
+            "authors": [
120
+                {
121
+                    "name": "Fabien Potencier",
122
+                    "email": "fabien@symfony.com"
123
+                }
124
+            ],
125
+            "description": "Pimple, a simple Dependency Injection Container",
126
+            "homepage": "http://pimple.sensiolabs.org",
127
+            "keywords": [
128
+                "container",
129
+                "dependency injection"
130
+            ],
131
+            "time": "2017-07-23T07:32:15+00:00"
132
+        },
133
+        {
134
+            "name": "psr/container",
135
+            "version": "1.0.0",
136
+            "source": {
137
+                "type": "git",
138
+                "url": "https://github.com/php-fig/container.git",
139
+                "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f"
140
+            },
141
+            "dist": {
142
+                "type": "zip",
143
+                "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
144
+                "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f",
145
+                "shasum": ""
146
+            },
147
+            "require": {
148
+                "php": ">=5.3.0"
149
+            },
150
+            "type": "library",
151
+            "extra": {
152
+                "branch-alias": {
153
+                    "dev-master": "1.0.x-dev"
154
+                }
155
+            },
156
+            "autoload": {
157
+                "psr-4": {
158
+                    "Psr\\Container\\": "src/"
159
+                }
160
+            },
161
+            "notification-url": "https://packagist.org/downloads/",
162
+            "license": [
163
+                "MIT"
164
+            ],
165
+            "authors": [
166
+                {
167
+                    "name": "PHP-FIG",
168
+                    "homepage": "http://www.php-fig.org/"
169
+                }
170
+            ],
171
+            "description": "Common Container Interface (PHP FIG PSR-11)",
172
+            "homepage": "https://github.com/php-fig/container",
173
+            "keywords": [
174
+                "PSR-11",
175
+                "container",
176
+                "container-interface",
177
+                "container-interop",
178
+                "psr"
179
+            ],
180
+            "time": "2017-02-14T16:28:37+00:00"
181
+        },
182
+        {
183
+            "name": "psr/http-message",
184
+            "version": "1.0.1",
185
+            "source": {
186
+                "type": "git",
187
+                "url": "https://github.com/php-fig/http-message.git",
188
+                "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363"
189
+            },
190
+            "dist": {
191
+                "type": "zip",
192
+                "url": "https://api.github.com/repos/php-fig/http-message/zipball/f6561bf28d520154e4b0ec72be95418abe6d9363",
193
+                "reference": "f6561bf28d520154e4b0ec72be95418abe6d9363",
194
+                "shasum": ""
195
+            },
196
+            "require": {
197
+                "php": ">=5.3.0"
198
+            },
199
+            "type": "library",
200
+            "extra": {
201
+                "branch-alias": {
202
+                    "dev-master": "1.0.x-dev"
203
+                }
204
+            },
205
+            "autoload": {
206
+                "psr-4": {
207
+                    "Psr\\Http\\Message\\": "src/"
208
+                }
209
+            },
210
+            "notification-url": "https://packagist.org/downloads/",
211
+            "license": [
212
+                "MIT"
213
+            ],
214
+            "authors": [
215
+                {
216
+                    "name": "PHP-FIG",
217
+                    "homepage": "http://www.php-fig.org/"
218
+                }
219
+            ],
220
+            "description": "Common interface for HTTP messages",
221
+            "homepage": "https://github.com/php-fig/http-message",
222
+            "keywords": [
223
+                "http",
224
+                "http-message",
225
+                "psr",
226
+                "psr-7",
227
+                "request",
228
+                "response"
229
+            ],
230
+            "time": "2016-08-06T14:39:51+00:00"
231
+        },
232
+        {
233
+            "name": "slim/flash",
234
+            "version": "0.2.0",
235
+            "source": {
236
+                "type": "git",
237
+                "url": "https://github.com/slimphp/Slim-Flash.git",
238
+                "reference": "3c9a26b3163820acc48080336c504d0a3cac6f30"
239
+            },
240
+            "dist": {
241
+                "type": "zip",
242
+                "url": "https://api.github.com/repos/slimphp/Slim-Flash/zipball/3c9a26b3163820acc48080336c504d0a3cac6f30",
243
+                "reference": "3c9a26b3163820acc48080336c504d0a3cac6f30",
244
+                "shasum": ""
245
+            },
246
+            "require": {
247
+                "php": ">=5.5.0"
248
+            },
249
+            "require-dev": {
250
+                "phpunit/phpunit": "^4.0"
251
+            },
252
+            "type": "library",
253
+            "autoload": {
254
+                "psr-4": {
255
+                    "Slim\\Flash\\": "src"
256
+                }
257
+            },
258
+            "notification-url": "https://packagist.org/downloads/",
259
+            "license": [
260
+                "MIT"
261
+            ],
262
+            "authors": [
263
+                {
264
+                    "name": "Josh Lockhart",
265
+                    "email": "hello@joshlockhart.com",
266
+                    "homepage": "http://joshlockhart.com"
267
+                }
268
+            ],
269
+            "description": "Slim Framework Flash message service provider",
270
+            "homepage": "http://slimframework.com",
271
+            "keywords": [
272
+                "flash",
273
+                "framework",
274
+                "message",
275
+                "provider",
276
+                "slim"
277
+            ],
278
+            "time": "2016-11-11T16:29:19+00:00"
279
+        },
280
+        {
281
+            "name": "slim/php-view",
282
+            "version": "2.2.0",
283
+            "source": {
284
+                "type": "git",
285
+                "url": "https://github.com/slimphp/PHP-View.git",
286
+                "reference": "122ed121a8d9cf91a94020814d2a3ee6c836754f"
287
+            },
288
+            "dist": {
289
+                "type": "zip",
290
+                "url": "https://api.github.com/repos/slimphp/PHP-View/zipball/122ed121a8d9cf91a94020814d2a3ee6c836754f",
291
+                "reference": "122ed121a8d9cf91a94020814d2a3ee6c836754f",
292
+                "shasum": ""
293
+            },
294
+            "require": {
295
+                "psr/http-message": "^1.0"
296
+            },
297
+            "require-dev": {
298
+                "phpunit/phpunit": "^4.8",
299
+                "slim/slim": "^3.0"
300
+            },
301
+            "type": "library",
302
+            "autoload": {
303
+                "psr-4": {
304
+                    "Slim\\Views\\": "src"
305
+                }
306
+            },
307
+            "notification-url": "https://packagist.org/downloads/",
308
+            "license": [
309
+                "MIT"
310
+            ],
311
+            "authors": [
312
+                {
313
+                    "name": "Glenn Eggleton",
314
+                    "email": "geggleto@gmail.com"
315
+                }
316
+            ],
317
+            "description": "Render PHP view scripts into a PSR-7 Response object.",
318
+            "keywords": [
319
+                "framework",
320
+                "php",
321
+                "phtml",
322
+                "renderer",
323
+                "slim",
324
+                "template",
325
+                "view"
326
+            ],
327
+            "time": "2016-10-11T07:43:08+00:00"
328
+        },
329
+        {
330
+            "name": "slim/slim",
331
+            "version": "3.8.1",
332
+            "source": {
333
+                "type": "git",
334
+                "url": "https://github.com/slimphp/Slim.git",
335
+                "reference": "5385302707530b2bccee1769613ad769859b826d"
336
+            },
337
+            "dist": {
338
+                "type": "zip",
339
+                "url": "https://api.github.com/repos/slimphp/Slim/zipball/5385302707530b2bccee1769613ad769859b826d",
340
+                "reference": "5385302707530b2bccee1769613ad769859b826d",
341
+                "shasum": ""
342
+            },
343
+            "require": {
344
+                "container-interop/container-interop": "^1.2",
345
+                "nikic/fast-route": "^1.0",
346
+                "php": ">=5.5.0",
347
+                "pimple/pimple": "^3.0",
348
+                "psr/container": "^1.0",
349
+                "psr/http-message": "^1.0"
350
+            },
351
+            "provide": {
352
+                "psr/http-message-implementation": "1.0"
353
+            },
354
+            "require-dev": {
355
+                "phpunit/phpunit": "^4.0",
356
+                "squizlabs/php_codesniffer": "^2.5"
357
+            },
358
+            "type": "library",
359
+            "autoload": {
360
+                "psr-4": {
361
+                    "Slim\\": "Slim"
362
+                }
363
+            },
364
+            "notification-url": "https://packagist.org/downloads/",
365
+            "license": [
366
+                "MIT"
367
+            ],
368
+            "authors": [
369
+                {
370
+                    "name": "Rob Allen",
371
+                    "email": "rob@akrabat.com",
372
+                    "homepage": "http://akrabat.com"
373
+                },
374
+                {
375
+                    "name": "Josh Lockhart",
376
+                    "email": "hello@joshlockhart.com",
377
+                    "homepage": "https://joshlockhart.com"
378
+                },
379
+                {
380
+                    "name": "Gabriel Manricks",
381
+                    "email": "gmanricks@me.com",
382
+                    "homepage": "http://gabrielmanricks.com"
383
+                },
384
+                {
385
+                    "name": "Andrew Smith",
386
+                    "email": "a.smith@silentworks.co.uk",
387
+                    "homepage": "http://silentworks.co.uk"
388
+                }
389
+            ],
390
+            "description": "Slim is a PHP micro framework that helps you quickly write simple yet powerful web applications and APIs",
391
+            "homepage": "https://slimframework.com",
392
+            "keywords": [
393
+                "api",
394
+                "framework",
395
+                "micro",
396
+                "router"
397
+            ],
398
+            "time": "2017-03-19T17:55:20+00:00"
399
+        }
400
+    ],
401
+    "packages-dev": [],
402
+    "aliases": [],
403
+    "minimum-stability": "stable",
404
+    "stability-flags": [],
405
+    "prefer-stable": false,
406
+    "prefer-lowest": false,
407
+    "platform": {
408
+        "php": ">=5.5.0"
409
+    },
410
+    "platform-dev": []
411
+}

+ 7
- 0
css/bootstrap.min.css
File diff suppressed because it is too large
View File


+ 4
- 0
css/custom.css View File

@@ -0,0 +1,4 @@
1
+body {
2
+  padding-top: 5rem;
3
+}
4
+

+ 59
- 0
index.php View File

@@ -0,0 +1,59 @@
1
+<?php
2
+
3
+/**
4
+ * FunkFeuer Node Manager
5
+ *
6
+ * @author     Bernhard Froehlich <decke@bluelife.at>
7
+ * @copyright  2017 Bernhard Froehlich
8
+ * @license    BSD License (2 Clause)
9
+ *
10
+ * @link       https://github.com/decke/nodeman
11
+ */
12
+namespace FunkFeuer\Nodeman;
13
+
14
+require_once __DIR__.'/vendor/autoload.php';
15
+
16
+$session = new Session();
17
+
18
+$app = new \Slim\App();
19
+
20
+/* init php-view */
21
+$container = $app->getContainer();
22
+$container['view'] = function($container) use ($session) {
23
+    $renderer = new \Slim\Views\PhpRenderer(__DIR__.'/templates/');
24
+    $renderer->addAttribute('session', $session);
25
+    $renderer->addAttribute('config', new \FunkFeuer\Nodeman\Config());
26
+    $renderer->addAttribute('flash', new \Slim\Flash\Messages());
27
+
28
+    return $renderer;
29
+};
30
+
31
+/* init flash messages */
32
+$container['flash'] = function() {
33
+    return new \Slim\Flash\Messages();
34
+};
35
+
36
+
37
+/* landing page */
38
+$app->get('/', function($request, $response) {
39
+    return $this->view->render($response, 'index.html');
40
+});
41
+
42
+/* Authentication - Login */
43
+$app->post('/login', function($request, $response) use ($session) {
44
+    if (!$request->getParam('username') || !$request->getParam('password')) {
45
+        $this->flash->addMessage('error', 'Authentication failed');
46
+    }
47
+    elseif (!$session->login($request->getParam('username'), $request->getParam('password'))) {
48
+        $this->flash->addMessage('error', 'Authentication failed');
49
+    }
50
+
51
+    return $response->withStatus(302)->withHeader('Location', '/');
52
+});
53
+
54
+$app->get('/logout', function($request, $response, $args) use ($session) {
55
+    $session->logout();
56
+    return $response->withStatus(302)->withHeader('Location', '/');
57
+});
58
+
59
+$app->run();

+ 6
- 0
js/bootstrap.min.js
File diff suppressed because it is too large
View File


+ 4
- 0
js/jquery.slim.min.js
File diff suppressed because it is too large
View File


+ 5
- 0
js/popper.min.js
File diff suppressed because it is too large
View File


+ 84
- 0
lib/FunkFeuer/Nodeman/Config.php View File

@@ -0,0 +1,84 @@
1
+<?php
2
+
3
+namespace FunkFeuer\Nodeman;
4
+
5
+/**
6
+ * Configuration class to store various static settings.
7
+ *
8
+ * @author     Bernhard Froehlich <decke@bluelife.at>
9
+ * @copyright  2017 Bernhard Froehlich         
10
+ * @license    BSD License (2 Clause)
11
+ *
12
+ * @link       https://github.com/decke/nodeman
13
+ */
14
+class Config
15
+{
16
+    protected static $datasource = 'sqlite:share/nodeman.db';
17
+    protected static $handle = null;
18
+
19
+    public static function getDataSource()
20
+    {
21
+        return self::$datasource;
22
+    }
23
+
24
+    public static function getDbHandle()
25
+    {
26
+        if(self::$handle === null)
27
+            self::$handle = new \PDO(self::$datasource);
28
+
29
+        return self::$handle;
30
+    }
31
+
32
+    public static function exists($property)
33
+    {
34
+        $handle = self::getDbHandle();
35
+
36
+        $stmt = $handle->prepare("SELECT name, value FROM config WHERE name = ?");
37
+        if(!$stmt) {
38
+            return false;
39
+        }
40
+
41
+        if(!$stmt->execute(array(strtolower($property)))) {
42
+            return false;
43
+        }
44
+
45
+        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
46
+        if(!is_array($row))
47
+            return false;
48
+
49
+        return true;
50
+    }
51
+
52
+    public static function get($property)
53
+    {
54
+        $handle = self::getDbHandle();
55
+
56
+        $stmt = $handle->prepare("SELECT name, value FROM config WHERE name = ?");
57
+        if(!$stmt) {
58
+            return false;
59
+        }
60
+
61
+        if(!$stmt->execute(array(strtolower($property)))) {
62
+            throw new \Exception('Could not find config property '.$property);
63
+        }
64
+
65
+        $row = $stmt->fetch(\PDO::FETCH_ASSOC);
66
+        if(!is_array($row)) {
67
+            throw new \Exception('Could not find config property '.$property);
68
+        }
69
+
70
+        return $row['value'];
71
+    }
72
+
73
+    public static function set($property, $value)
74
+    {
75
+        $handle = self::getDbHandle();
76
+
77
+        if(!self::exists($property))
78
+            return false;
79
+
80
+        $stmt = $handle->prepare("UPDATE config SET value = ? WHERE name = ?");
81
+
82
+        return $stmt->execute(array($value, strtolower($property)));
83
+    }
84
+}

+ 99
- 0
lib/FunkFeuer/Nodeman/Session.php View File

@@ -0,0 +1,99 @@
1
+<?php
2
+
3
+namespace FunkFeuer\Nodeman;
4
+
5
+/**
6
+ * Manage PHP sessions and authenticate users.
7
+ *
8
+ * @author     Bernhard Froehlich <decke@bluelife.at>
9
+ * @copyright  2017 Bernhard Froehlich
10
+ * @license    BSD License (2 Clause)
11
+ *
12
+ * @link       https://github.com/decke/nodeman
13
+ */
14
+class Session
15
+{
16
+    public function __construct()
17
+    {
18
+        self::initialize();
19
+
20
+        session_start();
21
+    }
22
+
23
+    public static function initialize()
24
+    {
25
+        // do not expose Cookie value to JavaScript (enforced by browser)
26
+        ini_set('session.cookie_httponly', 1);
27
+
28
+        if (Config::get('security.https_only') === true) {
29
+            // only send cookie over https
30
+            ini_set('session.cookie_secure', 1);
31
+        }
32
+
33
+        // prevent caching by sending no-cache header
34
+        session_cache_limiter('nocache');
35
+
36
+        // rename session
37
+        session_name('SESSIONID');
38
+    }
39
+
40
+    public static function getSessionId()
41
+    {
42
+        return session_id();
43
+    }
44
+
45
+    public static function login($username, $password)
46
+    {
47
+        $user = new User($username);
48
+
49
+        if(!$user->checkPassword($password)) {
50
+            return false;
51
+        }
52
+
53
+        /* login assumed to be successfull */
54
+        $_SESSION['authenticated'] = true;
55
+        $_SESSION['username'] = $username;
56
+        $_SESSION['loginip'] = $_SERVER['REMOTE_ADDR'];
57
+
58
+        return true;
59
+    }
60
+
61
+    public static function getUsername()
62
+    {
63
+        if (isset($_SESSION['username'])) {
64
+            return $_SESSION['username'];
65
+        }
66
+
67
+        return false;
68
+    }
69
+
70
+    public static function getUser()
71
+    {
72
+        if(self::isAuthenticated()) {
73
+            return new User(self::getUsername());
74
+        }
75
+
76
+        return false;
77
+    }
78
+
79
+    public static function isAuthenticated()
80
+    {
81
+        return isset($_SESSION['authenticated']);
82
+    }
83
+
84
+    public static function logout()
85
+    {
86
+        $_SESSION = array();
87
+
88
+        /* also destroy session cookie on client */
89
+        $params = session_get_cookie_params();
90
+        setcookie(session_name(), '', time() - 42000,
91
+            $params['path'], $params['domain'],
92
+            $params['secure'], $params['httponly']
93
+        );
94
+
95
+        session_destroy();
96
+
97
+        return true;
98
+    }
99
+}

+ 104
- 0
lib/FunkFeuer/Nodeman/User.php View File

@@ -0,0 +1,104 @@
1
+<?php
2
+
3
+namespace FunkFeuer\Nodeman;
4
+
5
+/**
6
+ * User class for registered users
7
+ *
8
+ * @author     Bernhard Froehlich <decke@bluelife.at>
9
+ * @copyright  2017 Bernhard Froehlich
10
+ * @license    BSD License (2 Clause)
11
+ *
12
+ * @link       https://github.com/decke/nodeman
13
+ */
14
+class User
15
+{
16
+    private $_handle;
17
+    private $_data = array(
18
+        'userid'   => null,
19
+        'username' => null,
20
+        'password' => null,
21
+        'email'    => null,
22
+        'phone'    => null
23
+    );
24
+
25
+    public function __construct($username = null)
26
+    {
27
+        $this->_handle = Config::getDbHandle();
28
+
29
+        if($username !== null) {
30
+            $this->load($username);
31
+        }
32
+    }
33
+
34
+    public function __get($name)
35
+    {
36
+        if(isset($this->_data[$name])) {
37
+            return $this->_data[$name];
38
+        }
39
+
40
+        throw new Exception('Undefined property '.$name.' in class User');
41
+    }
42
+
43
+    public function __set($name, $value)
44
+    {
45
+        if($name == 'password') {
46
+            return $this->setPassword($value);
47
+        }
48
+
49
+        if(isset($this->_data[$name])) {
50
+            $this->_data[$name] = $value;
51
+            return true;
52
+        }
53
+
54
+        throw new Exception('Undefined property '.$name.' in class User');
55
+    }
56
+
57
+    public function setPassword($password)
58
+    {
59
+        $this->_data['password'] = password_hash($password, PASSWORD_DEFAULT, array('cost' => 11));
60
+        return true;
61
+    }
62
+
63
+    public function checkPassword($password)
64
+    {
65
+        return password_verify($password, $this->password);
66
+    }
67
+
68
+    public function load($username)
69
+    {
70
+        $stmt = $this->_handle->prepare("SELECT userid, username, password, email, phone FROM users WHERE username = ?");
71
+        if(!$stmt->execute(array($username)))
72
+            return false;
73
+
74
+        while($row = $stmt->fetch(\PDO::FETCH_ASSOC)) {
75
+            $this->_data = $row;
76
+
77
+            return true;
78
+        }
79
+
80
+        return false;
81
+    }
82
+
83
+    public function save()
84
+    {
85
+        if(!$this->userid)
86
+        {
87
+            $stmt = $this->_handle->prepare("INSERT INTO users (username, password, email, phone) VALUES (?, ?, ?, ?)");
88
+
89
+            if($stmt->execute(array($this->username, $this->password, $this->email, $this->phone)))
90
+            {
91
+                $this->userid = $this->_handle->lastInsertId();
92
+                return true;
93
+            }
94
+        }
95
+        else
96
+        {
97
+            $stmt = $this->_handle->prepare("UPDATE users SET username = ?, password = ?, email = ?, phone = ? WHERE userid = ?");
98
+
99
+            return $stmt->execute(array($this->username, $this->password, $this->email, $this->phone, $this->userid));
100
+        }
101
+
102
+        return false;
103
+    }
104
+}

+ 42
- 0
lib/functions.php View File

@@ -0,0 +1,42 @@
1
+<?php
2
+/**
3
+ * Various functions.
4
+ *
5
+ * @author     Bernhard Froehlich <decke@bluelife.at>
6
+ * @copyright  2017 Bernhard Froehlich
7
+ * @license    BSD License (2 Clause)
8
+ *
9
+ * @link       https://github.com/decke/nodeman
10
+ */
11
+
12
+function checkDbSchema($handle)
13
+{
14
+}
15
+
16
+function jsonResponse($code, $data = array())
17
+{
18
+    $app = \Slim\Slim::getInstance();
19
+    $app->response->setStatus($code);
20
+    $app->response->headers->set('Content-Type', 'application/json');
21
+    $app->response->write(json_encode($data));
22
+
23
+    if ($code != 200) {
24
+        $app->stop();
25
+    }
26
+
27
+    return true;
28
+}
29
+
30
+function textResponse($code, $data = '')
31
+{
32
+    $app = \Slim\Slim::getInstance();
33
+    $app->response->setStatus($code);
34
+    $app->response->headers->set('Content-Type', 'text/plain');
35
+    $app->response->write($data);
36
+
37
+    if ($code != 200) {
38
+        $app->stop();
39
+    }
40
+
41
+    return true;
42
+}

+ 45
- 0
share/nodeman.conf View File

@@ -0,0 +1,45 @@
1
+#
2
+# Example nodeman config for Nginx
3
+#
4
+
5
+server {
6
+    listen       80 default_server;
7
+    server_name  _;
8
+    root         /usr/local/www/nodeman;
9
+    try_files    $uri /index.php?$query_string;
10
+
11
+    gzip on;
12
+    gzip_types text/plain;
13
+
14
+    # block access to our data
15
+    location ^~ /share/ {
16
+        return 403;
17
+    }
18
+
19
+    # block access to our code
20
+    location ^~ /lib/ {
21
+        return 403;
22
+    }
23
+  
24
+    # block access to our code
25
+    location ^~ /templates/ {
26
+        return 403;
27
+    }
28
+   
29
+    # block access to our dependencies
30
+    location ^~ /vendor/ {
31
+        return 403;
32
+    }
33
+     
34
+    # this will only pass index.php to the fastcgi process which is
35
+    # generally safer but assumes the whole site is run via Slim.
36
+    location /index.php {
37
+        fastcgi_pass    unix:/var/run/php-fpm.sock;
38
+        fastcgi_index   index.php;
39
+        fastcgi_connect_timeout 10s;
40
+        fastcgi_read_timeout 120s;
41
+        fastcgi_param  SCRIPT_FILENAME  $document_root$fastcgi_script_name;
42
+        include fastcgi_params;
43
+    }
44
+}
45
+

+ 41
- 0
share/schema.sql View File

@@ -0,0 +1,41 @@
1
+--- FunkFeuer nodeman database
2
+---
3
+--- Create the initial database:
4
+---    sqlite3 nodeman.db
5
+---    > .read schema.sql
6
+---    > .q
7
+
8
+BEGIN TRANSACTION;
9
+
10
+CREATE TABLE config (
11
+   name CHAR(50) NOT NULL,
12
+   value CHAR(50) NOT NULL
13
+);
14
+
15
+CREATE INDEX config_idx1 ON config (name);
16
+
17
+CREATE TABLE users (
18
+   userid INTEGER PRIMARY KEY NOT NULL,
19
+   username CHAR(50) NOT NULL,
20
+   password CHAR(255) NOT NULL,
21
+   email CHAR(255) NOT NULL,
22
+   phone CHAR(50) NOT NULL
23
+);
24
+
25
+CREATE INDEX users_idx1 ON users (username);
26
+
27
+
28
+---
29
+--- INITIAL DATA
30
+---
31
+
32
+INSERT INTO "config" VALUES('schemaversion','0');
33
+INSERT INTO "config" VALUES('security.https_only','false');
34
+INSERT INTO "config" VALUES('title','FunkFeuer Graz');
35
+INSERT INTO "config" VALUES('title.url','https://graz.funkfeuer.at/');
36
+
37
+--- default account
38
+--- username: admin, password: admin
39
+INSERT INTO "users" VALUES(1,'admin','$2y$11$mHyBgtw2Iu0JuUpAvr.ChekNkRZMsLzmoH0/rJJQUYxEJjii.CFjS','noreply@example.com','');
40
+
41
+COMMIT;

+ 7
- 0
templates/_footer.html View File

@@ -0,0 +1,7 @@
1
+  
2
+    <!-- optional JavaScript for Bootstrap -->
3
+    <script src="/js/jquery.slim.min.js"></script>
4
+    <script src="/js/popper.min.js"></script>
5
+    <script src="/js/bootstrap.min.js"></script>
6
+  </body>
7
+</html>

+ 45
- 0
templates/_header.html View File

@@ -0,0 +1,45 @@
1
+<!DOCTYPE html>
2
+<html lang="de">
3
+  <head>
4
+    <meta charset="utf-8">
5
+    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
6
+
7
+    <title><?=$config->get('title')?></title>
8
+
9
+    <!-- Bootstrap CSS -->
10
+    <link rel="stylesheet" href="/css/bootstrap.min.css">
11
+    <link rel="stylesheet" href="/css/custom.css">
12
+  </head>
13
+
14
+  <body>
15
+
16
+    <nav class="navbar navbar-expand-md navbar-dark bg-dark fixed-top">
17
+      <a class="navbar-brand" href="<?=$config->get('title.url')?>"><?=$config->get('title')?></a>
18
+      <button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarDefault" aria-controls="navbarDefault" aria-expanded="false" aria-label="Toggle navigation">
19
+        <span class="navbar-toggler-icon"></span>
20
+      </button>
21
+
22
+      <div class="collapse navbar-collapse" id="navbarDefault">
23
+        <ul class="navbar-nav mr-auto">
24
+          <li class="nav-item active">
25
+            <a class="nav-link" href="/">Home <span class="sr-only">(current)</span></a>
26
+          </li>
27
+        </ul>
28
+
29
+        <?php if($session->isAuthenticated()): ?>
30
+        <ul class="navbar-nav float-right">
31
+          <li class="nav-item">
32
+            <a class="btn btn-outline-success" href="/logout">Logout</a>
33
+          </li>
34
+        </ul>
35
+        <?php else: ?>
36
+        <form class="form-inline my-2 my-lg-0" action="/login" method="post">
37
+          <input type="text" name="username" placeholder="Username" class="form-control mr-sm-2">
38
+          <input type="password" name="password" placeholder="Password" class="form-control mr-sm-2">
39
+          <button type="submit" value="Login" class="btn btn-success my-2 my-sm-0">Sign in</button>
40
+        </form>
41
+        <?php endif; ?>
42
+
43
+      </div>
44
+    </nav>
45
+

+ 20
- 0
templates/index.html View File

@@ -0,0 +1,20 @@
1
+<?php include("_header.html"); ?>
2
+
3
+    <div class="container">
4
+
5
+      <?php if($flash->hasMessage('error')): ?>
6
+        <?php foreach($flash->getMessage('error') as $msg): ?>
7
+          <div class="alert alert-danger" role="alert"><strong>Sorry</strong> <?=$msg?></div>
8
+        <?php endforeach; ?>
9
+      <?php endif; ?>
10
+
11
+      <?php if($flash->hasMessage('success')): ?>
12
+        <?php foreach($flash->getMessage('success') as $msg): ?>
13
+          <div class="alert alert-success" role="alert"><strong>Success</strong> <?=$msg?></div>
14
+        <?php endforeach; ?>
15
+      <?php endif; ?>
16
+
17
+      <h1><?=$config->get('title')?></h1>
18
+    </div>
19
+
20
+<?php include("_footer.html"); ?>

Loading…
Cancel
Save