-
Notifications
You must be signed in to change notification settings - Fork 8
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
Andrew Leitsius
committed
Aug 1, 2017
1 parent
bcbfb3d
commit d5bc5b9
Showing
4 changed files
with
153 additions
and
130 deletions.
There are no files selected for viewing
Empty file.
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,31 @@ | ||
# -*- coding: utf-8 -*- | ||
from schematics.transforms import whitelist, blacklist | ||
from couchdb_schematics.document import SchematicsDocument | ||
|
||
schematics_default_role = SchematicsDocument.Options.roles['default'] + blacklist("__parent__") | ||
schematics_embedded_role = SchematicsDocument.Options.roles['embedded'] + blacklist("__parent__") | ||
|
||
plain_role = (blacklist('_attachments', 'revisions', 'dateModified') + schematics_embedded_role) | ||
listing_role = whitelist('dateModified', 'doc_id') | ||
draft_role = whitelist('status') | ||
|
||
document_create_role = blacklist('id', 'datePublished', 'dateModified', 'author', 'download_url') | ||
document_edit_role = blacklist('id', 'url', 'datePublished', 'dateModified', 'author', 'hash', 'download_url'), | ||
document_embedded_role = (blacklist('url', 'download_url') + schematics_embedded_role) | ||
document_view_role = (blacklist('revisions') + schematics_default_role) | ||
document_revisions_role = whitelist('url', 'dateModified') | ||
|
||
|
||
document_roles = { | ||
'create': document_create_role, | ||
'edit': document_edit_role, | ||
'embedded': document_embedded_role, | ||
'view': document_view_role, | ||
'revisions': document_revisions_role, | ||
} | ||
|
||
|
||
organization_roles = { | ||
'embedded': schematics_embedded_role, | ||
'view': schematics_default_role, | ||
} |
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,112 @@ | ||
# -*- coding: utf-8 -*- | ||
from datetime import datetime | ||
from iso8601 import parse_date, ParseError | ||
from schematics.exceptions import ConversionError, ValidationError | ||
|
||
from schematics.models import Model as SchematicsModel | ||
|
||
from schematics.types import BaseType, StringType | ||
from schematics.transforms import whitelist, blacklist, export_loop | ||
|
||
from openregistry.api.constants import TZ | ||
from openregistry.api.utils import get_now, set_parent | ||
|
||
|
||
class IsoDateTimeType(BaseType): | ||
MESSAGES = { | ||
'parse': u'Could not parse {0}. Should be ISO8601.', | ||
} | ||
|
||
def to_native(self, value, context=None): | ||
if isinstance(value, datetime): | ||
return value | ||
try: | ||
date = parse_date(value, None) | ||
if not date.tzinfo: | ||
date = TZ.localize(date) | ||
return date | ||
except ParseError: | ||
raise ConversionError(self.messages['parse'].format(value)) | ||
except OverflowError as e: | ||
raise ConversionError(e.message) | ||
|
||
def to_primitive(self, value, context=None): | ||
return value.isoformat() | ||
|
||
|
||
|
||
class HashType(StringType): | ||
|
||
MESSAGES = { | ||
'hash_invalid': "Hash type is not supported.", | ||
'hash_length': "Hash value is wrong length.", | ||
'hash_hex': "Hash value is not hexadecimal.", | ||
} | ||
|
||
def to_native(self, value, context=None): | ||
value = super(HashType, self).to_native(value, context) | ||
|
||
if ':' not in value: | ||
raise ValidationError(self.messages['hash_invalid']) | ||
|
||
hash_type, hash_value = value.split(':', 1) | ||
|
||
if hash_type not in algorithms: | ||
raise ValidationError(self.messages['hash_invalid']) | ||
|
||
if len(hash_value) != hash_new(hash_type).digest_size * 2: | ||
raise ValidationError(self.messages['hash_length']) | ||
try: | ||
int(hash_value, 16) | ||
except ValueError: | ||
raise ConversionError(self.messages['hash_hex']) | ||
return value | ||
|
||
|
||
class Model(SchematicsModel): | ||
|
||
class Options(object): | ||
"""Export options for Document.""" | ||
serialize_when_none = False | ||
roles = { | ||
"default": blacklist("__parent__"), | ||
"embedded": blacklist("__parent__"), | ||
} | ||
|
||
__parent__ = BaseType() | ||
|
||
def __init__(self,*args, **kwargs): | ||
super(Model, self).__init__(*args, **kwargs) | ||
for i, j in self._data.items(): | ||
if isinstance(j, list): | ||
for x in j: | ||
set_parent(x, self) | ||
else: | ||
set_parent(j, self) | ||
|
||
def __eq__(self, other): | ||
if isinstance(other, self.__class__): | ||
for k in self._fields: | ||
if k != '__parent__' and self.get(k) != other.get(k): | ||
return False | ||
return True | ||
return NotImplemented | ||
|
||
def serialize(self, *args, **kwargs): | ||
return super(Model, self).serialize(raise_error_on_role=False, *args, **kwargs) | ||
|
||
def to_patch(self, role=None, *arg, **kwargs): | ||
""" | ||
Return data as it would be validated. No filtering of output unless | ||
role is defined. | ||
""" | ||
field_converter = lambda field, value, context: field.to_primitive(value, context) | ||
data = export_loop(self.__class__, self, field_converter=field_converter, role=role, raise_error_on_role=False, *arg, **kwargs) | ||
return data | ||
|
||
def get_role(self): | ||
root = self.__parent__ | ||
while root.__parent__ is not None: | ||
root = root.__parent__ | ||
request = root.request | ||
return 'Administrator' if request.authenticated_role == 'Administrator' else 'edit' |