python4cpm 1.1.3__py3-none-any.whl → 1.1.5__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.
Potentially problematic release.
This version of python4cpm might be problematic. Click here for more details.
- python4cpm/__init__.py +2 -2
- python4cpm/accounts.py +28 -1
- python4cpm/args.py +1 -1
- python4cpm/{nethelper.py → devhelper.py} +10 -6
- python4cpm/logger.py +10 -10
- python4cpm/python4cpm.py +11 -3
- python4cpm/python4cpmhandler.py +0 -3
- {python4cpm-1.1.3.dist-info → python4cpm-1.1.5.dist-info}/METADATA +71 -99
- python4cpm-1.1.5.dist-info/RECORD +15 -0
- python4cpm-1.1.3.dist-info/RECORD +0 -15
- {python4cpm-1.1.3.dist-info → python4cpm-1.1.5.dist-info}/WHEEL +0 -0
- {python4cpm-1.1.3.dist-info → python4cpm-1.1.5.dist-info}/licenses/LICENSE +0 -0
- {python4cpm-1.1.3.dist-info → python4cpm-1.1.5.dist-info}/top_level.txt +0 -0
python4cpm/__init__.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
from python4cpm.python4cpm import Python4CPM
|
|
2
2
|
from python4cpm.python4cpmhandler import Python4CPMHandler
|
|
3
|
-
from python4cpm.
|
|
3
|
+
from python4cpm.devhelper import DevHelper
|
|
4
4
|
from importlib.metadata import version as __version
|
|
5
5
|
|
|
6
6
|
__version__ = __version(__name__)
|
|
@@ -8,5 +8,5 @@ __version__ = __version(__name__)
|
|
|
8
8
|
__all__ = [
|
|
9
9
|
Python4CPM,
|
|
10
10
|
Python4CPMHandler,
|
|
11
|
-
|
|
11
|
+
DevHelper
|
|
12
12
|
]
|
python4cpm/accounts.py
CHANGED
|
@@ -31,10 +31,22 @@ class BaseAccount(EnvHandler):
|
|
|
31
31
|
|
|
32
32
|
class TargetAccount(BaseAccount):
|
|
33
33
|
OBJ_PREFIX = "target_"
|
|
34
|
-
PROPS = Props(
|
|
34
|
+
PROPS = Props(
|
|
35
|
+
"policy_id",
|
|
36
|
+
"safe_name",
|
|
37
|
+
"object_name",
|
|
38
|
+
"username",
|
|
39
|
+
"password",
|
|
40
|
+
"address",
|
|
41
|
+
"port",
|
|
42
|
+
"new_password"
|
|
43
|
+
)
|
|
35
44
|
|
|
36
45
|
def __init__(
|
|
37
46
|
self,
|
|
47
|
+
policy_id: str | None,
|
|
48
|
+
safe_name: str | None,
|
|
49
|
+
object_name: str | None,
|
|
38
50
|
username: str | None,
|
|
39
51
|
password: str | None,
|
|
40
52
|
address: str | None,
|
|
@@ -45,10 +57,25 @@ class TargetAccount(BaseAccount):
|
|
|
45
57
|
username,
|
|
46
58
|
password
|
|
47
59
|
)
|
|
60
|
+
self._policy_id = policy_id
|
|
61
|
+
self._safe_name = safe_name
|
|
62
|
+
self._object_name = object_name
|
|
48
63
|
self._address = address
|
|
49
64
|
self._port = port
|
|
50
65
|
self._new_password = Secret.from_env_var(new_password)
|
|
51
66
|
|
|
67
|
+
@property
|
|
68
|
+
def policy_id(self) -> str | None:
|
|
69
|
+
return self._policy_id
|
|
70
|
+
|
|
71
|
+
@property
|
|
72
|
+
def safe_name(self) -> str | None:
|
|
73
|
+
return self._safe_name
|
|
74
|
+
|
|
75
|
+
@property
|
|
76
|
+
def object_name(self) -> str | None:
|
|
77
|
+
return self._object_name
|
|
78
|
+
|
|
52
79
|
@property
|
|
53
80
|
def address(self) -> str | None:
|
|
54
81
|
return self._address
|
python4cpm/args.py
CHANGED
|
@@ -1,16 +1,18 @@
|
|
|
1
|
-
from python4cpm.python4cpm import Python4CPM
|
|
2
1
|
from python4cpm.args import Args
|
|
3
2
|
from python4cpm.accounts import TargetAccount, LogonAccount, ReconcileAccount
|
|
4
3
|
from python4cpm.crypto import Crypto
|
|
5
4
|
import os
|
|
6
5
|
|
|
7
6
|
|
|
8
|
-
class
|
|
7
|
+
class DevHelper:
|
|
9
8
|
@classmethod
|
|
10
9
|
def set(
|
|
11
10
|
cls,
|
|
12
11
|
action: str | None = None,
|
|
13
12
|
logging_level: str | None = None,
|
|
13
|
+
target_policy_id: str | None = None,
|
|
14
|
+
target_safe_name: str | None = None,
|
|
15
|
+
target_object_name: str | None = None,
|
|
14
16
|
target_username: str | None = None,
|
|
15
17
|
target_address: str | None = None,
|
|
16
18
|
target_port: str | None = None,
|
|
@@ -29,6 +31,9 @@ class NETHelper:
|
|
|
29
31
|
keys = (
|
|
30
32
|
Args.get_key(Args.PROPS.action),
|
|
31
33
|
Args.get_key(Args.PROPS.logging_level),
|
|
34
|
+
TargetAccount.get_key(TargetAccount.PROPS.policy_id),
|
|
35
|
+
TargetAccount.get_key(TargetAccount.PROPS.safe_name),
|
|
36
|
+
TargetAccount.get_key(TargetAccount.PROPS.object_name),
|
|
32
37
|
TargetAccount.get_key(TargetAccount.PROPS.username),
|
|
33
38
|
TargetAccount.get_key(TargetAccount.PROPS.address),
|
|
34
39
|
TargetAccount.get_key(TargetAccount.PROPS.port),
|
|
@@ -42,6 +47,9 @@ class NETHelper:
|
|
|
42
47
|
values = (
|
|
43
48
|
action,
|
|
44
49
|
logging_level,
|
|
50
|
+
target_policy_id,
|
|
51
|
+
target_safe_name,
|
|
52
|
+
target_object_name,
|
|
45
53
|
target_username,
|
|
46
54
|
target_address,
|
|
47
55
|
target_port,
|
|
@@ -55,7 +63,3 @@ class NETHelper:
|
|
|
55
63
|
for i, key in enumerate(keys):
|
|
56
64
|
if values[i] is not None:
|
|
57
65
|
os.environ.update({key: values[i]})
|
|
58
|
-
|
|
59
|
-
@classmethod
|
|
60
|
-
def get(cls) -> Python4CPM:
|
|
61
|
-
return Python4CPM(cls.__name__)
|
python4cpm/logger.py
CHANGED
|
@@ -12,7 +12,7 @@ class Logger:
|
|
|
12
12
|
"info": logging.INFO,
|
|
13
13
|
"debug": logging.DEBUG
|
|
14
14
|
}
|
|
15
|
-
_DEFAULT_LEVEL =
|
|
15
|
+
_DEFAULT_LEVEL = "error"
|
|
16
16
|
|
|
17
17
|
@classmethod
|
|
18
18
|
def get_logger(
|
|
@@ -21,21 +21,21 @@ class Logger:
|
|
|
21
21
|
logging_level: str | None
|
|
22
22
|
) -> logging.Logger:
|
|
23
23
|
os.makedirs(cls._LOGS_DIR, exist_ok=True)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
24
|
+
uid = os.urandom(4).hex()
|
|
25
|
+
logger = logging.getLogger(uid)
|
|
26
|
+
_logging_level = (logging_level or cls._DEFAULT_LEVEL).lower()
|
|
27
|
+
if _logging_level not in cls._LOGGING_LEVELS:
|
|
28
|
+
_logging_level = cls._DEFAULT_LEVEL
|
|
29
|
+
logger.setLevel(cls._LOGGING_LEVELS[_logging_level])
|
|
30
|
+
file_name = f"{__name__}_{_logging_level}_{name}_{uid}.log"
|
|
31
|
+
logs_file = os.path.join(cls._LOGS_DIR, file_name)
|
|
32
32
|
handler = RotatingFileHandler(
|
|
33
33
|
filename=logs_file,
|
|
34
34
|
maxBytes=1024 ** 2,
|
|
35
35
|
backupCount=1
|
|
36
36
|
)
|
|
37
37
|
fmt = (
|
|
38
|
-
"%(asctime)s.%(msecs)03d | %(levelname)s |
|
|
38
|
+
"%(asctime)s.%(msecs)03d | %(levelname)s | "
|
|
39
39
|
"%(module)s | %(funcName)s | %(message)s"
|
|
40
40
|
)
|
|
41
41
|
datefmt = "%Y-%m-%d %H:%M:%S"
|
python4cpm/python4cpm.py
CHANGED
|
@@ -24,13 +24,12 @@ class Python4CPM:
|
|
|
24
24
|
_FAILED_RECOVERABLE_CODE = 81
|
|
25
25
|
_FAILED_UNRECOVERABLE_CODE = 89
|
|
26
26
|
|
|
27
|
-
def __init__(self
|
|
28
|
-
self._name = name
|
|
27
|
+
def __init__(self) -> None:
|
|
29
28
|
self._args = Args.get()
|
|
30
29
|
self._target_account = TargetAccount.get()
|
|
31
30
|
self._logon_account = LogonAccount.get()
|
|
32
31
|
self._reconcile_account = ReconcileAccount.get()
|
|
33
|
-
self._logger =
|
|
32
|
+
self._logger = self._get_logger()
|
|
34
33
|
self._logger.debug("Initiating...")
|
|
35
34
|
self._log_obj(self._args)
|
|
36
35
|
self._verify_action()
|
|
@@ -60,6 +59,15 @@ class Python4CPM:
|
|
|
60
59
|
def reconcile_account(self) -> ReconcileAccount:
|
|
61
60
|
return self._reconcile_account
|
|
62
61
|
|
|
62
|
+
def _get_logger(self) -> logging.Logger:
|
|
63
|
+
name_parts = (
|
|
64
|
+
self._target_account.policy_id,
|
|
65
|
+
self._target_account.safe_name,
|
|
66
|
+
self._target_account.object_name
|
|
67
|
+
)
|
|
68
|
+
name = "-".join(name_parts)
|
|
69
|
+
return Logger.get_logger(name, self._args.logging_level)
|
|
70
|
+
|
|
63
71
|
def _verify_action(self) -> None:
|
|
64
72
|
if self._args.action not in self._VALID_ACTIONS:
|
|
65
73
|
self._logger.warning(f"Unkonwn action -> '{self._args.action}'")
|
python4cpm/python4cpmhandler.py
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: python4cpm
|
|
3
|
-
Version: 1.1.
|
|
3
|
+
Version: 1.1.5
|
|
4
4
|
Summary: Python for CPM
|
|
5
5
|
Author-email: Gonzalo Atienza Rela <gonatienza@gmail.com>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -19,7 +19,7 @@ This module leverages the [Credential Management .NET SDK](https://docs.cyberark
|
|
|
19
19
|
|
|
20
20
|
All objects are collected from the SDK and sent as environment context to be picked up by the `python4cpm` module during the subprocess execution of python. All secrets of such environment are protected and encrypted by [Data Protection API (DPAPI)](https://learn.microsoft.com/en-us/dotnet/standard/security/how-to-use-data-protection), until they are explicitely retrieved in your python script runtime, invoking the `Secret.get()` method. Finally, python controls the termination signal sent back to the SDK, which is consequently used as the return code to CPM/SRS. Such as a successful or failed (recoverable or not) result of the requested action.
|
|
21
21
|
|
|
22
|
-
This platform allows you to duplicate it multiple times, simply changing its settings (
|
|
22
|
+
This platform allows you to duplicate it multiple times, simply changing its settings (from Privilege Cloud/PVWA) to point to different venvs and/or python scripts.
|
|
23
23
|
|
|
24
24
|
## Installation
|
|
25
25
|
|
|
@@ -67,105 +67,83 @@ This platform allows you to duplicate it multiple times, simply changing its set
|
|
|
67
67
|
from python4cpm import Python4CPMHandler
|
|
68
68
|
|
|
69
69
|
|
|
70
|
-
class
|
|
70
|
+
class CredManager(Python4CPMHandler):
|
|
71
71
|
"""
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
self.logon_account.password.get()
|
|
94
|
-
|
|
95
|
-
## Reconcile Account
|
|
96
|
-
self.reconcile_account.username
|
|
97
|
-
self.reconcile_account.password.get()
|
|
98
|
-
|
|
99
|
-
## Logging
|
|
100
|
-
|
|
101
|
-
self.logger.critical("this is critical message")
|
|
102
|
-
self.logger.error("this is an error message")
|
|
103
|
-
self.logger.warning("this is a warning message")
|
|
104
|
-
self.logger.info("this is an info message")
|
|
105
|
-
self.logger.debug("this is a debug message")
|
|
106
|
-
|
|
107
|
-
# The logging level comes from PythonLoggingLevel (platform parameters) (default is error)
|
|
108
|
-
|
|
109
|
-
=============================
|
|
110
|
-
REQUIRED TERMINATION SIGNALS
|
|
111
|
-
=============================
|
|
112
|
-
Terminate signals -> MUST use one of the following three signals to terminate the script:
|
|
113
|
-
|
|
114
|
-
self.close_success()
|
|
115
|
-
# terminate and provide CPM/SRS with a success state
|
|
116
|
-
|
|
117
|
-
self.close_fail()
|
|
118
|
-
# terminate and provide CPM/SRS with a failed recoverable state
|
|
119
|
-
|
|
120
|
-
self.close_fail(unrecoverable=True)
|
|
121
|
-
# terminate and provide CPM/SRS with a failed unrecoverable state
|
|
122
|
-
|
|
123
|
-
When calling a signal sys.exit is invoked and the script is terminated.
|
|
124
|
-
If no signal is called, and the script finishes without any exception,
|
|
125
|
-
it will behave like p4cpm.close_fail(unrecoverable=True) and log an error message.
|
|
126
|
-
|
|
127
|
-
=============================
|
|
128
|
-
REQUIRED METHODS
|
|
129
|
-
=============================
|
|
130
|
-
verify(), logon(), change(), prereconcile(), reconcile()
|
|
72
|
+
Properties:
|
|
73
|
+
target_account (TargetAccount): Account being managed.
|
|
74
|
+
.username (str): Account username.
|
|
75
|
+
.address (str): Target address.
|
|
76
|
+
.port (str): Target port.
|
|
77
|
+
.password (Secret): Current password. Call .get() to retrieve value.
|
|
78
|
+
.new_password (Secret): Replacement password. Call .get() to retrieve value.
|
|
79
|
+
|
|
80
|
+
logon_account (LogonAccount): Linked Logon Account.
|
|
81
|
+
.username (str): Account username.
|
|
82
|
+
.password (Secret): Logon password. Call .get() to retrieve value.
|
|
83
|
+
|
|
84
|
+
reconcile_account (ReconcileAccount): Linked Reconcile Account.
|
|
85
|
+
.username (str): Account username.
|
|
86
|
+
.password (Secret): Reconcile password. Call .get() to retrieve value.
|
|
87
|
+
|
|
88
|
+
logger (logging.Logger): Logger instance.
|
|
89
|
+
|
|
90
|
+
Methods:
|
|
91
|
+
close_success(): Signal successful completion and terminate.
|
|
92
|
+
close_fail(): Signal failed completion and terminate.
|
|
131
93
|
"""
|
|
132
94
|
|
|
95
|
+
|
|
133
96
|
def verify(self):
|
|
97
|
+
"""
|
|
98
|
+
REQUIRED METHOD
|
|
99
|
+
"""
|
|
134
100
|
# TODO: use account objects for your logic
|
|
135
101
|
self.close_success()
|
|
136
102
|
|
|
137
103
|
def logon(self):
|
|
104
|
+
"""
|
|
105
|
+
REQUIRED METHOD
|
|
106
|
+
"""
|
|
138
107
|
# TODO: use account objects for your logic
|
|
139
108
|
self.close_success()
|
|
140
109
|
|
|
141
110
|
def change(self):
|
|
111
|
+
"""
|
|
112
|
+
REQUIRED METHOD
|
|
113
|
+
"""
|
|
142
114
|
# TODO: use account objects for your logic
|
|
143
115
|
self.close_success()
|
|
144
116
|
|
|
145
117
|
def prereconcile(self):
|
|
118
|
+
"""
|
|
119
|
+
REQUIRED METHOD
|
|
120
|
+
"""
|
|
146
121
|
# TODO: use account objects for your logic
|
|
147
122
|
self.close_success()
|
|
148
123
|
|
|
149
124
|
def reconcile(self):
|
|
125
|
+
"""
|
|
126
|
+
REQUIRED METHOD
|
|
127
|
+
"""
|
|
150
128
|
# TODO: use account objects for your logic
|
|
151
129
|
self.close_success()
|
|
152
130
|
|
|
153
131
|
|
|
154
132
|
if __name__ == "__main__":
|
|
155
|
-
|
|
133
|
+
CredManager().run() # initializes the class and calls the action that was requested from CPM/SRS.
|
|
156
134
|
```
|
|
157
135
|
(*) More realistic examples can be found [here](https://github.com/gonatienza/python4cpm/blob/main/examples).
|
|
158
136
|
|
|
159
137
|
When doing `verify`, `change` or `reconcile` from Privilege Cloud/PVWA:
|
|
160
|
-
1. Verify -> the
|
|
161
|
-
2. Change -> the
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
138
|
+
1. Verify -> the script will be executed once running the `verify()` method.
|
|
139
|
+
2. Change -> the script will be executed twice: first `logon()`, then `change()`.
|
|
140
|
+
3. Reconcile -> the script will be executed twice: first `prereconcile()`, then `reconcile()`.
|
|
141
|
+
4. When calling `verify()`, `logon()` or `prereconcile()`: `target_account.new_password` will always return `None`.
|
|
142
|
+
5. If a logon account is not linked, `logon_account` will return `None`.
|
|
143
|
+
6. If a reconcile account is not linked, `reconcile_account` will return `None`.
|
|
144
|
+
7. Always use the `close_success` or `close_fail` methods to signal the proper termination for all actions.
|
|
145
|
+
- If any action is not terminated with a termination method, CPM/SRS will see this as a `close_fail(unrecoverable=True)`, even if no exceptions are raised.
|
|
146
|
+
8. The python `Logger` places its logs in the `Logs/ThirdParty` directory.
|
|
169
147
|
|
|
170
148
|
|
|
171
149
|
### Installing dependencies in python venv
|
|
@@ -179,40 +157,35 @@ As with any python venv, you can install dependencies in your venv.
|
|
|
179
157
|
|
|
180
158
|
## Dev Helper:
|
|
181
159
|
|
|
182
|
-
For dev purposes, `
|
|
160
|
+
For dev purposes, `DevHelper` is a companion helper to test your scripts without CPM/SRS. It simplifies the instantiation of the `Python4CPM` or `Python4CPMHandler` objects by simulating how the plugin creates the environment context for the python module.
|
|
183
161
|
|
|
184
|
-
**Note**: As CPM and the SRS management agent run in Windows, the plugin was built to encrypt secrets using DPAPI (a windows only library). For dev purposes in Linux/Mac dev workstations, those secrets put in the environment context by `
|
|
162
|
+
**Note**: As CPM and the SRS management agent run in Windows, the plugin was built to encrypt secrets using DPAPI (a windows only library). For dev purposes in Linux/Mac dev workstations, those secrets put in the environment context by `DevHelper` will be in plaintext. In windows dev workstations, `DevHelper` encrypts the secrets as the .NET plugin does. This is informational only, **the module will use its encryption/decryption capabilities automatically based on the platform** it is running on and you do not have to do anything specific to enable it.
|
|
185
163
|
|
|
186
164
|
### Example:
|
|
187
165
|
|
|
188
166
|
#### Set your arguments and secrets:
|
|
189
167
|
|
|
190
168
|
```python
|
|
191
|
-
from python4cpm import
|
|
192
|
-
from getpass import getpass
|
|
193
|
-
|
|
194
|
-
# Get secrets for your password, logon account password, reconcile account password and new password
|
|
195
|
-
# You may set to None any argument that does not apply or simply leaving it to its default None value.
|
|
196
|
-
target_password = getpass("password: ") # password from account
|
|
197
|
-
logon_password = getpass("logon_password: ") # password from linked logon account
|
|
198
|
-
reconcile_password = getpass("reconcile_password: ") # password from linked reconcile account
|
|
199
|
-
target_new_password = getpass("new_password: ") # new password for the rotation
|
|
169
|
+
from python4cpm import DevHelper, Python4CPM, Python4CPMHandler
|
|
200
170
|
|
|
201
|
-
|
|
171
|
+
DevHelper.set(
|
|
202
172
|
action=Python4CPM.ACTION_CHANGE, # use actions from Python4CPM.ACTION_*
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
173
|
+
logging_level="debug",
|
|
174
|
+
target_policy_id="DevHelper", # name of platform
|
|
175
|
+
target_safe_name="Safename", # name of safe
|
|
176
|
+
target_object_name="Objectname", # name of account
|
|
177
|
+
target_username="jdoe",
|
|
178
|
+
target_address="myapp.corp.local",
|
|
179
|
+
target_port="8443",
|
|
180
|
+
logon_username="ldoe",
|
|
181
|
+
reconcile_username="rdoe",
|
|
182
|
+
target_password="", # str value of target password
|
|
183
|
+
logon_password="", # str value of logon password
|
|
184
|
+
reconcile_password="", # str value of reconcile password
|
|
185
|
+
target_new_password="" # str value of new password
|
|
213
186
|
)
|
|
214
187
|
|
|
215
|
-
class
|
|
188
|
+
class CredManager(Python4CPMHandler):
|
|
216
189
|
def verify(self):
|
|
217
190
|
# TODO: Add your logic here
|
|
218
191
|
self.close_success()
|
|
@@ -233,11 +206,10 @@ class MyRotator(Python4CPMHandler):
|
|
|
233
206
|
# TODO: Add your logic here
|
|
234
207
|
self.close_success()
|
|
235
208
|
|
|
236
|
-
|
|
209
|
+
CredManager().run()
|
|
237
210
|
```
|
|
238
211
|
|
|
239
212
|
#### Remember for your final script:
|
|
240
213
|
|
|
241
|
-
- Remove the import of `
|
|
242
|
-
- Remove the `
|
|
243
|
-
- Remove any secrets prompting or interactive interruptions.
|
|
214
|
+
- Remove the import of `DevHelper`.
|
|
215
|
+
- Remove the `DevHelper.set()` call.
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
python4cpm/__init__.py,sha256=GQvsXZY2escF3zucv3d68s2ydqHSIYi5tnNDCkhTjcM,302
|
|
2
|
+
python4cpm/accounts.py,sha256=tzLr6kFeHD6jDF-dZXjp2FeoABFsWn2hp4bO5uYN2Zg,2201
|
|
3
|
+
python4cpm/args.py,sha256=PQDDlMakP-YsDLd3HdwIZtxVpIM4m4aHl2GuRj9kHpI,504
|
|
4
|
+
python4cpm/crypto.py,sha256=AKjmCVkuQRxomhuQJ8b5IN5QPc8n9aAMui99ZEgnGAg,2388
|
|
5
|
+
python4cpm/devhelper.py,sha256=iv5zHSMyMNMdksGkkTh_8c_ObocJfQormQ4S3nZzo0Y,2609
|
|
6
|
+
python4cpm/envhandler.py,sha256=mNDOaYVemmxKREXyOf7IuQdFDXrvZ7f_7sNaqWV7TsI,678
|
|
7
|
+
python4cpm/logger.py,sha256=XmuCY1Guxyo5aNKfnueLZY55_UePtH-FFysxXiTPjTE,1456
|
|
8
|
+
python4cpm/python4cpm.py,sha256=-zgvLHnnnvwnmSxTwizdtHwKJPK7DcsUZIHES5Q6sR8,3449
|
|
9
|
+
python4cpm/python4cpmhandler.py,sha256=SXKsnFAwUp8cHEhv2TygpNpptUkN3bVQZt1i-3TWql4,935
|
|
10
|
+
python4cpm/secret.py,sha256=Z2K8H406lViOLPJKklffScug6sdWoxt0T5jhX0EA_gI,572
|
|
11
|
+
python4cpm-1.1.5.dist-info/licenses/LICENSE,sha256=vF2wZA3GchZjH5lUmhonEwd4snuBc6o0ytpZNxVFyCw,1077
|
|
12
|
+
python4cpm-1.1.5.dist-info/METADATA,sha256=UD0JHnDBBH-6lT34jN4TyJL6K7n7m2AzsZ_ThQTfS8g,11193
|
|
13
|
+
python4cpm-1.1.5.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
14
|
+
python4cpm-1.1.5.dist-info/top_level.txt,sha256=EhbshwpANmL0wYXaET8_6V9ZENtSwIyAd-kM3jGhUlE,11
|
|
15
|
+
python4cpm-1.1.5.dist-info/RECORD,,
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
python4cpm/__init__.py,sha256=Z5UI6SPWKeegUkQ_YqMKTuYNIiDvgg5BmynCMJxpPaI,302
|
|
2
|
-
python4cpm/accounts.py,sha256=zCyPpbqAECj5_mak7PsRnsWA5-a9j7BwOVHcEbDdEVU,1624
|
|
3
|
-
python4cpm/args.py,sha256=2Td9rxbe7KDRv234l0yVtIYezd5X2DE7Jo9EseDrlKM,497
|
|
4
|
-
python4cpm/crypto.py,sha256=AKjmCVkuQRxomhuQJ8b5IN5QPc8n9aAMui99ZEgnGAg,2388
|
|
5
|
-
python4cpm/envhandler.py,sha256=mNDOaYVemmxKREXyOf7IuQdFDXrvZ7f_7sNaqWV7TsI,678
|
|
6
|
-
python4cpm/logger.py,sha256=H8yoJ0GrI9OJful0nT3t1HwBbn-BVEn2q7Z2CDjOs1o,1475
|
|
7
|
-
python4cpm/nethelper.py,sha256=iGbqQ8yt1T_GQSebG6u46caJzqE--dyCcws1XeCE99A,2315
|
|
8
|
-
python4cpm/python4cpm.py,sha256=BpyPdhRftkcPWZwank8FAsM8x3mY4AwCGyA5xW79cZo,3210
|
|
9
|
-
python4cpm/python4cpmhandler.py,sha256=zIhDVLinwnRqdef2Dz9wWPdDWFwOere6CZoAhgeHPoU,1018
|
|
10
|
-
python4cpm/secret.py,sha256=Z2K8H406lViOLPJKklffScug6sdWoxt0T5jhX0EA_gI,572
|
|
11
|
-
python4cpm-1.1.3.dist-info/licenses/LICENSE,sha256=vF2wZA3GchZjH5lUmhonEwd4snuBc6o0ytpZNxVFyCw,1077
|
|
12
|
-
python4cpm-1.1.3.dist-info/METADATA,sha256=lKEQaRuJ4U-wzmTzz7zLCpqdGGg6vB8jBvype21BUio,13308
|
|
13
|
-
python4cpm-1.1.3.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
|
|
14
|
-
python4cpm-1.1.3.dist-info/top_level.txt,sha256=EhbshwpANmL0wYXaET8_6V9ZENtSwIyAd-kM3jGhUlE,11
|
|
15
|
-
python4cpm-1.1.3.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|