[#8014] ticket:859 Bring OAuthConsumerToken.upsert() back (with a fix)
diff --git a/Allura/allura/model/oauth.py b/Allura/allura/model/oauth.py
index 6dc00e5..d467dc1 100644
--- a/Allura/allura/model/oauth.py
+++ b/Allura/allura/model/oauth.py
@@ -22,8 +22,9 @@
from paste.deploy.converters import aslist
from tg import config
+import pymongo
from ming import schema as S
-from ming.orm import FieldProperty, RelationProperty, ForeignIdProperty
+from ming.orm import FieldProperty, RelationProperty, ForeignIdProperty, session
from ming.orm.declarative import MappedClass
from allura.lib import helpers as h
@@ -80,6 +81,20 @@
return oauth.Consumer(self.api_key, self.secret_key)
@classmethod
+ def upsert(cls, name, user):
+ params = dict(name=name, user_id=user._id)
+ t = cls.query.get(**params)
+ if t is not None:
+ return t
+ try:
+ t = cls(**params)
+ session(t).flush(t)
+ except pymongo.errors.DuplicateKeyError:
+ session(t).expunge(t)
+ t = cls.query.get(**params)
+ return t
+
+ @classmethod
def for_user(cls, user=None):
if user is None:
user = c.user
diff --git a/Allura/allura/tests/model/test_oauth.py b/Allura/allura/tests/model/test_oauth.py
new file mode 100644
index 0000000..c565f5d
--- /dev/null
+++ b/Allura/allura/tests/model/test_oauth.py
@@ -0,0 +1,45 @@
+# -*- coding: utf-8 -*-
+
+# Licensed to the Apache Software Foundation (ASF) under one
+# or more contributor license agreements. See the NOTICE file
+# distributed with this work for additional information
+# regarding copyright ownership. The ASF licenses this file
+# to you under the Apache License, Version 2.0 (the
+# "License"); you may not use this file except in compliance
+# with the License. You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing,
+# software distributed under the License is distributed on an
+# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+# KIND, either express or implied. See the License for the
+# specific language governing permissions and limitations
+# under the License.
+
+
+from nose.tools import with_setup, assert_equal, assert_not_equal
+
+from ming.odm import ThreadLocalORMSession
+
+from allura import model as M
+from alluratest.controller import setup_basic_test, setup_global_objects
+
+
+def setUp():
+ setup_basic_test()
+ ThreadLocalORMSession.close_all()
+ setup_global_objects()
+
+
+@with_setup(setUp)
+def test_upsert():
+ admin = M.User.by_username('test-admin')
+ user = M.User.by_username('test-user')
+ name = 'test-token'
+ token1 = M.OAuthConsumerToken.upsert(name, admin)
+ token2 = M.OAuthConsumerToken.upsert(name, admin)
+ token3 = M.OAuthConsumerToken.upsert(name, user)
+ assert_equal(M.OAuthConsumerToken.query.find().count(), 2)
+ assert_equal(token1._id, token2._id)
+ assert_not_equal(token1._id, token3._id)