meerschaum 2.9.4__py3-none-any.whl → 3.0.0rc1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- meerschaum/__init__.py +5 -2
- meerschaum/_internal/__init__.py +1 -0
- meerschaum/_internal/arguments/_parse_arguments.py +4 -4
- meerschaum/_internal/arguments/_parser.py +17 -1
- meerschaum/_internal/entry.py +6 -6
- meerschaum/_internal/shell/Shell.py +1 -1
- meerschaum/_internal/static.py +372 -0
- meerschaum/actions/api.py +12 -2
- meerschaum/actions/bootstrap.py +7 -7
- meerschaum/actions/edit.py +142 -18
- meerschaum/actions/register.py +137 -6
- meerschaum/actions/show.py +117 -29
- meerschaum/actions/stop.py +4 -1
- meerschaum/actions/sync.py +1 -1
- meerschaum/actions/tag.py +9 -8
- meerschaum/api/__init__.py +9 -2
- meerschaum/api/_events.py +39 -2
- meerschaum/api/_oauth2.py +118 -8
- meerschaum/api/_tokens.py +102 -0
- meerschaum/api/dash/__init__.py +0 -1
- meerschaum/api/dash/callbacks/custom.py +2 -2
- meerschaum/api/dash/callbacks/dashboard.py +133 -18
- meerschaum/api/dash/callbacks/plugins.py +0 -1
- meerschaum/api/dash/callbacks/register.py +1 -1
- meerschaum/api/dash/callbacks/settings/__init__.py +1 -0
- meerschaum/api/dash/callbacks/settings/password_reset.py +2 -2
- meerschaum/api/dash/callbacks/settings/tokens.py +388 -0
- meerschaum/api/dash/components.py +30 -8
- meerschaum/api/dash/keys.py +19 -93
- meerschaum/api/dash/pages/dashboard.py +1 -20
- meerschaum/api/dash/pages/settings/__init__.py +1 -0
- meerschaum/api/dash/pages/settings/password_reset.py +1 -1
- meerschaum/api/dash/pages/settings/tokens.py +55 -0
- meerschaum/api/dash/pipes.py +156 -58
- meerschaum/api/dash/sessions.py +12 -0
- meerschaum/api/dash/tokens.py +606 -0
- meerschaum/api/dash/websockets.py +1 -1
- meerschaum/api/dash/webterm.py +4 -0
- meerschaum/api/models/__init__.py +23 -3
- meerschaum/api/models/_actions.py +22 -0
- meerschaum/api/models/_pipes.py +85 -7
- meerschaum/api/models/_tokens.py +81 -0
- meerschaum/api/resources/static/css/dash.css +16 -0
- meerschaum/api/resources/templates/termpage.html +12 -0
- meerschaum/api/routes/__init__.py +1 -0
- meerschaum/api/routes/_actions.py +3 -4
- meerschaum/api/routes/_connectors.py +3 -7
- meerschaum/api/routes/_jobs.py +14 -35
- meerschaum/api/routes/_login.py +49 -12
- meerschaum/api/routes/_misc.py +5 -10
- meerschaum/api/routes/_pipes.py +134 -111
- meerschaum/api/routes/_plugins.py +38 -28
- meerschaum/api/routes/_tokens.py +236 -0
- meerschaum/api/routes/_users.py +47 -35
- meerschaum/api/routes/_version.py +3 -3
- meerschaum/config/__init__.py +43 -20
- meerschaum/config/_default.py +32 -5
- meerschaum/config/_edit.py +28 -24
- meerschaum/config/_environment.py +1 -1
- meerschaum/config/_patch.py +6 -6
- meerschaum/config/_paths.py +5 -1
- meerschaum/config/_read_config.py +65 -34
- meerschaum/config/_sync.py +6 -3
- meerschaum/config/_version.py +1 -1
- meerschaum/config/stack/__init__.py +24 -5
- meerschaum/config/static.py +18 -0
- meerschaum/connectors/_Connector.py +10 -4
- meerschaum/connectors/__init__.py +4 -20
- meerschaum/connectors/api/_APIConnector.py +34 -6
- meerschaum/connectors/api/_actions.py +2 -2
- meerschaum/connectors/api/_jobs.py +1 -1
- meerschaum/connectors/api/_login.py +33 -7
- meerschaum/connectors/api/_misc.py +2 -2
- meerschaum/connectors/api/_pipes.py +15 -14
- meerschaum/connectors/api/_plugins.py +2 -2
- meerschaum/connectors/api/_request.py +1 -1
- meerschaum/connectors/api/_tokens.py +146 -0
- meerschaum/connectors/api/_users.py +70 -58
- meerschaum/connectors/instance/_InstanceConnector.py +83 -0
- meerschaum/connectors/instance/__init__.py +10 -0
- meerschaum/connectors/instance/_pipes.py +442 -0
- meerschaum/connectors/instance/_plugins.py +151 -0
- meerschaum/connectors/instance/_tokens.py +296 -0
- meerschaum/connectors/instance/_users.py +181 -0
- meerschaum/connectors/parse.py +4 -1
- meerschaum/connectors/sql/_SQLConnector.py +8 -5
- meerschaum/connectors/sql/_cli.py +12 -11
- meerschaum/connectors/sql/_create_engine.py +6 -154
- meerschaum/connectors/sql/_fetch.py +2 -18
- meerschaum/connectors/sql/_pipes.py +42 -31
- meerschaum/connectors/sql/_plugins.py +29 -0
- meerschaum/connectors/sql/_sql.py +9 -2
- meerschaum/connectors/sql/_users.py +29 -2
- meerschaum/connectors/sql/tables/__init__.py +1 -1
- meerschaum/connectors/valkey/_ValkeyConnector.py +2 -4
- meerschaum/connectors/valkey/_pipes.py +9 -10
- meerschaum/connectors/valkey/_plugins.py +2 -26
- meerschaum/core/Pipe/__init__.py +31 -14
- meerschaum/core/Pipe/_attributes.py +156 -58
- meerschaum/core/Pipe/_bootstrap.py +54 -24
- meerschaum/core/Pipe/_data.py +41 -1
- meerschaum/core/Pipe/_dtypes.py +29 -14
- meerschaum/core/Pipe/_edit.py +12 -4
- meerschaum/core/Pipe/_show.py +5 -5
- meerschaum/core/Pipe/_sync.py +48 -53
- meerschaum/core/Pipe/_verify.py +1 -1
- meerschaum/{plugins → core/Plugin}/_Plugin.py +9 -11
- meerschaum/core/Plugin/__init__.py +1 -1
- meerschaum/core/Token/_Token.py +221 -0
- meerschaum/core/Token/__init__.py +12 -0
- meerschaum/core/User/_User.py +34 -8
- meerschaum/core/User/__init__.py +9 -1
- meerschaum/core/__init__.py +1 -0
- meerschaum/jobs/_Job.py +3 -2
- meerschaum/jobs/__init__.py +3 -2
- meerschaum/jobs/systemd.py +1 -1
- meerschaum/models/__init__.py +35 -0
- meerschaum/models/pipes.py +247 -0
- meerschaum/models/tokens.py +38 -0
- meerschaum/models/users.py +26 -0
- meerschaum/plugins/__init__.py +22 -7
- meerschaum/plugins/bootstrap.py +2 -1
- meerschaum/utils/_get_pipes.py +68 -27
- meerschaum/utils/daemon/Daemon.py +2 -1
- meerschaum/utils/daemon/__init__.py +30 -2
- meerschaum/utils/dataframe.py +96 -15
- meerschaum/utils/dtypes/__init__.py +93 -21
- meerschaum/utils/dtypes/sql.py +44 -0
- meerschaum/utils/formatting/__init__.py +1 -1
- meerschaum/utils/formatting/_pipes.py +5 -4
- meerschaum/utils/formatting/_shell.py +11 -9
- meerschaum/utils/misc.py +237 -80
- meerschaum/utils/packages/__init__.py +3 -6
- meerschaum/utils/packages/_packages.py +34 -32
- meerschaum/utils/pipes.py +181 -0
- meerschaum/utils/process.py +1 -1
- meerschaum/utils/prompt.py +3 -1
- meerschaum/utils/schedule.py +1 -0
- meerschaum/utils/sql.py +115 -39
- meerschaum/utils/typing.py +1 -4
- meerschaum/utils/venv/_Venv.py +2 -2
- meerschaum/utils/venv/__init__.py +5 -7
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0rc1.dist-info}/METADATA +88 -80
- meerschaum-3.0.0rc1.dist-info/RECORD +282 -0
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0rc1.dist-info}/WHEEL +1 -1
- meerschaum/api/models/_interfaces.py +0 -15
- meerschaum/api/models/_locations.py +0 -15
- meerschaum/api/models/_metrics.py +0 -15
- meerschaum/config/static/__init__.py +0 -186
- meerschaum-2.9.4.dist-info/RECORD +0 -263
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0rc1.dist-info}/entry_points.txt +0 -0
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0rc1.dist-info}/licenses/LICENSE +0 -0
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0rc1.dist-info}/top_level.txt +0 -0
- {meerschaum-2.9.4.dist-info → meerschaum-3.0.0rc1.dist-info}/zip-safe +0 -0
@@ -0,0 +1,221 @@
|
|
1
|
+
#! /usr/bin/env python3
|
2
|
+
# vim:fenc=utf-8
|
3
|
+
|
4
|
+
"""
|
5
|
+
Define the properties of a long-lived access token.
|
6
|
+
"""
|
7
|
+
|
8
|
+
from __future__ import annotations
|
9
|
+
|
10
|
+
import base64
|
11
|
+
import uuid
|
12
|
+
from random import randint
|
13
|
+
from typing import Optional, Union, List, Tuple
|
14
|
+
from datetime import datetime, timedelta, timezone
|
15
|
+
|
16
|
+
import meerschaum as mrsm
|
17
|
+
from meerschaum.models import TokenModel
|
18
|
+
|
19
|
+
_PLACEHOLDER_EXPIRATION = datetime(2000, 1, 1)
|
20
|
+
|
21
|
+
class Token:
|
22
|
+
"""
|
23
|
+
Tokens (long lived access tokens) may be registered and revoked to provide easier authentication (e.g. IoT devices).
|
24
|
+
Tokens must be tied to a Meerschaum user account.
|
25
|
+
"""
|
26
|
+
|
27
|
+
def __init__(
|
28
|
+
self,
|
29
|
+
label: Optional[str] = None,
|
30
|
+
creation: Optional[datetime] = None,
|
31
|
+
expiration: Optional[datetime] = _PLACEHOLDER_EXPIRATION,
|
32
|
+
instance: Optional[str] = None,
|
33
|
+
user: Optional[mrsm.core.User] = None,
|
34
|
+
user_id: Union[int, str, uuid.UUID, None] = None,
|
35
|
+
scopes: Optional[List[str]] = None,
|
36
|
+
is_valid: bool = True,
|
37
|
+
id: Optional[uuid.UUID] = None,
|
38
|
+
secret: Optional[str] = None,
|
39
|
+
secret_hash: Optional[str] = None,
|
40
|
+
):
|
41
|
+
from meerschaum.utils.dtypes import coerce_timezone
|
42
|
+
from meerschaum.utils.daemon import get_new_daemon_name
|
43
|
+
from meerschaum.utils.misc import round_time
|
44
|
+
from meerschaum._internal.static import STATIC_CONFIG
|
45
|
+
now = datetime.now(timezone.utc)
|
46
|
+
default_expiration_days = mrsm.get_config(
|
47
|
+
'system', 'api', 'tokens', 'default_expiration_days',
|
48
|
+
) or 366
|
49
|
+
default_expiration = round_time(
|
50
|
+
now + timedelta(days=default_expiration_days),
|
51
|
+
timedelta(days=1),
|
52
|
+
)
|
53
|
+
if expiration == _PLACEHOLDER_EXPIRATION:
|
54
|
+
expiration = default_expiration
|
55
|
+
self.creation = coerce_timezone(creation) if creation is not None else None
|
56
|
+
self.expiration = coerce_timezone(expiration) if expiration is not None else None
|
57
|
+
self._instance_keys = str(instance) if instance is not None else None
|
58
|
+
self.label = label or get_new_daemon_name()
|
59
|
+
self._user = user
|
60
|
+
self._user_id = user_id
|
61
|
+
self.scopes = scopes or list(STATIC_CONFIG['tokens']['scopes'])
|
62
|
+
self.is_valid = is_valid
|
63
|
+
self.id = id
|
64
|
+
self.secret = secret
|
65
|
+
self.secret_hash = secret_hash
|
66
|
+
|
67
|
+
def generate_credentials(self) -> Tuple[uuid.UUID, str]:
|
68
|
+
"""
|
69
|
+
Generate and return the client ID and secret values for this token.
|
70
|
+
"""
|
71
|
+
if self.id and self.secret:
|
72
|
+
return self.id, self.secret
|
73
|
+
|
74
|
+
from meerschaum.utils.misc import generate_password
|
75
|
+
from meerschaum._internal.static import STATIC_CONFIG
|
76
|
+
min_len = STATIC_CONFIG['tokens']['minimum_length']
|
77
|
+
max_len = STATIC_CONFIG['tokens']['maximum_length']
|
78
|
+
|
79
|
+
secret_len = randint(min_len, max_len + 1)
|
80
|
+
self.secret = generate_password(secret_len)
|
81
|
+
self.id = uuid.uuid4()
|
82
|
+
return self.id, self.secret
|
83
|
+
|
84
|
+
def get_api_key(self) -> str:
|
85
|
+
"""
|
86
|
+
Return the API key to be sent in the `Authorization` header.
|
87
|
+
"""
|
88
|
+
return 'mrsm-key:' + base64.b64encode(f"{self.id}:{self.secret}".encode('utf-8')).decode('utf-8')
|
89
|
+
|
90
|
+
@property
|
91
|
+
def instance_connector(self) -> mrsm.connectors.InstanceConnector:
|
92
|
+
"""
|
93
|
+
Return the instance connector to use for this token.
|
94
|
+
"""
|
95
|
+
from meerschaum.connectors.parse import parse_instance_keys
|
96
|
+
return parse_instance_keys(self._instance_keys)
|
97
|
+
|
98
|
+
@property
|
99
|
+
def user(self) -> Union[mrsm.core.User, None]:
|
100
|
+
"""
|
101
|
+
Return the `User` for this token.
|
102
|
+
"""
|
103
|
+
if self._user is not None:
|
104
|
+
return self._user
|
105
|
+
|
106
|
+
if self._user_id is not None:
|
107
|
+
username = self.instance_connector.get_username(self._user_id)
|
108
|
+
if not username:
|
109
|
+
return None
|
110
|
+
_user = mrsm.core.User(
|
111
|
+
username,
|
112
|
+
user_id=self._user_id,
|
113
|
+
instance=str(self.instance_connector),
|
114
|
+
)
|
115
|
+
self._user = _user
|
116
|
+
return _user
|
117
|
+
|
118
|
+
return None
|
119
|
+
|
120
|
+
def register(self, debug: bool = False) -> mrsm.SuccessTuple:
|
121
|
+
"""
|
122
|
+
Register the new token to the configured instance.
|
123
|
+
"""
|
124
|
+
if self.user is None:
|
125
|
+
raise ValueError("Cannot register a token with a user.")
|
126
|
+
|
127
|
+
return self.instance_connector.register_token(self, debug=debug)
|
128
|
+
|
129
|
+
def edit(self, debug: bool = False) -> mrsm.SuccessTuple:
|
130
|
+
"""
|
131
|
+
Edit some of the token's attributes (expiration, scopes).
|
132
|
+
"""
|
133
|
+
return self.instance_connector.edit_token(self, debug=debug)
|
134
|
+
|
135
|
+
def invalidate(self, debug: bool = False) -> mrsm.SuccessTuple:
|
136
|
+
"""
|
137
|
+
Set `is_valid` to False for this token.
|
138
|
+
"""
|
139
|
+
self.is_valid = False
|
140
|
+
return self.instance_connector.invalidate_token(self, debug=debug)
|
141
|
+
|
142
|
+
def delete(self, debug: bool = False) -> mrsm.SuccessTuple:
|
143
|
+
"""
|
144
|
+
Delete this token from the instance connector.
|
145
|
+
"""
|
146
|
+
return self.instance_connector.delete_token(self, debug=debug)
|
147
|
+
|
148
|
+
def exists(self, debug: bool = False) -> bool:
|
149
|
+
"""
|
150
|
+
Return `True` if a token's ID exists in the tokens pipe.
|
151
|
+
"""
|
152
|
+
if not self.id:
|
153
|
+
return False
|
154
|
+
return self.instance_connector.token_exists(self.id, debug=debug)
|
155
|
+
|
156
|
+
def to_model(self, refresh: bool = False, debug: bool = False) -> TokenModel:
|
157
|
+
"""
|
158
|
+
Export the current state to a `TokenModel`.
|
159
|
+
"""
|
160
|
+
in_memory_doc = {
|
161
|
+
'id': self.id,
|
162
|
+
'label': self.label,
|
163
|
+
'creation': self.creation,
|
164
|
+
'expiration': self.expiration,
|
165
|
+
'is_valid': self.is_valid,
|
166
|
+
'user_id': self._user_id,
|
167
|
+
'scopes': self.scopes,
|
168
|
+
}
|
169
|
+
if not refresh:
|
170
|
+
return TokenModel(**in_memory_doc)
|
171
|
+
|
172
|
+
if not self.id:
|
173
|
+
raise ValueError(f"ID is not set for {self}.")
|
174
|
+
|
175
|
+
token_model = self.instance_connector.get_token_model(self.id, debug=debug)
|
176
|
+
if token_model is None:
|
177
|
+
raise ValueError(f"{self} does not exist on instance '{self.instance_connector}'.")
|
178
|
+
|
179
|
+
return token_model
|
180
|
+
|
181
|
+
def get_scopes(self, refresh: bool = False, debug: bool = False) -> List[str]:
|
182
|
+
"""
|
183
|
+
Return the scopes for this `Token`.
|
184
|
+
"""
|
185
|
+
if not refresh:
|
186
|
+
return self.scopes
|
187
|
+
|
188
|
+
self.scopes = self.instance_connector.get_token_scopes(self, debug=debug)
|
189
|
+
return self.scopes
|
190
|
+
|
191
|
+
def get_expiration_status(self, debug: bool = False) -> bool:
|
192
|
+
"""
|
193
|
+
Check the token's expiration against the current timestamp.
|
194
|
+
If it's expired, invalidate the token.
|
195
|
+
|
196
|
+
Returns
|
197
|
+
-------
|
198
|
+
A bool to indication whether the token has expired.
|
199
|
+
A value of `True` means the token is invalid,
|
200
|
+
and `False` indicates a valid token.
|
201
|
+
"""
|
202
|
+
expiration = self.expiration
|
203
|
+
if expiration is None:
|
204
|
+
return False
|
205
|
+
|
206
|
+
now = datetime.now(timezone.utc)
|
207
|
+
is_expired = expiration <= now
|
208
|
+
if is_expired:
|
209
|
+
self.is_valid = False
|
210
|
+
invalidate_success, invalidate_msg = self.invalidate(debug=debug)
|
211
|
+
if not invalidate_success:
|
212
|
+
from meerschaum.utils.warnings import warn
|
213
|
+
warn(f"Failed to invalidate {self}:\n{invalidate_msg}")
|
214
|
+
|
215
|
+
return is_expired
|
216
|
+
|
217
|
+
def __str__(self):
|
218
|
+
return self.label
|
219
|
+
|
220
|
+
def __repr__(self):
|
221
|
+
return self.to_model(refresh=False).__repr__().replace('TokenModel(', 'Token(')
|
meerschaum/core/User/_User.py
CHANGED
@@ -7,14 +7,15 @@ User class definition
|
|
7
7
|
"""
|
8
8
|
|
9
9
|
from __future__ import annotations
|
10
|
+
|
10
11
|
import os
|
11
12
|
import hashlib
|
12
13
|
import hmac
|
14
|
+
import uuid
|
13
15
|
from binascii import b2a_base64, a2b_base64, Error as _BinAsciiError
|
14
16
|
|
15
17
|
import meerschaum as mrsm
|
16
|
-
from meerschaum.utils.typing import Optional, Dict, Any, Union
|
17
|
-
from meerschaum.config.static import STATIC_CONFIG
|
18
|
+
from meerschaum.utils.typing import Optional, Dict, Any, Union, List
|
18
19
|
from meerschaum.utils.warnings import warn
|
19
20
|
|
20
21
|
|
@@ -40,7 +41,7 @@ def hash_password(
|
|
40
41
|
|
41
42
|
rounds: Optional[int], default None
|
42
43
|
If provided, use this number of rounds to generate the hash.
|
43
|
-
Defaults to
|
44
|
+
Defaults to 1,000,000.
|
44
45
|
|
45
46
|
Returns
|
46
47
|
-------
|
@@ -48,6 +49,7 @@ def hash_password(
|
|
48
49
|
See the `passlib` documentation on the string format:
|
49
50
|
https://passlib.readthedocs.io/en/stable/lib/passlib.hash.pbkdf2_digest.html#format-algorithm
|
50
51
|
"""
|
52
|
+
from meerschaum._internal.static import STATIC_CONFIG
|
51
53
|
hash_config = STATIC_CONFIG['users']['password_hash']
|
52
54
|
if password is None:
|
53
55
|
password = ''
|
@@ -64,7 +66,7 @@ def hash_password(
|
|
64
66
|
)
|
65
67
|
return (
|
66
68
|
f"$pbkdf2-{hash_config['algorithm_name']}"
|
67
|
-
+ f"${
|
69
|
+
+ f"${rounds}"
|
68
70
|
+ '$' + ab64_encode(salt).decode('utf-8')
|
69
71
|
+ '$' + ab64_encode(pw_hash).decode('utf-8')
|
70
72
|
)
|
@@ -89,6 +91,7 @@ def verify_password(
|
|
89
91
|
-------
|
90
92
|
A `bool` indicating whether `password` matches `password_hash`.
|
91
93
|
"""
|
94
|
+
from meerschaum._internal.static import STATIC_CONFIG
|
92
95
|
if password is None or password_hash is None:
|
93
96
|
return False
|
94
97
|
hash_config = STATIC_CONFIG['users']['password_hash']
|
@@ -177,7 +180,7 @@ class User:
|
|
177
180
|
type: Optional[str] = None,
|
178
181
|
email: Optional[str] = None,
|
179
182
|
attributes: Optional[Dict[str, Any]] = None,
|
180
|
-
user_id:
|
183
|
+
user_id: Union[int, str, uuid.UUID, None] = None,
|
181
184
|
instance: Optional[str] = None
|
182
185
|
):
|
183
186
|
if password is None:
|
@@ -188,7 +191,7 @@ class User:
|
|
188
191
|
self.type = type
|
189
192
|
self._attributes = attributes
|
190
193
|
self._user_id = user_id
|
191
|
-
self._instance_keys = str(instance)
|
194
|
+
self._instance_keys = str(instance) if instance is not None else None
|
192
195
|
|
193
196
|
def __repr__(self):
|
194
197
|
return str(self)
|
@@ -203,14 +206,14 @@ class User:
|
|
203
206
|
return self._attributes
|
204
207
|
|
205
208
|
@property
|
206
|
-
def instance_connector(self) ->
|
209
|
+
def instance_connector(self) -> mrsm.connectors.InstanceConnector:
|
207
210
|
from meerschaum.connectors.parse import parse_instance_keys
|
208
211
|
if '_instance_connector' not in self.__dict__:
|
209
212
|
self._instance_connector = parse_instance_keys(self._instance_keys)
|
210
213
|
return self._instance_connector
|
211
214
|
|
212
215
|
@property
|
213
|
-
def user_id(self) -> Union[int, str, None]:
|
216
|
+
def user_id(self) -> Union[int, str, uuid.UUID, None]:
|
214
217
|
"""NOTE: This causes recursion with the API,
|
215
218
|
so don't try to get fancy with read-only attributes.
|
216
219
|
"""
|
@@ -231,3 +234,26 @@ class User:
|
|
231
234
|
|
232
235
|
self._password_hash = hash_password(self.password)
|
233
236
|
return self._password_hash
|
237
|
+
|
238
|
+
def get_attributes(self, refresh: bool = False, debug: bool = False) -> Dict[str, Any]:
|
239
|
+
"""
|
240
|
+
Return the user's attributes.
|
241
|
+
"""
|
242
|
+
if not refresh:
|
243
|
+
return self.attributes
|
244
|
+
self._attributes = self.instance_connector.get_user_attributes(self, debug=debug) or {}
|
245
|
+
return self._attributes
|
246
|
+
|
247
|
+
def get_scopes(self, refresh: bool = False, debug: bool = False) -> List[str]:
|
248
|
+
"""
|
249
|
+
Return the scopes for this user.
|
250
|
+
"""
|
251
|
+
from meerschaum._internal.static import STATIC_CONFIG
|
252
|
+
_attributes = self.get_attributes(refresh=refresh, debug=debug)
|
253
|
+
return _attributes.get('scopes', None) or list(STATIC_CONFIG['tokens']['scopes'])
|
254
|
+
|
255
|
+
def register(self, debug: bool = False, **kwargs: Any) -> mrsm.SuccessTuple:
|
256
|
+
"""
|
257
|
+
Register a user to the instance connector.
|
258
|
+
"""
|
259
|
+
return self.instance_connector.register_user(self, debug=debug, **kwargs)
|
meerschaum/core/User/__init__.py
CHANGED
@@ -9,7 +9,15 @@ Manager users' metadata via the User class
|
|
9
9
|
from typing import Optional
|
10
10
|
|
11
11
|
import meerschaum as mrsm
|
12
|
-
from meerschaum.core.User._User import User
|
12
|
+
from meerschaum.core.User._User import User, hash_password, verify_password
|
13
|
+
|
14
|
+
|
15
|
+
__all__ = (
|
16
|
+
'User',
|
17
|
+
'hash_password',
|
18
|
+
'verify_password',
|
19
|
+
'is_user_allowed_to_execute',
|
20
|
+
)
|
13
21
|
|
14
22
|
|
15
23
|
def is_user_allowed_to_execute(
|
meerschaum/core/__init__.py
CHANGED
meerschaum/jobs/_Job.py
CHANGED
@@ -24,7 +24,7 @@ from meerschaum._internal.entry import entry
|
|
24
24
|
from meerschaum.utils.warnings import warn
|
25
25
|
from meerschaum.config.paths import LOGS_RESOURCES_PATH
|
26
26
|
from meerschaum.config import get_config
|
27
|
-
from meerschaum.
|
27
|
+
from meerschaum._internal.static import STATIC_CONFIG
|
28
28
|
|
29
29
|
if TYPE_CHECKING:
|
30
30
|
from meerschaum.jobs._Executor import Executor
|
@@ -702,7 +702,8 @@ class Job:
|
|
702
702
|
|
703
703
|
_result = self.daemon.properties.get('result', None)
|
704
704
|
if _result is None:
|
705
|
-
|
705
|
+
from meerschaum.utils.daemon.Daemon import _results
|
706
|
+
return _results.get(self.daemon.daemon_id, (False, "No result available."))
|
706
707
|
|
707
708
|
return tuple(_result)
|
708
709
|
|
meerschaum/jobs/__init__.py
CHANGED
@@ -79,7 +79,8 @@ def get_jobs(
|
|
79
79
|
}
|
80
80
|
|
81
81
|
def _get_systemd_jobs():
|
82
|
-
|
82
|
+
from meerschaum.jobs.systemd import SystemdExecutor
|
83
|
+
conn = SystemdExecutor('systemd')
|
83
84
|
jobs = conn.get_jobs(debug=debug)
|
84
85
|
return {
|
85
86
|
name: job
|
@@ -369,7 +370,7 @@ def start_check_jobs_thread():
|
|
369
370
|
import atexit
|
370
371
|
from functools import partial
|
371
372
|
from meerschaum.utils.threading import RepeatTimer
|
372
|
-
from meerschaum.
|
373
|
+
from meerschaum._internal.static import STATIC_CONFIG
|
373
374
|
|
374
375
|
global _check_loop_stop_thread
|
375
376
|
sleep_seconds = STATIC_CONFIG['jobs']['check_restart_seconds']
|
meerschaum/jobs/systemd.py
CHANGED
@@ -21,7 +21,7 @@ import meerschaum as mrsm
|
|
21
21
|
from meerschaum.jobs import Job, Executor, make_executor
|
22
22
|
from meerschaum.utils.typing import Dict, Any, List, SuccessTuple, Union, Optional, Callable
|
23
23
|
from meerschaum.config import get_config
|
24
|
-
from meerschaum.
|
24
|
+
from meerschaum._internal.static import STATIC_CONFIG
|
25
25
|
from meerschaum.utils.warnings import warn, dprint
|
26
26
|
from meerschaum._internal.arguments._parse_arguments import parse_arguments
|
27
27
|
|
@@ -0,0 +1,35 @@
|
|
1
|
+
#! /usr/bin/env python3
|
2
|
+
# vim:fenc=utf-8
|
3
|
+
|
4
|
+
"""
|
5
|
+
Define fundamental Pydantic models (to be built upon for API response models).
|
6
|
+
"""
|
7
|
+
|
8
|
+
import meerschaum as mrsm
|
9
|
+
|
10
|
+
annotated_types = mrsm.attempt_import('annotated_types', lazy=False)
|
11
|
+
pydantic = mrsm.attempt_import('pydantic', lazy=False)
|
12
|
+
|
13
|
+
from meerschaum.models.pipes import (
|
14
|
+
PipeModel,
|
15
|
+
PipeWithParametersModel,
|
16
|
+
PipesWithParametersDictModel,
|
17
|
+
ConnectorKeysModel,
|
18
|
+
MetricKeyModel,
|
19
|
+
LocationKeyModel,
|
20
|
+
InstanceKeysModel,
|
21
|
+
)
|
22
|
+
from meerschaum.models.users import UserModel
|
23
|
+
from meerschaum.models.tokens import TokenModel
|
24
|
+
|
25
|
+
__all__ = (
|
26
|
+
'PipeModel',
|
27
|
+
'PipeWithParametersModel',
|
28
|
+
'PipesWithParametersDictModel',
|
29
|
+
'ConnectorKeysModel',
|
30
|
+
'MetricKeyModel',
|
31
|
+
'LocationKeyModel',
|
32
|
+
'InstanceKeysModel',
|
33
|
+
'UserModel',
|
34
|
+
'TokenModel',
|
35
|
+
)
|