Skip to content

Commit 807250f

Browse files
committed
fix: base64 attributes serialization
replace the usage of `bytes` for attributes by `Base64Bytes`
1 parent 5e83803 commit 807250f

9 files changed

Lines changed: 42 additions & 60 deletions

File tree

doc/changelog.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ Changelog
77
Added
88
^^^^^
99
- Python 3.13 support.
10+
- Proper Base64 serialization. #31
1011

1112
Changed
1213
^^^^^^^

samples/rfc7643-8.2-user-full.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@
100100
],
101101
"x509Certificates": [
102102
{
103-
"value": "MIIDQzCCAqygAwIBAgICEAAwDQYJKoZIhvcNAQEFBQAwTjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFDASBgNVBAoMC2V4YW1wbGUuY29tMRQwEgYDVQQDDAtleGFtcGxlLmNvbTAeFw0xMTEwMjIwNjI0MzFaFw0xMjEwMDQwNjI0MzFaMH8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRQwEgYDVQQKDAtleGFtcGxlLmNvbTEhMB8GA1UEAwwYTXMuIEJhcmJhcmEgSiBKZW5zZW4gSUlJMSIwIAYJKoZIhvcNAQkBFhNiamVuc2VuQGV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7Kr+Dcds/JQ5GwejJFcBIP682X3xpjis56AK02bc1FLgzdLI8auoR+cC9/Vrh5t66HkQIOdA4unHh0AaZ4xL5PhVbXIPMB5vAPKpzz5iPSi8xO8SL7I7SDhcBVJhqVqr3HgllEG6UClDdHO7nkLuwXq8HcISKkbT5WFTVfFZzidPl8HZ7DhXkZIRtJwBweq4bvm3hM1Os7UQH05ZS6cVDgweKNwdLLrT51ikSQG3DYrl+ft781UQRIqxgwqCfXEuDiinPh0kkvIi5jivVu1Z9QiwlYEdRbLJ4zJQBmDrSGTMYn4lRc2HgHO4DqB/bnMVorHB0CC6AV1QoFK4GPe1LwIDAQABo3sweTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQU8pD0U0vsZIsaA16lL8En8bx0F/gwHwYDVR0jBBgwFoAUdGeKitcaF7gnzsNwDx708kqaVt0wDQYJKoZIhvcNAQEFBQADgYEAA81SsFnOdYJtNg5Tcq+/ByEDrBgnusx0jloUhByPMEVkoMZ3J7j1ZgI8rAbOkNngX8+pKfTiDz1RC4+dx8oU6Za+4NJXUjlL5CvV6BEYb1+QAEJwitTVvxB/A67g42/vzgAtoRUeDov1+GFiBZ+GNF/cAYKcMtGcrs2i97ZkJMo="
103+
"value": "MIIDQzCCAqygAwIBAgICEAAwDQYJKoZIhvcNAQEFBQAwTjELMAkGA1UEBhMCVVMxEzARBgNVBAgM\nCkNhbGlmb3JuaWExFDASBgNVBAoMC2V4YW1wbGUuY29tMRQwEgYDVQQDDAtleGFtcGxlLmNvbTAe\nFw0xMTEwMjIwNjI0MzFaFw0xMjEwMDQwNjI0MzFaMH8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApD\nYWxpZm9ybmlhMRQwEgYDVQQKDAtleGFtcGxlLmNvbTEhMB8GA1UEAwwYTXMuIEJhcmJhcmEgSiBK\nZW5zZW4gSUlJMSIwIAYJKoZIhvcNAQkBFhNiamVuc2VuQGV4YW1wbGUuY29tMIIBIjANBgkqhkiG\n9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7Kr+Dcds/JQ5GwejJFcBIP682X3xpjis56AK02bc1FLgzdLI\n8auoR+cC9/Vrh5t66HkQIOdA4unHh0AaZ4xL5PhVbXIPMB5vAPKpzz5iPSi8xO8SL7I7SDhcBVJh\nqVqr3HgllEG6UClDdHO7nkLuwXq8HcISKkbT5WFTVfFZzidPl8HZ7DhXkZIRtJwBweq4bvm3hM1O\ns7UQH05ZS6cVDgweKNwdLLrT51ikSQG3DYrl+ft781UQRIqxgwqCfXEuDiinPh0kkvIi5jivVu1Z\n9QiwlYEdRbLJ4zJQBmDrSGTMYn4lRc2HgHO4DqB/bnMVorHB0CC6AV1QoFK4GPe1LwIDAQABo3sw\neTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0\nZTAdBgNVHQ4EFgQU8pD0U0vsZIsaA16lL8En8bx0F/gwHwYDVR0jBBgwFoAUdGeKitcaF7gnzsNw\nDx708kqaVt0wDQYJKoZIhvcNAQEFBQADgYEAA81SsFnOdYJtNg5Tcq+/ByEDrBgnusx0jloUhByP\nMEVkoMZ3J7j1ZgI8rAbOkNngX8+pKfTiDz1RC4+dx8oU6Za+4NJXUjlL5CvV6BEYb1+QAEJwitTV\nvxB/A67g42/vzgAtoRUeDov1+GFiBZ+GNF/cAYKcMtGcrs2i97ZkJMo=\n"
104104
}
105105
],
106106
"meta": {

samples/rfc7643-8.3-enterprise_user.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@
101101
],
102102
"x509Certificates": [
103103
{
104-
"value": "MIIDQzCCAqygAwIBAgICEAAwDQYJKoZIhvcNAQEFBQAwTjELMAkGA1UEBhMCVVMxEzARBgNVBAgMCkNhbGlmb3JuaWExFDASBgNVBAoMC2V4YW1wbGUuY29tMRQwEgYDVQQDDAtleGFtcGxlLmNvbTAeFw0xMTEwMjIwNjI0MzFaFw0xMjEwMDQwNjI0MzFaMH8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRQwEgYDVQQKDAtleGFtcGxlLmNvbTEhMB8GA1UEAwwYTXMuIEJhcmJhcmEgSiBKZW5zZW4gSUlJMSIwIAYJKoZIhvcNAQkBFhNiamVuc2VuQGV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7Kr+Dcds/JQ5GwejJFcBIP682X3xpjis56AK02bc1FLgzdLI8auoR+cC9/Vrh5t66HkQIOdA4unHh0AaZ4xL5PhVbXIPMB5vAPKpzz5iPSi8xO8SL7I7SDhcBVJhqVqr3HgllEG6UClDdHO7nkLuwXq8HcISKkbT5WFTVfFZzidPl8HZ7DhXkZIRtJwBweq4bvm3hM1Os7UQH05ZS6cVDgweKNwdLLrT51ikSQG3DYrl+ft781UQRIqxgwqCfXEuDiinPh0kkvIi5jivVu1Z9QiwlYEdRbLJ4zJQBmDrSGTMYn4lRc2HgHO4DqB/bnMVorHB0CC6AV1QoFK4GPe1LwIDAQABo3sweTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0ZTAdBgNVHQ4EFgQU8pD0U0vsZIsaA16lL8En8bx0F/gwHwYDVR0jBBgwFoAUdGeKitcaF7gnzsNwDx708kqaVt0wDQYJKoZIhvcNAQEFBQADgYEAA81SsFnOdYJtNg5Tcq+/ByEDrBgnusx0jloUhByPMEVkoMZ3J7j1ZgI8rAbOkNngX8+pKfTiDz1RC4+dx8oU6Za+4NJXUjlL5CvV6BEYb1+QAEJwitTVvxB/A67g42/vzgAtoRUeDov1+GFiBZ+GNF/cAYKcMtGcrs2i97ZkJMo="
104+
"value": "MIIDQzCCAqygAwIBAgICEAAwDQYJKoZIhvcNAQEFBQAwTjELMAkGA1UEBhMCVVMxEzARBgNVBAgM\nCkNhbGlmb3JuaWExFDASBgNVBAoMC2V4YW1wbGUuY29tMRQwEgYDVQQDDAtleGFtcGxlLmNvbTAe\nFw0xMTEwMjIwNjI0MzFaFw0xMjEwMDQwNjI0MzFaMH8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApD\nYWxpZm9ybmlhMRQwEgYDVQQKDAtleGFtcGxlLmNvbTEhMB8GA1UEAwwYTXMuIEJhcmJhcmEgSiBK\nZW5zZW4gSUlJMSIwIAYJKoZIhvcNAQkBFhNiamVuc2VuQGV4YW1wbGUuY29tMIIBIjANBgkqhkiG\n9w0BAQEFAAOCAQ8AMIIBCgKCAQEA7Kr+Dcds/JQ5GwejJFcBIP682X3xpjis56AK02bc1FLgzdLI\n8auoR+cC9/Vrh5t66HkQIOdA4unHh0AaZ4xL5PhVbXIPMB5vAPKpzz5iPSi8xO8SL7I7SDhcBVJh\nqVqr3HgllEG6UClDdHO7nkLuwXq8HcISKkbT5WFTVfFZzidPl8HZ7DhXkZIRtJwBweq4bvm3hM1O\ns7UQH05ZS6cVDgweKNwdLLrT51ikSQG3DYrl+ft781UQRIqxgwqCfXEuDiinPh0kkvIi5jivVu1Z\n9QiwlYEdRbLJ4zJQBmDrSGTMYn4lRc2HgHO4DqB/bnMVorHB0CC6AV1QoFK4GPe1LwIDAQABo3sw\neTAJBgNVHRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZpY2F0\nZTAdBgNVHQ4EFgQU8pD0U0vsZIsaA16lL8En8bx0F/gwHwYDVR0jBBgwFoAUdGeKitcaF7gnzsNw\nDx708kqaVt0wDQYJKoZIhvcNAQEFBQADgYEAA81SsFnOdYJtNg5Tcq+/ByEDrBgnusx0jloUhByP\nMEVkoMZ3J7j1ZgI8rAbOkNngX8+pKfTiDz1RC4+dx8oU6Za+4NJXUjlL5CvV6BEYb1+QAEJwitTV\nvxB/A67g42/vzgAtoRUeDov1+GFiBZ+GNF/cAYKcMtGcrs2i97ZkJMo=\n"
105105
}
106106
],
107107
"urn:ietf:params:scim:schemas:extension:enterprise:2.0:User": {

scim2_models/rfc7643/schema.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
from typing import Union
1212
from typing import get_origin
1313

14+
from pydantic import Base64Bytes
1415
from pydantic import Field
1516
from pydantic import create_model
1617
from pydantic.alias_generators import to_pascal
@@ -109,7 +110,7 @@ def to_python(
109110
self.decimal: float,
110111
self.integer: int,
111112
self.date_time: datetime,
112-
self.binary: bytes,
113+
self.binary: Base64Bytes,
113114
self.complex: MultiValuedComplexAttribute
114115
if multiple
115116
else ComplexAttribute,
@@ -133,7 +134,7 @@ def from_python(cls, pytype) -> str:
133134
float: cls.decimal.value,
134135
int: cls.integer.value,
135136
datetime: cls.date_time.value,
136-
bytes: cls.binary.value,
137+
Base64Bytes: cls.binary.value,
137138
}
138139
return attr_types.get(pytype, cls.string.value)
139140

scim2_models/rfc7643/user.py

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55
from typing import Optional
66
from typing import Union
77

8+
from pydantic import Base64Bytes
89
from pydantic import EmailStr
910
from pydantic import Field
1011

@@ -209,7 +210,7 @@ class Role(MultiValuedComplexAttribute):
209210

210211

211212
class X509Certificate(MultiValuedComplexAttribute):
212-
value: Annotated[Optional[bytes], CaseExact.true] = None
213+
value: Annotated[Optional[Base64Bytes], CaseExact.true] = None
213214
"""The value of an X.509 certificate."""
214215

215216

tests/test_dynamic_resources.py

Lines changed: 4 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
from typing import Literal
33
from typing import Union
44

5+
from pydantic import Base64Bytes
6+
57
from scim2_models.base import CaseExact
68
from scim2_models.base import ComplexAttribute
79
from scim2_models.base import ExternalReference
@@ -1071,7 +1073,7 @@ def test_make_user_model_from_schema(load_sample):
10711073
)
10721074

