Browse Source

Add more user management functionality to the CLI

J. King 1 month ago
parent
commit
9428d7468a
3 changed files with 81 additions and 25 deletions
  1. 2
    1
      arsse.php
  2. 76
    24
      lib/CLI.php
  3. 3
    0
      locale/en.php

+ 2
- 1
arsse.php View File

@@ -18,7 +18,8 @@ if (\PHP_SAPI=="cli") {
18 18
     // initialize the CLI; this automatically handles --help and --version
19 19
     $cli = new CLI;
20 20
     // handle other CLI requests; some do not require configuration
21
-    $cli->dispatch();
21
+    $exitStatus = $cli->dispatch();
22
+    exit($exitStatus);
22 23
 } else {
23 24
     // load configuration
24 25
     $conf = file_exists(BASE."config.php") ? new Conf(BASE."config.php") : new Conf;

+ 76
- 24
lib/CLI.php View File

@@ -6,6 +6,8 @@
6 6
 declare(strict_types=1);
7 7
 namespace JKingWeb\Arsse;
8 8
 
9
+use Docopt\Response as Opts;
10
+
9 11
 class CLI {
10 12
     protected $args = [];
11 13
 
@@ -15,13 +17,17 @@ class CLI {
15 17
 Usage:
16 18
     $prog daemon
17 19
     $prog feed refresh <n>
18
-    $prog conf save-defaults <file>
20
+    $prog conf save-defaults [<file>]
21
+    $prog user [list]
19 22
     $prog user add <username> [<password>]
23
+    $prog user remove <username>
24
+    $prog user set-pass [--oldpass=<pass>] <username> [<password>]
25
+    $prog user auth <username> <password>
20 26
     $prog --version
21 27
     $prog --help | -h
22 28
 
23 29
 The Arsse command-line interface currently allows you to start the refresh
24
-daemon, refresh a specific feed by numeric ID, add a user, or save default
30
+daemon, refresh a specific feed by numeric ID, manage users, or save default
25 31
 configuration to a sample file.
26 32
 USAGE_TEXT;
27 33
     }
@@ -35,6 +41,18 @@ USAGE_TEXT;
35 41
         ]);
36 42
     }
37 43
 
44
+    protected function command(array $options, $args): string {
45
+        foreach ($options as $cmd) {
46
+            foreach (explode(" ", $cmd) as $part) {
47
+                if (!$args[$part]) {
48
+                    continue 2;
49
+                }
50
+            }
51
+            return $cmd;
52
+        }
53
+        return "";
54
+    }
55
+
38 56
     protected function loadConf(): bool {
39 57
         $conf = file_exists(BASE."config.php") ? new Conf(BASE."config.php") : new Conf;
40 58
         Arsse::load($conf);
@@ -46,27 +64,24 @@ USAGE_TEXT;
46 64
     public function dispatch(array $args = null): int {
47 65
         // act on command line
48 66
         $args = $args ?? $this->args;
49
-        if ($this->command("daemon", $args)) {
50
-            $this->loadConf();
51
-            return $this->daemon();
52
-        } elseif ($this->command("feed refresh", $args)) {
53
-            $this->loadConf();
54
-            return $this->feedRefresh((int) $args['<n>']);
55
-        } elseif ($this->command("conf save-defaults", $args)) {
56
-            return $this->confSaveDefaults($args['<file>']);
57
-        } elseif ($this->command("user add", $args)) {
58
-            $this->loadConf();
59
-            return $this->userAdd($args['<username>'], $args['<password>']);
60
-        }
61
-    }
62
-
63
-    protected function command($cmd, $args): bool {
64
-        foreach (explode(" ", $cmd) as $part) {
65
-            if (!$args[$part]) {
66
-                return false;
67
+        try {
68
+            switch ($this->command(["daemon", "feed refresh", "conf save-defaults", "user"], $args)) {
69
+                case "daemon":
70
+                    $this->loadConf();
71
+                    return $this->daemon();
72
+                case "feed refresh":
73
+                    $this->loadConf();
74
+                    return $this->feedRefresh((int) $args['<n>']);
75
+                case "conf save-defaults":
76
+                    return $this->confSaveDefaults($args['<file>']);
77
+                case "user":
78
+                    $this->loadConf();
79
+                    return $this->userManage($args);
67 80
             }
81
+        } catch (AbstractException $e) {
82
+            fwrite(STDERR, $e->getMessage().\PHP_EOL);
83
+            return $e->getCode();
68 84
         }
69
-        return true;
70 85
     }
71 86
 
72 87
     public function daemon(bool $loop = true): int {
@@ -78,15 +93,52 @@ USAGE_TEXT;
78 93
         return (int) !Arsse::$db->feedUpdate($id); // FIXME: exception error codes should be returned here
79 94
     }
80 95
 
81
-    public function confSaveDefaults(string $file): int {
96
+    public function confSaveDefaults(string $file = null): int {
97
+        $file = ($file=="-" ? null : $file) ?? STDOUT;
82 98
         return (int) !(new Conf)->exportFile($file, true);
83 99
     }
84 100
 
85
-    public function userAdd(string $user, string $password = null): int {
86
-        $passwd = Arsse::$user->add($user, $password);
101
+    public function userManage($args): int {
102
+        switch ($this->command(["add", "remove", "set-pass", "list", "auth"], $args)) {
103
+            case "add":
104
+                return $this->userAddOrSetPassword("add", $args["<username>"], $args["<password>"]);
105
+            case "set-pass":
106
+                return $this->userAddOrSetPassword("passwordSet", $args["<username>"], $args["<password>"], $args["<oldpass>"]);
107
+            case "remove":
108
+                return (int) !Arsse::$user->remove($args["<username>"]);
109
+            case "auth":
110
+                return $this->userAuthenticate($args["<username>"], $args["<password>"]);
111
+            case "list":
112
+            case "":
113
+                return $this->userList();
114
+        }
115
+    }
116
+
117
+    protected function userAddOrSetPassword(string $method, string $user, string $password = null, string $oldpass = null): int {
118
+        $args = \func_get_args();
119
+        array_shift($args);
120
+        $passwd = Arsse::$user->$method(...$args);
87 121
         if (is_null($password)) {
88 122
             echo $passwd.\PHP_EOL;
89 123
         }
90 124
         return 0;
91 125
     }
126
+
127
+    protected function userList(): int {
128
+        $list = Arsse::$user->list();
129
+        if ($list) {
130
+            echo implode(\PHP_EOL, $list).\PHP_EOL;
131
+        }
132
+        return 0;
133
+    }
134
+
135
+    protected function userAuthenticate(string $user, string $password): int {
136
+        if (Arsse::$user->auth($user, $password)) {
137
+            echo Arsse::$lang->msg("CLI.Auth.Success").\PHP_EOL;
138
+            return 0;
139
+        } else {
140
+            echo Arsse::$lang->msg("CLI.Auth.Failure").\PHP_EOL;
141
+            return 1;
142
+        }
143
+    }
92 144
 }

+ 3
- 0
locale/en.php View File

@@ -4,6 +4,9 @@
4 4
  * See LICENSE and AUTHORS files for details */
5 5
 
6 6
 return [
7
+    'CLI.Auth.Success'                                                     => 'Authentication successful',
8
+    'CLI.Auth.Failure'                                                     => 'Authentication failed',
9
+
7 10
     'API.TTRSS.Category.Uncategorized'                                     => 'Uncategorized',
8 11
     'API.TTRSS.Category.Special'                                           => 'Special',
9 12
     'API.TTRSS.Category.Labels'                                            => 'Labels',

Loading…
Cancel
Save