[#7329] bump Ming version; change ForeignIdProperty(User) to always set allow_none=True
diff --git a/Allura/allura/model/__init__.py b/Allura/allura/model/__init__.py
index a785773..bc40872 100644
--- a/Allura/allura/model/__init__.py
+++ b/Allura/allura/model/__init__.py
@@ -26,7 +26,7 @@
from .discuss import Discussion, Thread, PostHistory, Post, DiscussionAttachment
from .attachments import BaseAttachment
from .auth import AuthGlobals, User, ProjectRole, EmailAddress, ApiToken, ApiTicket, OldProjectRole
-from .auth import AuditLog, audit_log
+from .auth import AuditLog, audit_log, AlluraUserProperty
from .filesystem import File
from .notification import Notification, Mailbox
from .repository import Repository, RepositoryImplementation
diff --git a/Allura/allura/model/auth.py b/Allura/allura/model/auth.py
index 4e93581..7d56e8c 100644
--- a/Allura/allura/model/auth.py
+++ b/Allura/allura/model/auth.py
@@ -99,6 +99,17 @@
return urllib.urlencode([i for i in generate_smart_str(params)])
+class AlluraUserProperty(ForeignIdProperty):
+ '''
+ Specialized ForeignIdProperty for users, specifically to set allow_none=True
+ since Allura uses _id=None to represent *anonymous user, and ming
+ (by default) doesn't allow a None foreign key to reference a real object
+ '''
+
+ def __init__(self, **kwargs):
+ super(AlluraUserProperty, self).__init__('User', allow_none=True, **kwargs)
+
+
class ApiAuthMixIn(object):
def authenticate_request(self, path, params):
@@ -153,7 +164,7 @@
unique_indexes = ['user_id']
_id = FieldProperty(S.ObjectId)
- user_id = ForeignIdProperty('User')
+ user_id = AlluraUserProperty()
api_key = FieldProperty(str, if_missing=lambda: str(uuid.uuid4()))
secret_key = FieldProperty(str, if_missing=h.cryptographic_nonce)
@@ -172,7 +183,7 @@
PREFIX = 'tck'
_id = FieldProperty(S.ObjectId)
- user_id = ForeignIdProperty('User')
+ user_id = AlluraUserProperty()
api_key = FieldProperty(
str, if_missing=lambda: ApiTicket.PREFIX + h.nonce(20))
secret_key = FieldProperty(str, if_missing=h.cryptographic_nonce)
@@ -786,7 +797,7 @@
]
_id = FieldProperty(S.ObjectId)
- user_id = ForeignIdProperty('User', if_missing=None)
+ user_id = AlluraUserProperty(if_missing=None)
project_id = ForeignIdProperty('Project', if_missing=None)
name = FieldProperty(str)
roles = FieldProperty([S.ObjectId])
@@ -950,5 +961,5 @@
main_orm_session.mapper(AuditLog, audit_log, properties=dict(
project_id=ForeignIdProperty('Project'),
project=RelationProperty('Project'),
- user_id=ForeignIdProperty('User'),
+ user_id=AlluraUserProperty(),
user=RelationProperty('User')))
diff --git a/Allura/allura/model/discuss.py b/Allura/allura/model/discuss.py
index b9f25d1..1f19208 100644
--- a/Allura/allura/model/discuss.py
+++ b/Allura/allura/model/discuss.py
@@ -37,7 +37,7 @@
from allura.model.notification import Notification, Mailbox
from .artifact import Artifact, ArtifactReference, VersionedArtifact, Snapshot, Message, Feed
from .attachments import BaseAttachment
-from .auth import User, ProjectRole
+from .auth import User, ProjectRole, AlluraUserProperty
from .timeline import ActivityObject
from .types import MarkdownCache
@@ -463,7 +463,7 @@
flagged_by = FieldProperty([schema.ObjectId])
flags = FieldProperty(int, if_missing=0)
last_edit_date = FieldProperty(datetime, if_missing=None)
- last_edit_by_id = ForeignIdProperty(User)
+ last_edit_by_id = AlluraUserProperty()
edit_count = FieldProperty(int, if_missing=0)
spam_check_id = FieldProperty(str, if_missing='')
text_cache = FieldProperty(MarkdownCache)
diff --git a/Allura/allura/model/notification.py b/Allura/allura/model/notification.py
index 164dc8b..ad27f5f 100644
--- a/Allura/allura/model/notification.py
+++ b/Allura/allura/model/notification.py
@@ -55,7 +55,7 @@
import allura.tasks.mail_tasks
from .session import main_orm_session
-from .auth import User
+from .auth import User, AlluraUserProperty
log = logging.getLogger(__name__)
@@ -95,7 +95,7 @@
subject = FieldProperty(str)
text = FieldProperty(str)
link = FieldProperty(str)
- author_id = ForeignIdProperty('User')
+ author_id = AlluraUserProperty()
feed_meta = FieldProperty(S.Deprecated)
artifact_reference = FieldProperty(S.Deprecated)
pubdate = FieldProperty(datetime, if_missing=datetime.utcnow)
@@ -397,7 +397,7 @@
]
_id = FieldProperty(S.ObjectId)
- user_id = ForeignIdProperty('User', if_missing=lambda: c.user._id)
+ user_id = AlluraUserProperty(if_missing=lambda: c.user._id)
project_id = ForeignIdProperty('Project', if_missing=lambda: c.project._id)
app_config_id = ForeignIdProperty(
'AppConfig', if_missing=lambda: c.app.config._id)
diff --git a/Allura/allura/model/oauth.py b/Allura/allura/model/oauth.py
index fe21cc1..14b30d1 100644
--- a/Allura/allura/model/oauth.py
+++ b/Allura/allura/model/oauth.py
@@ -27,6 +27,7 @@
from allura.lib import helpers as h
from .session import main_orm_session
from .types import MarkdownCache
+from .auth import AlluraUserProperty
log = logging.getLogger(__name__)
@@ -60,7 +61,7 @@
unique_indexes = ['name']
type = FieldProperty(str, if_missing='consumer')
- user_id = ForeignIdProperty('User', if_missing=lambda: c.user._id)
+ user_id = AlluraUserProperty(if_missing=lambda: c.user._id)
name = FieldProperty(str)
description = FieldProperty(str)
description_cache = FieldProperty(MarkdownCache)
@@ -90,7 +91,7 @@
type = FieldProperty(str, if_missing='request')
consumer_token_id = ForeignIdProperty('OAuthConsumerToken')
- user_id = ForeignIdProperty('User', if_missing=lambda: c.user._id)
+ user_id = AlluraUserProperty(if_missing=lambda: c.user._id)
callback = FieldProperty(str)
validation_pin = FieldProperty(str)
@@ -105,7 +106,7 @@
type = FieldProperty(str, if_missing='access')
consumer_token_id = ForeignIdProperty('OAuthConsumerToken')
request_token_id = ForeignIdProperty('OAuthToken')
- user_id = ForeignIdProperty('User', if_missing=lambda: c.user._id)
+ user_id = AlluraUserProperty(if_missing=lambda: c.user._id)
is_bearer = FieldProperty(bool, if_missing=False)
user = RelationProperty('User')
diff --git a/ForgeShortUrl/forgeshorturl/model/shorturl.py b/ForgeShortUrl/forgeshorturl/model/shorturl.py
index b42d30d..6682632 100644
--- a/ForgeShortUrl/forgeshorturl/model/shorturl.py
+++ b/ForgeShortUrl/forgeshorturl/model/shorturl.py
@@ -35,7 +35,7 @@
short_name = FieldProperty(str)
description = FieldProperty(str)
private = FieldProperty(bool)
- create_user = ForeignIdProperty(User)
+ create_user = M.AlluraUserProperty()
created = FieldProperty(datetime, if_missing=datetime.utcnow)
last_updated = FieldProperty(datetime, if_missing=datetime.utcnow)
diff --git a/ForgeTracker/forgetracker/model/ticket.py b/ForgeTracker/forgetracker/model/ticket.py
index b308416..738a5d8 100644
--- a/ForgeTracker/forgetracker/model/ticket.py
+++ b/ForgeTracker/forgetracker/model/ticket.py
@@ -58,6 +58,7 @@
artifact_orm_session,
project_orm_session,
+ AlluraUserProperty,
)
from allura.model.timeline import ActivityObject
from allura.model.notification import MailFooter
@@ -613,8 +614,8 @@
summary = FieldProperty(str)
description = FieldProperty(str, if_missing='')
description_cache = FieldProperty(MarkdownCache)
- reported_by_id = ForeignIdProperty(User, if_missing=lambda: c.user._id)
- assigned_to_id = ForeignIdProperty(User, if_missing=None)
+ reported_by_id = AlluraUserProperty(if_missing=lambda: c.user._id)
+ assigned_to_id = AlluraUserProperty(if_missing=None)
milestone = FieldProperty(str, if_missing='')
status = FieldProperty(str, if_missing='')
custom_fields = FieldProperty({str: None})
diff --git a/requirements-common.txt b/requirements-common.txt
index b1163cf..2721662 100644
--- a/requirements-common.txt
+++ b/requirements-common.txt
@@ -21,7 +21,7 @@
iso8601==0.1.4
Jinja2==2.6
Markdown==2.2.0
-Ming==0.4.6
+Ming==0.4.7
oauth2==1.5.170
# tg2 dep PasteDeploy must specified before TurboGears2, to avoid a version/allow-hosts problem
Paste==1.7.5.1