10731075
# x_509_certificate.value
1074-
assert X509Certificates.get_field_root_type("value") is bytes
1076+
assert X509Certificates.get_field_root_type("value") is Base64Bytes
10751077
assert not is_multiple(X509Certificates.model_fields["value"])
10761078
assert (
10771079
X509Certificates.model_fields["value"].description
@@ -1223,24 +1225,7 @@ def test_make_user_model_from_schema(load_sample):
12231225
)
12241226
assert obj.groups[2].display == "US Employees"
12251227
assert obj.x_509_certificates[0].value == (
1226-
b"MIIDQzCCAqygAwIBAgICEAAwDQYJKoZIhvcNAQEFBQAwTjELMAkGA1UEBhMCVVMx"
1227-
b"EzARBgNVBAgMCkNhbGlmb3JuaWExFDASBgNVBAoMC2V4YW1wbGUuY29tMRQwEgYD"
1228-
b"VQQDDAtleGFtcGxlLmNvbTAeFw0xMTEwMjIwNjI0MzFaFw0xMjEwMDQwNjI0MzFa"
1229-
b"MH8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRQwEgYDVQQKDAtl"
1230-
b"eGFtcGxlLmNvbTEhMB8GA1UEAwwYTXMuIEJhcmJhcmEgSiBKZW5zZW4gSUlJMSIw"
1231-
b"IAYJKoZIhvcNAQkBFhNiamVuc2VuQGV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0B"
1232-
b"AQEFAAOCAQ8AMIIBCgKCAQEA7Kr+Dcds/JQ5GwejJFcBIP682X3xpjis56AK02bc"
1233-
b"1FLgzdLI8auoR+cC9/Vrh5t66HkQIOdA4unHh0AaZ4xL5PhVbXIPMB5vAPKpzz5i"
1234-
b"PSi8xO8SL7I7SDhcBVJhqVqr3HgllEG6UClDdHO7nkLuwXq8HcISKkbT5WFTVfFZ"
1235-
b"zidPl8HZ7DhXkZIRtJwBweq4bvm3hM1Os7UQH05ZS6cVDgweKNwdLLrT51ikSQG3"
1236-
b"DYrl+ft781UQRIqxgwqCfXEuDiinPh0kkvIi5jivVu1Z9QiwlYEdRbLJ4zJQBmDr"
1237-
b"SGTMYn4lRc2HgHO4DqB/bnMVorHB0CC6AV1QoFK4GPe1LwIDAQABo3sweTAJBgNV"
1238-
b"HRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZp"
1239-
b"Y2F0ZTAdBgNVHQ4EFgQU8pD0U0vsZIsaA16lL8En8bx0F/gwHwYDVR0jBBgwFoAU"
1240-
b"dGeKitcaF7gnzsNwDx708kqaVt0wDQYJKoZIhvcNAQEFBQADgYEAA81SsFnOdYJt"
1241-
b"Ng5Tcq+/ByEDrBgnusx0jloUhByPMEVkoMZ3J7j1ZgI8rAbOkNngX8+pKfTiDz1R"
1242-
b"C4+dx8oU6Za+4NJXUjlL5CvV6BEYb1+QAEJwitTVvxB/A67g42/vzgAtoRUeDov1"
1243-
b"+GFiBZ+GNF/cAYKcMtGcrs2i97ZkJMo="
1228+
b"0\x82\x03C0\x82\x02\xac\xa0\x03\x02\x01\x02\x02\x02\x10\x000\r\x06\t*\x86H\x86\xf7\r\x01\x01\x05\x05\x000N1\x0b0\t\x06\x03U\x04\x06\x13\x02US1\x130\x11\x06\x03U\x04\x08\x0c\nCalifornia1\x140\x12\x06\x03U\x04\n\x0c\x0bexample.com1\x140\x12\x06\x03U\x04\x03\x0c\x0bexample.com0\x1e\x17\r111022062431Z\x17\r121004062431Z0\x7f1\x0b0\t\x06\x03U\x04\x06\x13\x02US1\x130\x11\x06\x03U\x04\x08\x0c\nCalifornia1\x140\x12\x06\x03U\x04\n\x0c\x0bexample.com1!0\x1f\x06\x03U\x04\x03\x0c\x18Ms. Barbara J Jensen III1\"0 \x06\t*\x86H\x86\xf7\r\x01\t\x01\x16\x13bjensen@example.com0\x82\x01\"0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x000\x82\x01\n\x02\x82\x01\x01\x00\xec\xaa\xfe\r\xc7l\xfc\x949\x1b\x07\xa3$W\x01 \xfe\xbc\xd9}\xf1\xa68\xac\xe7\xa0\n\xd3f\xdc\xd4R\xe0\xcd\xd2\xc8\xf1\xab\xa8G\xe7\x02\xf7\xf5k\x87\x9bz\xe8y\x10 \xe7@\xe2\xe9\xc7\x87@\x1ag\x8cK\xe4\xf8Umr\x0f0\x1eo\x00\xf2\xa9\xcf>b=(\xbc\xc4\xef\x12/\xb2;H8\\\x05Ra\xa9Z\xab\xdcx%\x94A\xbaP)Cts\xbb\x9eB\xee\xc1z\xbc\x1d\xc2\x12*F\xd3\xe5aSU\xf1Y\xce'O\x97\xc1\xd9\xec8W\x91\x92\x11\xb4\x9c\x01\xc1\xea\xb8n\xf9\xb7\x84\xcdN\xb3\xb5\x10\x1fNYK\xa7\x15\x0e\x0c\x1e(\xdc\x1d,\xba\xd3\xe7X\xa4I\x01\xb7\r\x8a\xe5\xf9\xfb{\xf3U\x10D\x8a\xb1\x83\n\x82}q.\x0e(\xa7>\x1d$\x92\xf2\"\xe68\xafV\xedY\xf5\x08\xb0\x95\x81\x1dE\xb2\xc9\xe32P\x06`\xebHd\xccb~%E\xcd\x87\x80s\xb8\x0e\xa0\x7fns\x15\xa2\xb1\xc1\xd0 \xba\x01]P\xa0R\xb8\x18\xf7\xb5/\x02\x03\x01\x00\x01\xa3{0y0\t\x06\x03U\x1d\x13\x04\x020\x000,\x06\t`\x86H\x01\x86\xf8B\x01\r\x04\x1f\x16\x1dOpenSSL Generated Certificate0\x1d\x06\x03U\x1d\x0e\x04\x16\x04\x14\xf2\x90\xf4SK\xecd\x8b\x1a\x03^\xa5/\xc1'\xf1\xbct\x17\xf80\x1f\x06\x03U\x1d#\x04\x180\x16\x80\x14tg\x8a\x8a\xd7\x1a\x17\xb8'\xce\xc3p\x0f\x1e\xf4\xf2J\x9aV\xdd0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x05\x05\x00\x03\x81\x81\x00\x03\xcdR\xb0Y\xceu\x82m6\x0eSr\xaf\xbf\x07!\x03\xac\x18'\xba\xcct\x8eZ\x14\x84\x1c\x8f0Ed\xa0\xc6w'\xb8\xf5f\x02<\xac\x06\xce\x90\xd9\xe0_\xcf\xa9)\xf4\xe2\x0f=Q\x0b\x8f\x9d\xc7\xca\x14\xe9\x96\xbe\xe0\xd2WR9K\xe4+\xd5\xe8\x11\x18o_\x90\x00Bp\x8a\xd4\xd5\xbf\x10\x7f\x03\xae\xe0\xe3o\xef\xce\x00-\xa1\x15\x1e\x0e\x8b\xf5\xf8ab\x05\x9f\x864_\xdc\x01\x82\x9c2\xd1\x9c\xae\xcd\xa2\xf7\xb6d$\xca"
12441229
)
12451230
assert obj.meta.resource_type == "User"
12461231
assert obj.meta.created == datetime.datetime(

tests/test_enterprise_user.py

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -91,24 +91,7 @@ def test_enterprise_user(load_sample):
9191
)
9292
assert obj.groups[2].display == "US Employees"
9393
assert obj.x509_certificates[0].value == (
94-
b"MIIDQzCCAqygAwIBAgICEAAwDQYJKoZIhvcNAQEFBQAwTjELMAkGA1UEBhMCVVMx"
95-
b"EzARBgNVBAgMCkNhbGlmb3JuaWExFDASBgNVBAoMC2V4YW1wbGUuY29tMRQwEgYD"
96-
b"VQQDDAtleGFtcGxlLmNvbTAeFw0xMTEwMjIwNjI0MzFaFw0xMjEwMDQwNjI0MzFa"
97-
b"MH8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRQwEgYDVQQKDAtl"
98-
b"eGFtcGxlLmNvbTEhMB8GA1UEAwwYTXMuIEJhcmJhcmEgSiBKZW5zZW4gSUlJMSIw"
99-
b"IAYJKoZIhvcNAQkBFhNiamVuc2VuQGV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0B"
100-
b"AQEFAAOCAQ8AMIIBCgKCAQEA7Kr+Dcds/JQ5GwejJFcBIP682X3xpjis56AK02bc"
101-
b"1FLgzdLI8auoR+cC9/Vrh5t66HkQIOdA4unHh0AaZ4xL5PhVbXIPMB5vAPKpzz5i"
102-
b"PSi8xO8SL7I7SDhcBVJhqVqr3HgllEG6UClDdHO7nkLuwXq8HcISKkbT5WFTVfFZ"
103-
b"zidPl8HZ7DhXkZIRtJwBweq4bvm3hM1Os7UQH05ZS6cVDgweKNwdLLrT51ikSQG3"
104-
b"DYrl+ft781UQRIqxgwqCfXEuDiinPh0kkvIi5jivVu1Z9QiwlYEdRbLJ4zJQBmDr"
105-
b"SGTMYn4lRc2HgHO4DqB/bnMVorHB0CC6AV1QoFK4GPe1LwIDAQABo3sweTAJBgNV"
106-
b"HRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZp"
107-
b"Y2F0ZTAdBgNVHQ4EFgQU8pD0U0vsZIsaA16lL8En8bx0F/gwHwYDVR0jBBgwFoAU"
108-
b"dGeKitcaF7gnzsNwDx708kqaVt0wDQYJKoZIhvcNAQEFBQADgYEAA81SsFnOdYJt"
109-
b"Ng5Tcq+/ByEDrBgnusx0jloUhByPMEVkoMZ3J7j1ZgI8rAbOkNngX8+pKfTiDz1R"
110-
b"C4+dx8oU6Za+4NJXUjlL5CvV6BEYb1+QAEJwitTVvxB/A67g42/vzgAtoRUeDov1"
111-
b"+GFiBZ+GNF/cAYKcMtGcrs2i97ZkJMo="
94+
b"0\x82\x03C0\x82\x02\xac\xa0\x03\x02\x01\x02\x02\x02\x10\x000\r\x06\t*\x86H\x86\xf7\r\x01\x01\x05\x05\x000N1\x0b0\t\x06\x03U\x04\x06\x13\x02US1\x130\x11\x06\x03U\x04\x08\x0c\nCalifornia1\x140\x12\x06\x03U\x04\n\x0c\x0bexample.com1\x140\x12\x06\x03U\x04\x03\x0c\x0bexample.com0\x1e\x17\r111022062431Z\x17\r121004062431Z0\x7f1\x0b0\t\x06\x03U\x04\x06\x13\x02US1\x130\x11\x06\x03U\x04\x08\x0c\nCalifornia1\x140\x12\x06\x03U\x04\n\x0c\x0bexample.com1!0\x1f\x06\x03U\x04\x03\x0c\x18Ms. Barbara J Jensen III1\"0 \x06\t*\x86H\x86\xf7\r\x01\t\x01\x16\x13bjensen@example.com0\x82\x01\"0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x000\x82\x01\n\x02\x82\x01\x01\x00\xec\xaa\xfe\r\xc7l\xfc\x949\x1b\x07\xa3$W\x01 \xfe\xbc\xd9}\xf1\xa68\xac\xe7\xa0\n\xd3f\xdc\xd4R\xe0\xcd\xd2\xc8\xf1\xab\xa8G\xe7\x02\xf7\xf5k\x87\x9bz\xe8y\x10 \xe7@\xe2\xe9\xc7\x87@\x1ag\x8cK\xe4\xf8Umr\x0f0\x1eo\x00\xf2\xa9\xcf>b=(\xbc\xc4\xef\x12/\xb2;H8\\\x05Ra\xa9Z\xab\xdcx%\x94A\xbaP)Cts\xbb\x9eB\xee\xc1z\xbc\x1d\xc2\x12*F\xd3\xe5aSU\xf1Y\xce'O\x97\xc1\xd9\xec8W\x91\x92\x11\xb4\x9c\x01\xc1\xea\xb8n\xf9\xb7\x84\xcdN\xb3\xb5\x10\x1fNYK\xa7\x15\x0e\x0c\x1e(\xdc\x1d,\xba\xd3\xe7X\xa4I\x01\xb7\r\x8a\xe5\xf9\xfb{\xf3U\x10D\x8a\xb1\x83\n\x82}q.\x0e(\xa7>\x1d$\x92\xf2\"\xe68\xafV\xedY\xf5\x08\xb0\x95\x81\x1dE\xb2\xc9\xe32P\x06`\xebHd\xccb~%E\xcd\x87\x80s\xb8\x0e\xa0\x7fns\x15\xa2\xb1\xc1\xd0 \xba\x01]P\xa0R\xb8\x18\xf7\xb5/\x02\x03\x01\x00\x01\xa3{0y0\t\x06\x03U\x1d\x13\x04\x020\x000,\x06\t`\x86H\x01\x86\xf8B\x01\r\x04\x1f\x16\x1dOpenSSL Generated Certificate0\x1d\x06\x03U\x1d\x0e\x04\x16\x04\x14\xf2\x90\xf4SK\xecd\x8b\x1a\x03^\xa5/\xc1'\xf1\xbct\x17\xf80\x1f\x06\x03U\x1d#\x04\x180\x16\x80\x14tg\x8a\x8a\xd7\x1a\x17\xb8'\xce\xc3p\x0f\x1e\xf4\xf2J\x9aV\xdd0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x05\x05\x00\x03\x81\x81\x00\x03\xcdR\xb0Y\xceu\x82m6\x0eSr\xaf\xbf\x07!\x03\xac\x18'\xba\xcct\x8eZ\x14\x84\x1c\x8f0Ed\xa0\xc6w'\xb8\xf5f\x02<\xac\x06\xce\x90\xd9\xe0_\xcf\xa9)\xf4\xe2\x0f=Q\x0b\x8f\x9d\xc7\xca\x14\xe9\x96\xbe\xe0\xd2WR9K\xe4+\xd5\xe8\x11\x18o_\x90\x00Bp\x8a\xd4\xd5\xbf\x10\x7f\x03\xae\xe0\xe3o\xef\xce\x00-\xa1\x15\x1e\x0e\x8b\xf5\xf8ab\x05\x9f\x864_\xdc\x01\x82\x9c2\xd1\x9c\xae\xcd\xa2\xf7\xb6d$\xca"
11295
)
11396
assert obj.meta.resource_type == "User"
11497
assert obj.meta.created == datetime.datetime(

tests/test_model_attributes.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -300,3 +300,31 @@ def test_dump_after_assignment():
300300
],
301301
"userName": "ABC",
302302
}
303+
304+
305+
def test_binary_attributes():
306+
decoded = b"This is a very long line with a lot of characters, enough to create newlines when encoded."
307+
encoded = "VGhpcyBpcyBhIHZlcnkgbG9uZyBsaW5lIHdpdGggYSBsb3Qgb2YgY2hhcmFjdGVycywgZW5vdWdo\nIHRvIGNyZWF0ZSBuZXdsaW5lcyB3aGVuIGVuY29kZWQu\n"
308+
309+
user = User.model_validate(
310+
{"userName": "foobar", "x509Certificates": [{"value": encoded}]}
311+
)
312+
assert user.x509_certificates[0].value == decoded
313+
assert user.model_dump()["x509Certificates"][0]["value"] == encoded
314+
315+
encoded_without_newlines = "VGhpcyBpcyBhIHZlcnkgbG9uZyBsaW5lIHdpdGggYSBsb3Qgb2YgY2hhcmFjdGVycywgZW5vdWdoIHRvIGNyZWF0ZSBuZXdsaW5lcyB3aGVuIGVuY29kZWQu"
316+
user = User.model_validate(
317+
{
318+
"userName": "foobar",
319+
"x509Certificates": [{"value": encoded_without_newlines}],
320+
}
321+
)
322+
assert user.x509_certificates[0].value == decoded
323+
assert user.model_dump()["x509Certificates"][0]["value"] == encoded
324+
325+
encoded_with_padding = "VGhpcyBpcyBhIHZlcnkgbG9uZyBsaW5lIHdpdGggYSBsb3Qgb2YgY2hhcmFjdGVycywgZW5vdWdo\nIHRvIGNyZWF0ZSBuZXdsaW5lcyB3aGVuIGVuY29kZWQu==================\n"
326+
user = User.model_validate(
327+
{"userName": "foobar", "x509Certificates": [{"value": encoded_with_padding}]}
328+
)
329+
assert user.x509_certificates[0].value == decoded
330+
assert user.model_dump()["x509Certificates"][0]["value"] == encoded

