Browse Source

Improve user permissions.

master
Syfaro 1 year ago
parent
commit
07df4079d9
3 changed files with 132 additions and 48 deletions
  1. 118
    46
      index.php
  2. 6
    0
      templates/_main.html
  3. 8
    2
      templates/admin/login.html

+ 118
- 46
index.php View File

@@ -166,17 +166,35 @@ $klein->respond(function ($request, $response, $service, $app) {
166 166
         }
167 167
     });
168 168
 
169
-    $app->register('twig', function () use ($app) {
169
+    $app->register('twig', function () use ($service, $app) {
170 170
         $loader = new Twig_Loader_Filesystem(__DIR__ . '/templates');
171 171
         $twig = new Twig_Environment($loader);
172 172
 
173 173
         $twig->addGlobal('user', $app->user);
174
+        $twig->addGlobal('flashes', $service->flashes());
175
+
176
+        $twig->addGlobal('session', $_SESSION);
177
+        $twig->addGlobal('server', $_SERVER);
174 178
 
175 179
         return $twig;
176 180
     });
177 181
 });
178 182
 
183
+function hasBeenInstalled()
184
+{
185
+    try {
186
+        $user = User::find_one();
187
+        if (!$user) return false;
188
+    } catch (Exception $ex) {
189
+        return false;
190
+    }
191
+
192
+    return true;
193
+}
194
+
179 195
 $klein->respond('GET', '/', function ($request, $response, $service, $app) {
196
+    if (!hasBeenInstalled()) return $response->redirect('/admin/setup');
197
+
180 198
     return $app->twig->render('index.html');
181 199
 });
182 200
 
