Skip to content

Commit f3fb4a9

Browse files
author
Juliya Smith
authored
Feature/support new search params (#8)
1 parent 942f32e commit f3fb4a9

30 files changed

+958
-594
lines changed

CHANGELOG.md

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,33 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
88
The intended audience of this file is for py42 consumers -- as such, changes that don't affect
99
how a consumer would use the library (e.g. adding unit tests, updating documentation, etc) are not captured here.
1010

11-
## Unreleased
11+
## 0.3.0 - 2020-03-04
1212

1313
### Added
1414

1515
- Begin and end date now support specifying time: `code42 securitydata print -b 2020-02-02 12:00:00`.
16+
- New search arguments for `print`, `write-to`, and `send-to`:
17+
- `--c42username`
18+
- `--actor`
19+
- `--md5`
20+
- `--sha256`
21+
- `--source`
22+
- `--filename`
23+
- `--filepath`
24+
- `--processOwner`
25+
- `--tabURL`
26+
- `--include-non-exposure`
27+
28+
### Changed
29+
30+
- It is no longer required to store your password in your profile,
31+
and you will be prompted to enter your password at runtime if you don't.
32+
- You will be asked if you would like to set a password after using `code42cli profile set`.
33+
- Begin date is now required for `securitydata` `print`, `write-to`, and `send-to` commands.
34+
35+
### Removed
36+
37+
- Removed `--show` flag from `code42 profile set` command. Just use `code42 profile show`.
1638

1739
## 0.2.0 - 2020-02-25
1840

README.md

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# The Code42 CLI
22

33
Use the `code42` command to interact with your Code42 environment.
4-
`code42 securitydata` is a CLI tool for extracting AED events.
4+
`code42 securitydata` is a CLI tool for extracting AED events.
55
Additionally, `code42 securitydata` can record a checkpoint so that you only get events you have not previously gotten.
66

77
## Requirements
@@ -23,15 +23,11 @@ First, set your profile:
2323
code42 profile set -s https://example.authority.com -u [email protected]
2424
```
2525
Your profile contains the necessary properties for logging into Code42 servers.
26-
You will prompted for a password if there is not one saved for your current username/authority URL combination.
27-
28-
To explicitly set your password, use `-p`:
29-
```bash
30-
code42 profile set -p
31-
```
32-
You will be securely prompted to input your password.
26+
After running this `code42 profile set`, you will be prompted about storing a password.
27+
If you agree, you will be securely prompted to input your password.
3328
Your password is not stored in plain-text, and is not shown when you do `code42 profile show`.
3429
However, `code42 profile show` will confirm that there is a password set for your profile.
30+
If you do not set a password, you will be securely prompted to enter a password each time you run a command.
3531

3632
To ignore SSL errors, do:
3733
```bash
@@ -67,6 +63,16 @@ Each destination-type subcommand shares query parameters
6763
* `-t` (exposure types)
6864
* `-b` (begin date)
6965
* `-e` (end date)
66+
* `--c42username`
67+
* `--actor`
68+
* `--md5`
69+
* `--sha256`
70+
* `--source`
71+
* `--filename`
72+
* `--filepath`
73+
* `--processOwner`
74+
* `--tabURL`
75+
* `--include-non-exposure` (does not work with `-t`)
7076
* `--advanced-query` (raw JSON query)
7177

7278
Note that you cannot use other query parameters if you use `--advanced-query`.

setup.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
packages=find_packages("src"),
2121
package_dir={"": "src"},
2222
python_requires=">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, <4",
23-
install_requires=["c42eventextractor==0.2.0", "keyring==18.0.1","py42==0.5.1"],
23+
install_requires=["c42eventextractor==0.2.1", "keyring==18.0.1","py42==0.5.1"],
2424
license="MIT",
2525
include_package_data=True,
2626
zip_safe=False,

src/code42cli/__version__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
__version__ = "0.2.0"
1+
__version__ = "0.3.0"

src/code42cli/main.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@ def main():
1010
subcommand_parser = code42_arg_parser.add_subparsers()
1111
profile.init(subcommand_parser)
1212
securitydata.init_subcommand(subcommand_parser)
13-
_call_subcommand(code42_arg_parser)
13+
_run(code42_arg_parser)
1414

1515

16-
def _call_subcommand(parser):
16+
def _run(parser):
1717
try:
1818
args = parser.parse_args()
1919
args.func(args)

src/code42cli/profile/config.py

Lines changed: 42 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@
66
import code42cli.util as util
77

88

9+
_DEFAULT_VALUE = u"__DEFAULT__"
10+
11+
912
class ConfigurationKeys(object):
1013
USER_SECTION = u"Code42"
1114
AUTHORITY_KEY = u"c42_authority_url"
@@ -16,33 +19,37 @@ class ConfigurationKeys(object):
1619

1720

1821
def get_config_profile():
22+
"""Get your config file profile."""
1923
parser = ConfigParser()
2024
if not profile_has_been_set():
21-
util.print_error("Profile is not set.")
22-
print("")
23-
print("To set, use: ")
24-
util.print_bold("\tcode42 profile set -s <authority-URL> -u <username>")
25-
print("")
25+
util.print_error(u"Profile has not completed setup.")
26+
print(u"")
27+
print(u"To set, use: ")
28+
util.print_bold(u"\tcode42 profile set -s <authority-URL> -u <username>")
29+
print(u"")
2630
exit(1)
2731

2832
return _get_config_profile_from_parser(parser)
2933

3034

31-
def mark_as_set():
35+
def profile_has_been_set():
36+
"""Whether you have, at one point in time, set your username and authority server URL."""
3237
parser = ConfigParser()
3338
config_file_path = _get_config_file_path()
3439
parser.read(config_file_path)
3540
settings = parser[ConfigurationKeys.INTERNAL_SECTION]
36-
settings[ConfigurationKeys.HAS_SET_PROFILE_KEY] = "True"
37-
_save(parser, ConfigurationKeys.HAS_SET_PROFILE_KEY)
41+
return settings.getboolean(ConfigurationKeys.HAS_SET_PROFILE_KEY)
3842

3943

40-
def profile_has_been_set():
44+
def mark_as_set_if_complete():
45+
if not _profile_can_be_set():
46+
return
4147
parser = ConfigParser()
4248
config_file_path = _get_config_file_path()
4349
parser.read(config_file_path)
4450
settings = parser[ConfigurationKeys.INTERNAL_SECTION]
45-
return settings.getboolean(ConfigurationKeys.HAS_SET_PROFILE_KEY)
51+
settings[ConfigurationKeys.HAS_SET_PROFILE_KEY] = u"True"
52+
_save(parser, ConfigurationKeys.HAS_SET_PROFILE_KEY)
4653

4754

4855
def set_username(new_username):
@@ -66,22 +73,31 @@ def set_ignore_ssl_errors(new_value):
6673
_save(parser, ConfigurationKeys.IGNORE_SSL_ERRORS_KEY)
6774

6875

69-
def _get_config_file_path():
70-
path = "{}config.cfg".format(util.get_user_project_path())
71-
if not os.path.exists(path) or not _verify_config_file(path):
72-
_create_new_config_file(path)
73-
74-
return path
76+
def _profile_can_be_set():
77+
"""Whether your current username and authority URL are set,
78+
but your profile has not been marked as set.
79+
"""
80+
parser = ConfigParser()
81+
profile = _get_config_profile_from_parser(parser)
82+
username = profile[ConfigurationKeys.USERNAME_KEY]
83+
authority = profile[ConfigurationKeys.AUTHORITY_KEY]
84+
return username != _DEFAULT_VALUE and authority != _DEFAULT_VALUE and not profile_has_been_set()
7585

7686

7787
def _get_config_profile_from_parser(parser):
7888
config_file_path = _get_config_file_path()
7989
parser.read(config_file_path)
8090
config = parser[ConfigurationKeys.USER_SECTION]
81-
config.ignore_ssl_errors = config.getboolean(ConfigurationKeys.IGNORE_SSL_ERRORS_KEY)
8291
return config
8392

8493

94+
def _get_config_file_path():
95+
path = u"{}config.cfg".format(util.get_user_project_path())
96+
if not os.path.exists(path) or not _verify_config_file(path):
97+
_create_new_config_file(path)
98+
return path
99+
100+
85101
def _create_new_config_file(path):
86102
config_parser = ConfigParser()
87103
config_parser = _create_user_section(config_parser)
@@ -93,25 +109,28 @@ def _create_user_section(parser):
93109
keys = ConfigurationKeys
94110
parser.add_section(keys.USER_SECTION)
95111
parser[keys.USER_SECTION] = {}
96-
parser[keys.USER_SECTION][keys.AUTHORITY_KEY] = "null"
97-
parser[keys.USER_SECTION][keys.USERNAME_KEY] = "null"
98-
parser[keys.USER_SECTION][keys.IGNORE_SSL_ERRORS_KEY] = "False"
112+
parser[keys.USER_SECTION][keys.AUTHORITY_KEY] = _DEFAULT_VALUE
113+
parser[keys.USER_SECTION][keys.USERNAME_KEY] = _DEFAULT_VALUE
114+
parser[keys.USER_SECTION][keys.IGNORE_SSL_ERRORS_KEY] = u"False"
99115
return parser
100116

101117

102118
def _create_internal_section(parser):
103119
keys = ConfigurationKeys
104120
parser.add_section(keys.INTERNAL_SECTION)
105121
parser[keys.INTERNAL_SECTION] = {}
106-
parser[keys.INTERNAL_SECTION][keys.HAS_SET_PROFILE_KEY] = "False"
122+
parser[keys.INTERNAL_SECTION][keys.HAS_SET_PROFILE_KEY] = u"False"
107123
return parser
108124

109125

110126
def _save(parser, key=None, path=None):
111127
path = _get_config_file_path() if path is None else path
112-
util.open_file(path, "w+", lambda f: parser.write(f))
128+
util.open_file(path, u"w+", lambda f: parser.write(f))
113129
if key is not None:
114-
print("'{}' has been successfully updated".format(key))
130+
if key == ConfigurationKeys.HAS_SET_PROFILE_KEY:
131+
print(u"You have completed setting up your profile!")
132+
else:
133+
print(u"'{}' has been successfully updated".format(key))
115134

116135

117136
def _verify_config_file(path):

src/code42cli/profile/password.py

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,32 +9,33 @@
99
_ROOT_SERVICE_NAME = u"code42cli"
1010

1111

12-
def get_password(prompt_if_not_exists=True):
12+
def get_password():
1313
"""Gets your currently stored password for your username / authority URL combo."""
1414
profile = config.get_config_profile()
1515
service_name = _get_service_name(profile)
1616
username = _get_username(profile)
1717
password = keyring.get_password(service_name, username)
18-
if password is None and prompt_if_not_exists:
19-
return set_password()
20-
2118
return password
2219

2320

24-
def set_password():
21+
def set_password_from_prompt():
2522
"""Prompts and sets your password for your username / authority URL combo."""
2623
password = getpass()
2724
profile = config.get_config_profile()
2825
service_name = _get_service_name(profile)
2926
username = _get_username(profile)
3027
keyring.set_password(service_name, username, password)
31-
print("'Code42 Password' updated.")
28+
print(u"'Code42 Password' updated.")
3229
return password
3330

3431

32+
def get_password_from_prompt():
33+
return getpass()
34+
35+
3536
def _get_service_name(profile):
3637
authority_url = profile[ConfigurationKeys.AUTHORITY_KEY]
37-
return "{}::{}".format(_ROOT_SERVICE_NAME, authority_url)
38+
return u"{}::{}".format(_ROOT_SERVICE_NAME, authority_url)
3839

3940

4041
def _get_username(profile):

0 commit comments

Comments
 (0)