cloudnoteslib 0.1.0__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.
@@ -0,0 +1,12 @@
1
+ """
2
+ cloudnoteslib.security — Note Security Tools.
3
+
4
+ Exports:
5
+ NoteEncryptor: AES encryption/decryption for sensitive notes.
6
+ ContentSanitizer: XSS prevention and HTML sanitization.
7
+ """
8
+
9
+ from .encryptor import NoteEncryptor
10
+ from .sanitizer import ContentSanitizer
11
+
12
+ __all__ = ["NoteEncryptor", "ContentSanitizer"]
@@ -0,0 +1,81 @@
1
+ """
2
+ cloudnoteslib.security.encryptor — Note Encryption Engine.
3
+
4
+ Provides simple AES-inspired (using Fernet) encryption for securing
5
+ highly sensitive note content before database storage.
6
+ """
7
+
8
+ import base64
9
+ try:
10
+ from cryptography.fernet import Fernet
11
+ from cryptography.hazmat.primitives import hashes
12
+ from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
13
+ CRYPTO_AVAILABLE = True
14
+ except ImportError:
15
+ CRYPTO_AVAILABLE = False
16
+
17
+
18
+ class NoteEncryptor:
19
+ """
20
+ Encrypts and decrypts note content.
21
+
22
+ Uses Fernet (symmetric encryption verified with a MAC).
23
+ Keys are derived from a password using PBKDF2.
24
+ """
25
+
26
+ def __init__(self, salt: bytes = b'cloudnotes_salt_123'):
27
+ if not CRYPTO_AVAILABLE:
28
+ raise ImportError(
29
+ "cryptography package is required for NoteEncryptor. "
30
+ "Install with: pip install cryptography"
31
+ )
32
+ self._salt = salt
33
+
34
+ def _get_key(self, password: str) -> bytes:
35
+ """Derive a secure encryption key from a password."""
36
+ kdf = PBKDF2HMAC(
37
+ algorithm=hashes.SHA256(),
38
+ length=32,
39
+ salt=self._salt,
40
+ iterations=100000,
41
+ )
42
+ key = base64.urlsafe_b64encode(kdf.derive(password.encode()))
43
+ return key
44
+
45
+ def encrypt(self, plain_text: str, password: str) -> str:
46
+ """
47
+ Encrypt plain text using the password.
48
+
49
+ Args:
50
+ plain_text: Text to encrypt.
51
+ password: Password to derive key from.
52
+
53
+ Returns:
54
+ Encrypted URL-safe base64 string.
55
+ """
56
+ key = self._get_key(password)
57
+ f = Fernet(key)
58
+ encrypted = f.encrypt(plain_text.encode('utf-8'))
59
+ return encrypted.decode('utf-8')
60
+
61
+ def decrypt(self, encrypted_text: str, password: str) -> str:
62
+ """
63
+ Decrypt text using the password.
64
+
65
+ Args:
66
+ encrypted_text: Encrypted string.
67
+ password: Password to derive key from.
68
+
69
+ Returns:
70
+ Decrypted plain text.
71
+
72
+ Raises:
73
+ ValueError: If decryption fails (wrong password or corrupted data).
74
+ """
75
+ try:
76
+ key = self._get_key(password)
77
+ f = Fernet(key)
78
+ decrypted = f.decrypt(encrypted_text.encode('utf-8'))
79
+ return decrypted.decode('utf-8')
80
+ except Exception as e:
81
+ raise ValueError(f"Decryption failed: {str(e)}")
@@ -0,0 +1,56 @@
1
+ """
2
+ cloudnoteslib.security.sanitizer — Content Sanitizer.
3
+
4
+ Prevents XSS (Cross-Site Scripting) by stripping malicious tags
5
+ from HTML/Rich text content.
6
+ """
7
+
8
+ import re
9
+
10
+
11
+ class ContentSanitizer:
12
+ """
13
+ Sanitizes note content to prevent XSS attacks.
14
+ """
15
+
16
+ # Tags that are always stripped, along with their contents
17
+ DANGEROUS_TAGS = ['script', 'style', 'iframe', 'object', 'embed', 'applet']
18
+
19
+ def sanitize(self, content: str) -> str:
20
+ """
21
+ Remove dangerous HTML tags and attributes from content.
22
+
23
+ Args:
24
+ content: Raw user input.
25
+
26
+ Returns:
27
+ Sanitized content safe for rendering.
28
+ """
29
+ if not content:
30
+ return ""
31
+
32
+ clean = content
33
+
34
+ # 1. Remove dangerous tags and their contents entirely
35
+ for tag in self.DANGEROUS_TAGS:
36
+ pattern = f"<{tag}[^>]*>.*?</{tag}>"
37
+ clean = re.sub(pattern, "", clean, flags=re.IGNORECASE | re.DOTALL)
38
+
39
+ # 2. Remove inline event handlers (onclick, onload, etc)
40
+ # Matches any attribute starting with 'on' followed by =
41
+ clean = re.sub(
42
+ r'(<[^>]+)(\son[a-z]+\s*=\s*(["\']).*?\3)([^>]*>)',
43
+ r'\1\4',
44
+ clean,
45
+ flags=re.IGNORECASE
46
+ )
47
+
48
+ # 3. Remove javascript: URIs in href or src attributes
49
+ clean = re.sub(
50
+ r'((?:href|src)\s*=\s*["\'])\s*javascript:[^"\']*["\']',
51
+ r'\1#"',
52
+ clean,
53
+ flags=re.IGNORECASE
54
+ )
55
+
56
+ return clean
@@ -0,0 +1,37 @@
1
+ Metadata-Version: 2.4
2
+ Name: cloudnoteslib
3
+ Version: 0.1.0
4
+ Summary: A reusable Object-Oriented generic library for note processing, analysis, and security.
5
+ Home-page: https://github.com/Kavyavegunta04/Cloudnote
6
+ Author: Kavya
7
+ Author-email: Kavya <kavyavegunta27@gmail.com>
8
+ Project-URL: Homepage, https://github.com/Kavyavegunta04/Cloudnote
9
+ Classifier: Programming Language :: Python :: 3
10
+ Classifier: License :: OSI Approved :: MIT License
11
+ Classifier: Operating System :: OS Independent
12
+ Classifier: Intended Audience :: Developers
13
+ Requires-Python: >=3.9
14
+ Description-Content-Type: text/markdown
15
+ Requires-Dist: cryptography>=41.0.0
16
+ Dynamic: author
17
+ Dynamic: home-page
18
+ Dynamic: requires-python
19
+
20
+ # cloudnoteslib
21
+
22
+ A comprehensive, reusable Python Object-Oriented Programming (OOP) library designed for text note processing, content analysis, security, and exports.
23
+
24
+ ## Features & OOP Principles
25
+ - **Encapsulation:** Strongly typed `Note` and `Tag` models with data validation via `@property`.
26
+ - **Abstraction:** Abstract `NoteProcessor` base class guaranteeing unified interfaces.
27
+ - **Inheritance & Polymorphism:** `MarkdownProcessor`, `PlainTextProcessor`, and `RichTextProcessor` implementations sharing the same contract.
28
+ - **Design Patterns:**
29
+ - **Facade Pattern:** `CloudNotesClient` acts as the single point of entry.
30
+ - **Strategy Pattern:** Interchangeable search algorithms (`search.py`).
31
+ - **Template Method Pattern:** Processors share generic steps while overriding specific details.
32
+ - **Singleton Pattern:** Global configuration management.
33
+
34
+ ## Installation
35
+ ```bash
36
+ pip install cloudnoteslib
37
+ ```
@@ -0,0 +1,27 @@
1
+ cloudnoteslib/__init__.py,sha256=BI7teGxZtwtvwHsX7zj32YQ_LCv_lOgYIo4Rv70t77k,4845
2
+ cloudnoteslib/config.py,sha256=PwdMoQQYsCPmlQeokcgYAhIH_9UuawEj_Cnbq5EkFMg,739
3
+ cloudnoteslib/exceptions.py,sha256=tzYoc0dIcJqnSLbAXJkDj8p4eA0zhXUB-CyJZOgFFgw,518
4
+ cloudnoteslib/analyzers/__init__.py,sha256=R2_eWlhZga4bKHvyd4_2NdVOwf0KqcoKV2UsuxNoESo,418
5
+ cloudnoteslib/analyzers/content_analyzer.py,sha256=2x79GKkxrian3dO8wuM0h5aWXTBDGptWe6_u_JklQpw,6604
6
+ cloudnoteslib/analyzers/search.py,sha256=f-NWgXW3-KACGv1OJlCB26VWTYGaeAe0YUxpomOImkY,4331
7
+ cloudnoteslib/analyzers/statistics.py,sha256=RJwW5I8MZm2wlW_EtS6VTIYzqbwAH0SFz5O20e1ZBrI,2847
8
+ cloudnoteslib/exporters/__init__.py,sha256=Zytx7kmSeJb-FmE2XIsStcdaaDcxI6fO6xGoHw8t8Lw,306
9
+ cloudnoteslib/exporters/base.py,sha256=ezVSVArNqfY0QRQZEhJE4-VhylZ3SxGLM0JTWZTavKY,765
10
+ cloudnoteslib/exporters/json_exporter.py,sha256=ARErXtoO8e4Op6lj8rWxjZmyoox_ZxkiDEFdLhs2-Gg,486
11
+ cloudnoteslib/exporters/markdown_exporter.py,sha256=R7u-fxLv8SOZ-lDbo8KjQuQF82cgI77zRTimbV290hU,850
12
+ cloudnoteslib/models/__init__.py,sha256=AGCPwqAXvycac6i1IhN1Q1Y59Y2WOZWICtW9_NxYtMY,588
13
+ cloudnoteslib/models/note.py,sha256=TlvZZI1BcVrp9VUDWkH2-vJZhwyYAL2b09eQjpIsNSo,10916
14
+ cloudnoteslib/models/note_collection.py,sha256=u-9FoBwHh-_zXDNRGoQcCRur5oTO3pMCmCgVj62JCEo,7521
15
+ cloudnoteslib/models/tag.py,sha256=R0rx6jmUkNohoMb8DsII7B9Ub8Xk7jvyzg0YHFq__HQ,3705
16
+ cloudnoteslib/processors/__init__.py,sha256=Rpm76ePqP8q9DBHCQU7c4ctB1-kVh0LG2Q_uvl8x_oE,1148
17
+ cloudnoteslib/processors/base.py,sha256=YNYW8IYpMp6QNGbJtrhy3reZkEUExHcvw2Pl20tU0ho,5078
18
+ cloudnoteslib/processors/markdown_processor.py,sha256=V02L8cyR_QiLrSMwNbalZ52a_GFJiVoNsu5AxMKWywY,5106
19
+ cloudnoteslib/processors/plaintext_processor.py,sha256=B97gj5coKT26u7E7IT2QorU5Rw741p0dSzEUmXY2aVE,2979
20
+ cloudnoteslib/processors/richtext_processor.py,sha256=Cn4iMS3xd61cSVJErKCUlJadou_ZP5YrGi2hBCObFdo,3530
21
+ cloudnoteslib/security/__init__.py,sha256=Yy1lk1Ll_ROAqYNqE24kavtVn02hPWX2xbDPrrcUAwY,319
22
+ cloudnoteslib/security/encryptor.py,sha256=nwu5YZm9rfEIdjCObBY-Jl5xngCA3hBtAMjkajvAldE,2521
23
+ cloudnoteslib/security/sanitizer.py,sha256=D-45nL1AfD6XRHMEFo6oToOIwx3geJRDLYZFFgXfOgg,1608
24
+ cloudnoteslib-0.1.0.dist-info/METADATA,sha256=pNVf9tgZNRgNCtg29X2-aPQSsX69V_xcl6-xLuHkTxo,1642
25
+ cloudnoteslib-0.1.0.dist-info/WHEEL,sha256=aeYiig01lYGDzBgS8HxWXOg3uV61G9ijOsup-k9o1sk,91
26
+ cloudnoteslib-0.1.0.dist-info/top_level.txt,sha256=az-9qrV_u-_rIoUsISe5mQAOlK9pMGddgsS8Jex4zro,14
27
+ cloudnoteslib-0.1.0.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (82.0.1)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1 @@
1
+ cloudnoteslib