mirror of
https://github.com/kellyjonbrazil/jc.git
synced 2025-10-08 23:22:21 +02:00
net-user parser fixup
This commit is contained in:
@@ -74,7 +74,7 @@ Examples:
|
||||
]
|
||||
}
|
||||
|
||||
$ net users /domain | jc --net-user -p | jq
|
||||
$ net users /domain | jc --net-user -p
|
||||
{
|
||||
"account_origin": "\\\\DESKTOP-WIN10-PRO.somecompany.corp",
|
||||
"domain": "somecompany.corp",
|
||||
@@ -121,7 +121,7 @@ Examples:
|
||||
]
|
||||
}
|
||||
|
||||
$ net users Administrator | jc --net-user -p | jq
|
||||
$ net users Administrator | jc --net-user -p
|
||||
{
|
||||
"domain": "",
|
||||
"user_accounts": [
|
||||
@@ -179,12 +179,9 @@ Examples:
|
||||
]
|
||||
}
|
||||
"""
|
||||
|
||||
|
||||
from datetime import datetime
|
||||
import re
|
||||
import jc.utils
|
||||
from jc.exceptions import ParseError
|
||||
|
||||
|
||||
class info():
|
||||
@@ -193,7 +190,7 @@ class info():
|
||||
description = '`net user` command parser'
|
||||
author = 'joehacksalot'
|
||||
author_email = 'joehacksalot@gmail.com'
|
||||
compatible = ['windows']
|
||||
compatible = ['win32']
|
||||
magic_commands = ['net user']
|
||||
tags = ['command']
|
||||
|
||||
@@ -220,14 +217,13 @@ def parse(data, raw=False, quiet=False):
|
||||
|
||||
raw_output = {}
|
||||
if jc.utils.has_data(data):
|
||||
try:
|
||||
raw_output = _parse(data)
|
||||
return raw_output if raw else _process(raw_output)
|
||||
except Exception as e:
|
||||
if not quiet:
|
||||
raise ParseError('Could not parse data due to unexpected format.')
|
||||
return {}
|
||||
|
||||
raw_output = _parse(data)
|
||||
|
||||
if not raw_output:
|
||||
raw_output = {}
|
||||
|
||||
return raw_output if raw else _process(raw_output)
|
||||
|
||||
def _set_if_not_none(output_dict, key, value):
|
||||
if value is not None:
|
||||
output_dict[key] = value
|
||||
@@ -267,7 +263,11 @@ def _process(proc_data):
|
||||
_set_if_not_none(user_account, "password_required", _process_string_is_yes(user_account.get("password_required", None)))
|
||||
_set_if_not_none(user_account, "user_may_change_password", _process_string_is_yes(user_account.get("user_may_change_password", None)))
|
||||
_set_if_not_none(user_account, "last_logon", _process_date(user_account.get("last_logon", None)))
|
||||
return proc_data # No further processing is needed
|
||||
|
||||
if not proc_data:
|
||||
proc_data = {}
|
||||
|
||||
return proc_data
|
||||
|
||||
|
||||
class _PushbackIterator:
|
||||
@@ -339,7 +339,7 @@ def _parse(data):
|
||||
"domain": "",
|
||||
"user_accounts": []
|
||||
}
|
||||
|
||||
|
||||
lines = data.splitlines()
|
||||
lines = [line.rstrip() for line in lines if line.strip() != ""]
|
||||
|
||||
@@ -358,11 +358,11 @@ def _parse(data):
|
||||
elif "User name" in line:
|
||||
line_iter.pushback(line)
|
||||
user_account_keypairs = {}
|
||||
|
||||
|
||||
# Regular expression to match key-value pairs
|
||||
kv_pattern = re.compile(r'^([\w\s\/\'\-]{1,29})\s*(.+)?$')
|
||||
key = None
|
||||
|
||||
|
||||
while True:
|
||||
# Process each line
|
||||
# Break when done
|
||||
@@ -371,7 +371,7 @@ def _parse(data):
|
||||
line = line.strip()
|
||||
if not line:
|
||||
continue # Skip empty lines
|
||||
|
||||
|
||||
match = kv_pattern.match(line)
|
||||
if "The command completed" in line:
|
||||
break
|
||||
@@ -437,5 +437,5 @@ def _parse(data):
|
||||
break
|
||||
else:
|
||||
raise ValueError(f"Unexpected line: {line}")
|
||||
|
||||
|
||||
return result
|
@@ -1,56 +1,112 @@
|
||||
import json
|
||||
import os
|
||||
import unittest
|
||||
import jc.parsers.ipconfig
|
||||
import jc.parsers.net_localgroup
|
||||
import jc.parsers.net_user
|
||||
import json
|
||||
from typing import Dict
|
||||
from jc.parsers.net_user import parse
|
||||
|
||||
THIS_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||
|
||||
|
||||
class MyTests(unittest.TestCase):
|
||||
test_files = [
|
||||
"tests/fixtures/windows/windows-xp/net_user",
|
||||
"tests/fixtures/windows/windows-xp/net_user.administrator",
|
||||
"tests/fixtures/windows/windows-7/net_user",
|
||||
"tests/fixtures/windows/windows-7/net_user.administrator",
|
||||
"tests/fixtures/windows/windows-2008/net_user",
|
||||
"tests/fixtures/windows/windows-2008/net_user.administrator",
|
||||
"tests/fixtures/windows/windows-2016/net_user.administrators",
|
||||
"tests/fixtures/windows/windows-2016/net_user",
|
||||
"tests/fixtures/windows/windows-10/net_user",
|
||||
"tests/fixtures/windows/windows-10/net_user.administrator",
|
||||
"tests/fixtures/windows/windows-11/net_user",
|
||||
"tests/fixtures/windows/windows-11/net_user.administrator"
|
||||
]
|
||||
f_in: Dict = {}
|
||||
f_json: Dict = {}
|
||||
|
||||
def setUp(self):
|
||||
for tf in MyTests.test_files:
|
||||
in_file = os.path.join(THIS_DIR, os.pardir, f"{tf}.out")
|
||||
out_file = os.path.join(THIS_DIR, os.pardir, f"{tf}.json")
|
||||
@classmethod
|
||||
def setUpClass(cls):
|
||||
fixtures = {
|
||||
'windows_xp_net_user': (
|
||||
'fixtures/windows/windows-xp/net_user.out',
|
||||
'fixtures/windows/windows-xp/net_user.json'),
|
||||
'windows_7_net_user': (
|
||||
'fixtures/windows/windows-7/net_user.out',
|
||||
'fixtures/windows/windows-7/net_user.json'),
|
||||
'windows_2008_net_user': (
|
||||
'fixtures/windows/windows-2008/net_user.out',
|
||||
'fixtures/windows/windows-2008/net_user.json'),
|
||||
'windows_2016_net_user': (
|
||||
'fixtures/windows/windows-2016/net_user.out',
|
||||
'fixtures/windows/windows-2016/net_user.json'),
|
||||
'windows_10_net_user': (
|
||||
'fixtures/windows/windows-10/net_user.out',
|
||||
'fixtures/windows/windows-10/net_user.json'),
|
||||
'windows_11_net_user': (
|
||||
'fixtures/windows/windows-11/net_user.out',
|
||||
'fixtures/windows/windows-11/net_user.json'),
|
||||
}
|
||||
|
||||
with open(in_file, "r", encoding="utf-8") as f:
|
||||
setattr(self, self.varName(tf), f.read())
|
||||
with open(out_file, "r", encoding="utf-8") as f:
|
||||
setattr(self, self.varName(tf) + "_json", json.loads(f.read()))
|
||||
for file, filepaths in fixtures.items():
|
||||
with open(os.path.join(THIS_DIR, filepaths[0]), 'r', encoding='utf-8') as a, \
|
||||
open(os.path.join(THIS_DIR, filepaths[1]), 'r', encoding='utf-8') as b:
|
||||
cls.f_in[file] = a.read()
|
||||
cls.f_json[file] = json.loads(b.read())
|
||||
|
||||
def varName(self, path):
|
||||
return (
|
||||
path.replace("tests/fixtures/windows", "")
|
||||
.replace("-", "_")
|
||||
.replace("/", "_")
|
||||
|
||||
def test_net_user_nodata(self):
|
||||
"""
|
||||
Test 'net_user' with no data
|
||||
"""
|
||||
self.assertEqual(parse('', quiet=True), {})
|
||||
|
||||
|
||||
def test_net_user_windows_xp(self):
|
||||
"""
|
||||
Test 'net_user' on Windows XP
|
||||
"""
|
||||
self.assertEqual(
|
||||
parse(self.f_in['windows_xp_net_user'], quiet=True),
|
||||
self.f_json['windows_xp_net_user']
|
||||
)
|
||||
|
||||
def test_windows_net_localgroup(self):
|
||||
|
||||
def test_net_user_windows_7(self):
|
||||
"""
|
||||
Test a sample Windows "net localgroup" command output
|
||||
Test 'net_user' on Windows 7
|
||||
"""
|
||||
for tf in MyTests.test_files:
|
||||
in_var = getattr(self, self.varName(tf))
|
||||
out_var = getattr(self, self.varName(tf) + "_json")
|
||||
|
||||
self.assertEqual(jc.parsers.net_user.parse(in_var, quiet=True), out_var)
|
||||
self.assertEqual(
|
||||
parse(self.f_in['windows_7_net_user'], quiet=True),
|
||||
self.f_json['windows_7_net_user']
|
||||
)
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
def test_net_user_windows_2008(self):
|
||||
"""
|
||||
Test 'net_user' on Windows 2008
|
||||
"""
|
||||
self.assertEqual(
|
||||
parse(self.f_in['windows_2008_net_user'], quiet=True),
|
||||
self.f_json['windows_2008_net_user']
|
||||
)
|
||||
|
||||
|
||||
def test_net_user_windows_2016(self):
|
||||
"""
|
||||
Test 'net_user' on Windows 2016
|
||||
"""
|
||||
self.assertEqual(
|
||||
parse(self.f_in['windows_2016_net_user'], quiet=True),
|
||||
self.f_json['windows_2016_net_user']
|
||||
)
|
||||
|
||||
|
||||
def test_net_user_windows_10(self):
|
||||
"""
|
||||
Test 'net_user' on Windows 10
|
||||
"""
|
||||
self.assertEqual(
|
||||
parse(self.f_in['windows_10_net_user'], quiet=True),
|
||||
self.f_json['windows_10_net_user']
|
||||
)
|
||||
|
||||
|
||||
def test_net_user_windows_11(self):
|
||||
"""
|
||||
Test 'net_user' on Windows 11
|
||||
"""
|
||||
self.assertEqual(
|
||||
parse(self.f_in['windows_11_net_user'], quiet=True),
|
||||
self.f_json['windows_11_net_user']
|
||||
)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
unittest.main()
|
||||
|
Reference in New Issue
Block a user