tests/test_user.py

Lines changed: 1 addition & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -108,24 +108,7 @@ def test_full_user(load_sample):
108108
)
109109
assert obj.groups[2].display == "US Employees"
110110
assert obj.x509_certificates[0].value == (
111-
b"MIIDQzCCAqygAwIBAgICEAAwDQYJKoZIhvcNAQEFBQAwTjELMAkGA1UEBhMCVVMx"
112-
b"EzARBgNVBAgMCkNhbGlmb3JuaWExFDASBgNVBAoMC2V4YW1wbGUuY29tMRQwEgYD"
113-
b"VQQDDAtleGFtcGxlLmNvbTAeFw0xMTEwMjIwNjI0MzFaFw0xMjEwMDQwNjI0MzFa"
114-
b"MH8xCzAJBgNVBAYTAlVTMRMwEQYDVQQIDApDYWxpZm9ybmlhMRQwEgYDVQQKDAtl"
115-
b"eGFtcGxlLmNvbTEhMB8GA1UEAwwYTXMuIEJhcmJhcmEgSiBKZW5zZW4gSUlJMSIw"
116-
b"IAYJKoZIhvcNAQkBFhNiamVuc2VuQGV4YW1wbGUuY29tMIIBIjANBgkqhkiG9w0B"
117-
b"AQEFAAOCAQ8AMIIBCgKCAQEA7Kr+Dcds/JQ5GwejJFcBIP682X3xpjis56AK02bc"
118-
b"1FLgzdLI8auoR+cC9/Vrh5t66HkQIOdA4unHh0AaZ4xL5PhVbXIPMB5vAPKpzz5i"
119-
b"PSi8xO8SL7I7SDhcBVJhqVqr3HgllEG6UClDdHO7nkLuwXq8HcISKkbT5WFTVfFZ"
120-
b"zidPl8HZ7DhXkZIRtJwBweq4bvm3hM1Os7UQH05ZS6cVDgweKNwdLLrT51ikSQG3"
121-
b"DYrl+ft781UQRIqxgwqCfXEuDiinPh0kkvIi5jivVu1Z9QiwlYEdRbLJ4zJQBmDr"
122-
b"SGTMYn4lRc2HgHO4DqB/bnMVorHB0CC6AV1QoFK4GPe1LwIDAQABo3sweTAJBgNV"
123-
b"HRMEAjAAMCwGCWCGSAGG+EIBDQQfFh1PcGVuU1NMIEdlbmVyYXRlZCBDZXJ0aWZp"
124-
b"Y2F0ZTAdBgNVHQ4EFgQU8pD0U0vsZIsaA16lL8En8bx0F/gwHwYDVR0jBBgwFoAU"
125-
b"dGeKitcaF7gnzsNwDx708kqaVt0wDQYJKoZIhvcNAQEFBQADgYEAA81SsFnOdYJt"
126-
b"Ng5Tcq+/ByEDrBgnusx0jloUhByPMEVkoMZ3J7j1ZgI8rAbOkNngX8+pKfTiDz1R"
127-
b"C4+dx8oU6Za+4NJXUjlL5CvV6BEYb1+QAEJwitTVvxB/A67g42/vzgAtoRUeDov1"
128-
b"+GFiBZ+GNF/cAYKcMtGcrs2i97ZkJMo="
111+
b"0\x82\x03C0\x82\x02\xac\xa0\x03\x02\x01\x02\x02\x02\x10\x000\r\x06\t*\x86H\x86\xf7\r\x01\x01\x05\x05\x000N1\x0b0\t\x06\x03U\x04\x06\x13\x02US1\x130\x11\x06\x03U\x04\x08\x0c\nCalifornia1\x140\x12\x06\x03U\x04\n\x0c\x0bexample.com1\x140\x12\x06\x03U\x04\x03\x0c\x0bexample.com0\x1e\x17\r111022062431Z\x17\r121004062431Z0\x7f1\x0b0\t\x06\x03U\x04\x06\x13\x02US1\x130\x11\x06\x03U\x04\x08\x0c\nCalifornia1\x140\x12\x06\x03U\x04\n\x0c\x0bexample.com1!0\x1f\x06\x03U\x04\x03\x0c\x18Ms. Barbara J Jensen III1\"0 \x06\t*\x86H\x86\xf7\r\x01\t\x01\x16\x13bjensen@example.com0\x82\x01\"0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x01\x05\x00\x03\x82\x01\x0f\x000\x82\x01\n\x02\x82\x01\x01\x00\xec\xaa\xfe\r\xc7l\xfc\x949\x1b\x07\xa3$W\x01 \xfe\xbc\xd9}\xf1\xa68\xac\xe7\xa0\n\xd3f\xdc\xd4R\xe0\xcd\xd2\xc8\xf1\xab\xa8G\xe7\x02\xf7\xf5k\x87\x9bz\xe8y\x10 \xe7@\xe2\xe9\xc7\x87@\x1ag\x8cK\xe4\xf8Umr\x0f0\x1eo\x00\xf2\xa9\xcf>b=(\xbc\xc4\xef\x12/\xb2;H8\\\x05Ra\xa9Z\xab\xdcx%\x94A\xbaP)Cts\xbb\x9eB\xee\xc1z\xbc\x1d\xc2\x12*F\xd3\xe5aSU\xf1Y\xce'O\x97\xc1\xd9\xec8W\x91\x92\x11\xb4\x9c\x01\xc1\xea\xb8n\xf9\xb7\x84\xcdN\xb3\xb5\x10\x1fNYK\xa7\x15\x0e\x0c\x1e(\xdc\x1d,\xba\xd3\xe7X\xa4I\x01\xb7\r\x8a\xe5\xf9\xfb{\xf3U\x10D\x8a\xb1\x83\n\x82}q.\x0e(\xa7>\x1d$\x92\xf2\"\xe68\xafV\xedY\xf5\x08\xb0\x95\x81\x1dE\xb2\xc9\xe32P\x06`\xebHd\xccb~%E\xcd\x87\x80s\xb8\x0e\xa0\x7fns\x15\xa2\xb1\xc1\xd0 \xba\x01]P\xa0R\xb8\x18\xf7\xb5/\x02\x03\x01\x00\x01\xa3{0y0\t\x06\x03U\x1d\x13\x04\x020\x000,\x06\t`\x86H\x01\x86\xf8B\x01\r\x04\x1f\x16\x1dOpenSSL Generated Certificate0\x1d\x06\x03U\x1d\x0e\x04\x16\x04\x14\xf2\x90\xf4SK\xecd\x8b\x1a\x03^\xa5/\xc1'\xf1\xbct\x17\xf80\x1f\x06\x03U\x1d#\x04\x180\x16\x80\x14tg\x8a\x8a\xd7\x1a\x17\xb8'\xce\xc3p\x0f\x1e\xf4\xf2J\x9aV\xdd0\r\x06\t*\x86H\x86\xf7\r\x01\x01\x05\x05\x00\x03\x81\x81\x00\x03\xcdR\xb0Y\xceu\x82m6\x0eSr\xaf\xbf\x07!\x03\xac\x18'\xba\xcct\x8eZ\x14\x84\x1c\x8f0Ed\xa0\xc6w'\xb8\xf5f\x02<\xac\x06\xce\x90\xd9\xe0_\xcf\xa9)\xf4\xe2\x0f=Q\x0b\x8f\x9d\xc7\xca\x14\xe9\x96\xbe\xe0\xd2WR9K\xe4+\xd5\xe8\x11\x18o_\x90\x00Bp\x8a\xd4\xd5\xbf\x10\x7f\x03\xae\xe0\xe3o\xef\xce\x00-\xa1\x15\x1e\x0e\x8b\xf5\xf8ab\x05\x9f\x864_\xdc\x01\x82\x9c2\xd1\x9c\xae\xcd\xa2\xf7\xb6d$\xca"
129112
)
130113
assert obj.meta.resource_type == "User"
131114
assert obj.meta.created == datetime.datetime(

0 commit comments

Comments
 (0)