@@ -184,7 +202,9 @@ $klein->with('/admin', function () use ($klein) {
184 202
     $klein->respond('GET', '', function ($request, $response, $service, $app) {
185 203
         if (!$app->user) return $response->redirect('/admin/login');
186 204
 
187
-        $questions = Question::find_many();
205
+        $questions = Question::where('user_id', $app->user->id)
206
+            ->order_by_asc('id')
207
+            ->find_many();
188 208
 
189 209
         return $app->twig->render('admin/index.html', [
190 210
             'questions' => $questions,
@@ -192,25 +212,13 @@ $klein->with('/admin', function () use ($klein) {
192 212
     });
193 213
 
194 214
     $klein->respond('GET', '/setup', function ($request, $response, $service, $app) {
195
-        try {
196
-            $user = User::find_one();
197
-            if ($user) {
198
-                return $response->redirect('/admin');
199
-            }
200
-        } catch (Exception $ex) {
201
-        }
215
+        if (hasBeenInstalled()) return $response->redirect('/admin');
202 216
 
203 217
         return $app->twig->render('admin/setup.html');
204 218
     });
205 219
 
206 220
     $klein->respond('POST', '/setup', function ($request, $response, $service, $app) {
207
-        try {
208
-            $user = User::find_one();
209
-            if ($user) {
210
-                return $response->redirect('/admin');
211
-            }
212
-        } catch (Exception $ex) {
213
-        }
221
+        if (hasBeenInstalled()) return $response->redirect('/admin');
214 222
 
215 223
         $service->validateParam('username')->isLen(3, 24)->isChars('a-zA-Z0-9-');
216 224
         $service->validateParam('password')->isLen(10, 128);
@@ -234,24 +242,30 @@ $klein->with('/admin', function () use ($klein) {
234 242
     });
235 243
 
236 244
     $klein->respond('GET', '/login', function ($request, $response, $service, $app) {
237
-        try {
238
-            $user = User::find_one();
239
-            if (!$user) {
240
-                return $response->redirect('/admin/setup');
241
-            }
242
-        } catch (Exception $ex) {
243
-            return $response->redirect('/admin/setup');
244
-        }
245
+        if (!hasBeenInstalled()) return $response->redirect('/admin/setup');
245 246
 
246 247
         return $app->twig->render('admin/login.html');
247 248
     });
248 249
 
249 250
     $klein->respond('POST', '/login', function ($request, $response, $service, $app) {
251
+        $service->validateParam('username')->notNull();
252
+
250 253
         $user = User::where('username', $request->username)->find_one();
251
-        if (!$user) return $response->redirect('/admin/login');
252
-        if (!$user->verify_password($request->password)) return $response->redirect('/admin/login');
254
+
255
+        $_SESSION['username'] = $request->username;
256
+
257
+        if (!$user) {
258
+            $service->flash('Unknown username', 'error');
259
+            return $response->redirect('/admin/login');
260
+        }
261
+
262
+        if (!$user->verify_password($request->password)) {
263
+            $service->flash('Invalid password', 'error');
264
+            return $response->redirect('/admin/login');
265
+        }
253 266
 
254 267
         $_SESSION['USER_ID'] = $user->id;
268
+        unset($_SESSION['username']);
255 269
 
256 270
         return $response->redirect('/admin');
257 271
     });
@@ -262,11 +276,24 @@ $klein->with('/admin', function () use ($klein) {
262 276
     });
263 277
 
264 278
     $klein->with('/question', function () use ($klein) {
279
+        $klein->respond(function ($request, $response, $service, $app) {
280
+            if (!$app->user) {
281
+                $response->redirect('/admin/login');
282
+                throw new \Klein\Exceptions\DispatchHaltedException();
283
+            }
284
+        });
285
+
265 286
         $klein->with('/[i:id]', function () use ($klein) {
266 287
             $klein->respond('GET', '', function ($request, $response, $service, $app) {
267
-                if (!$app->user) return $response->redirect('/admin/login');
288
+                $question = Question::where([
289
+                    'id' => $request->id,
290
+                    'user_id' => $app->user->id,
291
+                ])->find_one();
268 292
 
269
-                $question = Question::find_one($request->id);
293
+                if (!$question) {
294
+                    $response->redirect('/admin');
295
+                    throw new \Klein\Exceptions\DispatchHaltedException();
296
+                }
270 297
 
271 298
                 return $app->twig->render('admin/question/view.html', [
272 299
                     'question' => $question,
@@ -274,9 +301,14 @@ $klein->with('/admin', function () use ($klein) {
274 301
             });
275 302
 
276 303
             $klein->respond('POST', '', function ($request, $response, $service, $app) {
277
-                if (!$app->user) return $response->redirect('/admin/login');
304
+                $question = Question::where([
305
+                    'id' => $request->id,
306
+                    'user_id' => $app->user->id,
307
+                ])->find_one();
278 308
 
279
-                $question = Question::find_one($request->id);
309
+                if (!$question) {
310
+                    return $response->redirect('/admin');
311
+                }
280 312
 
281 313
                 $question->title = $request->title;
282 314
                 $question->description = $request->description;
@@ -287,11 +319,14 @@ $klein->with('/admin', function () use ($klein) {
287 319
             });
288 320
 
289 321
             $klein->respond('POST', '/delete', function ($request, $response, $service, $app) {
290
-                if (!$app->user) return $response->redirect('/admin/login');
322
+                $question = Question::where([
323
+                    'id' => $request->id,
324
+                    'user_id' => $app->user->id,
325
+                ])->find_one();
291 326
 
292
-                $question = Question::find_one($request->id);
293
-
294
-                if (!$question) return $response->redirect('/admin');
327
+                if (!$question) {
328
+                    return $response->redirect('/admin');
329
+                }
295 330
 
296 331
                 $choices = $question->choices();
297 332
                 if ($choices) {
@@ -313,18 +348,40 @@ $klein->with('/admin', function () use ($klein) {
313 348
                 $klein->respond('POST', '/add', function ($request, $response, $service, $app) {
314 349
                     $choice = Choice::create();
315 350
 
316
-                    $choice->question_id = $request->id;
351
+                    $question = Question::where([
352
+                        'id' => $request->id,
353
+                        'user_id' => $app->user->id,
354
+                    ])->find_one();
355
+
356
+                    if (!$question) {
357
+                        return $response->redirect('/admin');
358
+                    }
359
+
360
+                    $choice->question_id = $question->id;
317 361
                     $choice->value = $request->value;
318 362
 
319 363
                     $choice->save();
320 364
 
321
-                    return $response->redirect('/admin/question/' . $request->id);
365
+                    return $response->redirect('/admin/question/' . $question->id);
322 366
                 });
323 367
 
324 368
                 $klein->with('/[i:cid]', function () use ($klein) {
325 369
                     $klein->respond('GET', '', function ($request, $response, $service, $app) {
326 370
                         $choice = Choice::find_one($request->cid);
327 371
 
372
+                        if (!$choice) {
373
+                            return $response->redirect('/admin');
374
+                        }
375
+
376
+                        $question = Question::where([
377
+                            'id' => $choice->question()->find_one()->id,
378
+                            'user_id' => $app->user->id,
379
+                        ])->find_one();
380
+
381
+                        if (!$question) {
382
+                            return $response->redirect('/admin');
383
+                        }
384
+
328 385
                         return $app->twig->render('admin/question/choice/view.html', [
329 386
                             'choice' => $choice,
330 387
                         ]);
@@ -333,13 +390,26 @@ $klein->with('/admin', function () use ($klein) {
333 390
                     $klein->respond('POST', '/delete', function ($request, $response, $service, $app) {
334 391
                         $choice = Choice::find_one($request->cid);
335 392
 
393
+                        if (!$choice) {
394
+                            return $response->redirect('/admin');
395
+                        }
396
+
397
+                        $question = Question::where([
398
+                            'id' => $choice->question()->find_one()->id,
399
+                            'user_id' => $app->user->id,
400
+                        ])->find_one();
401
+
402
+                        if (!$question) {
403
+                            return $response->redirect('/admin');
404
+                        }
405
+
336 406
                         foreach (ChoiceResponse::where('choice_id', $choice->id)->find_many() as $resp) {
337 407
                             $resp->delete();
338 408
                         }
339 409
 
340 410
                         $choice->delete();
341 411
 
342
-                        return $response->redirect('/admin/question/' . $request->id);
412
+                        return $response->redirect('/admin/question/' . $question->id);
343 413
                     });
344 414
                 });
345 415
             });
@@ -347,10 +417,10 @@ $klein->with('/admin', function () use ($klein) {
347 417
             $klein->with('/response', function () use ($klein) {
348 418
                 $klein->with('/[i:rid]', function () use ($klein) {
349 419
                     $klein->respond('GET', '', function ($request, $response, $service, $app) {
350
-                        if (!$app->user) return $response->redirect('/admin/login');
351
-
352 420
                         $question = Question::find_one($request->id);
421
+                        if (!$question || $question->user_id != $app->user->id) return $response->redirect('/admin');
353 422
                         $resp = $question->response($request->rid);
423
+                        if (!$resp) return $response->redirect('/admin');
354 424
 
355 425
                         return $app->twig->render('admin/question/response/view.html', [
356 426
                             'question' => $question,
@@ -360,6 +430,7 @@ $klein->with('/admin', function () use ($klein) {
360 430
 
361 431
                     $klein->respond('POST', '/delete', function ($request, $response, $service, $app) {
362 432
                         $question = Question::find_one($request->id);
433
+                        if (!$question || $question->user_id != $app->user->id) return $response->redirect('/admin');
363 434
                         $resp = $question->response($request->rid)->find_one();
364 435
                         $resp->delete();
365 436
 
@@ -370,9 +441,12 @@ $klein->with('/admin', function () use ($klein) {
370 441
                 $klein->respond('POST', '/add', function ($request, $response, $service, $app) {
371 442
                     $service->validateParam('value')->notNull();
372 443
 
373
-                    if (!$app->user) return $response->redirect('/admin/login');
444
+                    $question = Question::where([
445
+                        'id' => $request->id,
446
+                        'user_id' => $app->user->id,
447
+                    ])->find_one();
374 448
 
375
-                    $question = Question::find_one($request->id);
449
+                    if (!$question || $question->user_id != $app->user->id) return $response->redirect('/admin');
376 450
 
377 451
                     switch ($question->type) {
378 452
                         case 'freeform':
@@ -404,8 +478,6 @@ $klein->with('/admin', function () use ($klein) {
404 478
         });
405 479
 
406 480
         $klein->respond('POST', '/add', function ($request, $response, $service, $app) {
407
-            if (!$app->user) return $response->redirect('/admin/login');
408
-
409 481
             $question = Question::create();
410 482
 
411 483
             $question->user_id = $app->user->id;
@@ -434,7 +506,7 @@ $klein->with('/api/v1', function () use ($klein) {
434 506
             $data = $question->as_array();
435 507
 
436 508
             if ($question->type == 'single') {
437
-                $data['choices'] = $question->choices()->find_array();
509
+                $data['choices'] = $question->choices()->order_by_asc('id')->find_array();
438 510
             }
439 511
 
440 512
             return $response->json($data);
@@ -457,10 +529,10 @@ $klein->with('/api/v1', function () use ($klein) {
457 529
                     case 'freeform':
458 530
                     case 'numeric':
459 531
                         return $response->json([
460
-                            'responses' => $question->responses()->find_array(),
532
+                            'responses' => $question->responses()->order_by_asc('id')->find_array(),
461 533
                         ]);
462 534
                     case 'single':
463
-                        $items = $question->responses()->find_many();
535
+                        $items = $question->responses()->order_by_asc('id')->find_many();
464 536
                         $responses = [];
465 537
                         foreach ($items as $item) {
466 538
                             $data = $item->as_array();

+ 6
- 0
templates/_main.html View File

@@ -37,6 +37,12 @@
37 37
                 <a href="https://git.huefox.com/syfaro/peppershrike">open source</a> &middot; made by <a
38 38
                     href="https://syfaro.net">syfaro</a>
39 39
             </p>
40
+
41
+            {% if user %}
42
+                <p>
43
+                    <a href="/admin/logout">log out</a>
44
+                </p>
45
+            {% endif %}
40 46
         </div>
41 47
     </div>
42 48
 </footer>

+ 8
- 2
templates/admin/login.html View File

@@ -6,18 +6,24 @@
6 6
 
7 7
     <div class="columns is-centered">
8 8
         <div class="column is-half">
9
+            {% for flash in flashes['error'] %}
10
+                <div class="notification is-danger">
11
+                    {{ flash }}
12
+                </div>
13
+            {% endfor %}
14
+
9 15
             <form method="POST">
10 16
                 <div class="field">
11 17
                     <label class="label">Username</label>
12 18
                     <div class="control">
13
-                        <input class="input" type="text" placeholder="Username" name="username">
19
+                        <input class="input" type="text" placeholder="Username" name="username" {% if session.username %}value="{{ session.username }}"{% endif %}>
14 20
                     </div>
15 21
                 </div>
16 22
 
17 23
                 <div class="field">
18 24
                     <label class="label">Password</label>
19 25
                     <div class="control">
20
-                        <input type="password" class="input" placeholder="Password" name="password">
26
+                        <input type="password" class="input" placeholder="Password" name="password" {% if session.username %}autofocus{% endif %}>
21 27
                     </div>
22 28
                 </div>
23 29
 

Loading…
Cancel
Save