-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
12 changed files
with
139 additions
and
11 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
import uuid | ||
|
||
from osbot_utils.utils.Misc import is_guid | ||
|
||
GUID__NAMESPACE = uuid.UUID('2cfec064-537a-4ff7-8fdc-2fc9e2606f3d') | ||
|
||
class Guid(str): | ||
def __new__(cls, value: str): | ||
if not isinstance(value, str): # Check if the value is a string | ||
raise ValueError(f'in Guid: value provided was not a string: {value}') # if not raise a ValueError | ||
if is_guid(value): | ||
guid = value | ||
else: | ||
guid = uuid.uuid5(GUID__NAMESPACE, value) # Generate a UUID5 using the namespace and value | ||
return super().__new__(cls, str(guid)) # Return a new instance of Guid initialized with the string version of the UUID | ||
|
||
def __str__(self): | ||
return self |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,22 @@ | ||
import re | ||
|
||
REGEX__ASCII_VALUE = re.compile(r'[^a-zA-Z0-9_\s!@#$%^&*()\[\]{}\-+=:;,.?]') | ||
|
||
class Str_ASCII(str): | ||
""" | ||
A string subclass that ensures values only contain safe ASCII characters. | ||
Replaces any unsafe characters with underscores. | ||
""" | ||
def __new__(cls, value=None, max_length=None): | ||
if value is None: | ||
value = "" | ||
|
||
if not isinstance(value, str): | ||
value = str(value) | ||
|
||
if max_length and len(value) > max_length: | ||
raise ValueError(f"Value length exceeds maximum of {max_length} characters (was {len(value)})") | ||
|
||
sanitized_value = REGEX__ASCII_VALUE.sub('_', value) | ||
|
||
return super().__new__(cls, sanitized_value) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
v1.87.0 | ||
v1.87.1 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,6 @@ | ||
[tool.poetry] | ||
name = "osbot_utils" | ||
version = "v1.87.0" | ||
version = "v1.87.1" | ||
description = "OWASP Security Bot - Utils" | ||
authors = ["Dinis Cruz <[email protected]>"] | ||
license = "MIT" | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,41 @@ | ||
from unittest import TestCase | ||
from osbot_utils.helpers.Guid import Guid | ||
|
||
|
||
class test_Guid(TestCase): | ||
def setUp(self): | ||
self.test_value = "test-guid" | ||
self.guid = Guid(self.test_value) | ||
|
||
def test_create_guid(self): | ||
assert isinstance(self.guid, Guid) | ||
assert isinstance(self.guid, str) | ||
assert len(str(self.guid)) == 36 # Standard UUID length | ||
|
||
def test_deterministic(self): | ||
guid_1 = Guid(self.test_value) | ||
guid_2 = Guid(self.test_value) | ||
assert guid_1 == guid_2 # Same input produces same UUID | ||
assert guid_1 == '2d68e4f3-bb56-5e6f-a2a6-9c20e650f08a' | ||
assert Guid('a') == '8a809dc1-0090-52e4-bf96-c888f7e20aa5' # static strings always produce the same value | ||
assert Guid('b') == '6e2adca9-5cbe-5d1b-bd74-3ed29cf04fc3' | ||
|
||
def test_different_inputs(self): | ||
guid_1 = Guid("value-1") | ||
guid_2 = Guid("value-2") | ||
assert guid_1 != guid_2 # Different inputs produce different UUIDs | ||
|
||
def test_empty_input(self): | ||
guid = Guid("") # Empty string is valid | ||
assert isinstance(guid, Guid) | ||
assert len(str(guid)) == 36 | ||
|
||
def test_none_input(self): | ||
with self.assertRaises(ValueError) as context: | ||
Guid(None) # Non-string input | ||
assert "value provided was not a string" in str(context.exception) | ||
|
||
def test_invalid_input(self): | ||
with self.assertRaises(ValueError) as context: | ||
Guid(123) # Non-string input | ||
assert "value provided was not a string" in str(context.exception) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
from unittest import TestCase | ||
from osbot_utils.helpers.Str_ASCII import Str_ASCII | ||
|
||
|
||
class test_Str_ASCII(TestCase): | ||
|
||
def test_basic_values(self): | ||
test_cases = [("hello-world" , "hello-world" ), | ||
("hello™world" , "hello_world" ), | ||
("hello世界" , "hello__" ), | ||
("[email protected]" , "[email protected]" ), | ||
("multiple___spaces" , "multiple___spaces"), | ||
("_trim_edges_" , "_trim_edges_" ), | ||
(123 , "123" ), | ||
(3.14 , "3.14" )] | ||
for input_value, expected in test_cases: | ||
result = Str_ASCII(input_value) | ||
assert result == expected | ||
|
||
def test_max_length(self): | ||
# Valid length | ||
assert Str_ASCII("test", max_length=10) == "test" | ||
|
||
# Invalid length | ||
with self.assertRaises(ValueError) as context: | ||
Str_ASCII("too_long_string", max_length=5) | ||
assert "Value length exceeds maximum" in str(context.exception) | ||
|
||
def test_handle_invalid_inputs(self): | ||
invalid_cases = [None, # None value | ||
"", # Empty string | ||
"™™™", # Only special chars | ||
"_____" # Only underscores | ||
] | ||
for invalid_input in invalid_cases: | ||
Str_ASCII(invalid_input) | ||
|
||
def test_preserves_allowed_chars(self): | ||
special_chars = "!@#$%^&*()[]{}-+=:;,.?" | ||
result = Str_ASCII(f"test{special_chars}123") | ||
assert result == f"test{special_chars}123" | ||
|
||
def test_replaces_invalid_chars(self): | ||
invalid_chars = "™£€¥©®℗" | ||
result = Str_ASCII(f"test{invalid_chars}123") | ||
assert result == "test_______123" |