Commits

Marcin Kuzminski committed 12ceeda

#404 API extensions for showing permission for users
- added permissions to get_user function
- added last_login to get_user and get_users function
- modified custom JSON encoder to handle non standard python types, like set, OrderedDict, datetime, date

  • Participants
  • Parent commits a8c9c00

Comments (0)

Files changed (5)

File docs/api/api.rst

                 "email" :    "<email>",
                 "active" :   "<bool>",
                 "admin" :    "<bool>",
-                "ldap_dn" :  "<ldap_dn>"
+                "ldap_dn" :  "<ldap_dn>",
+                "last_login": "<last_login>",
+                "permissions": {
+                    "global": ["hg.create.repository",
+                               "repository.read",
+                               "hg.register.manual_activate"],
+                    "repositories": {"repo1": "repository.none"},
+                    "repositories_groups": {"Group1": "group.read"}
+                 },
             }
 
     error:  null
                 "email" :    "<email>",
                 "active" :   "<bool>",
                 "admin" :    "<bool>",
-                "ldap_dn" :  "<ldap_dn>"
+                "ldap_dn" :  "<ldap_dn>",
+                "last_login": "<last_login>",
               },
             ]

File docs/changelog.rst

 - fixed #393 py2.5 fixes for routes url generator
 - fixed #397 Private repository groups shows up before login
 - fixed #396 fixed problems with revoking users in nested groups
+- fixed mysql unicode issues + specified InnoDB as default engine with 
+  utf8 charset
   
 1.3.3 (**2012-03-02**)
 ----------------------

File rhodecode/controllers/api/__init__.py

         try:
             return json.dumps(response)
         except TypeError, e:
-            log.debug('Error encoding response: %s' % e)
+            log.error('API FAILED. Error encoding response: %s' % e)
             return json.dumps(
                 dict(
-                    self._req_id,
+                    id=self._req_id,
                     result=None,
                     error="Error encoding response"
                 )

File rhodecode/controllers/api/api.py

 
 from rhodecode.controllers.api import JSONRPCController, JSONRPCError
 from rhodecode.lib.auth import HasPermissionAllDecorator, \
-    HasPermissionAnyDecorator, PasswordGenerator
+    HasPermissionAnyDecorator, PasswordGenerator, AuthUser
 
 from rhodecode.model.meta import Session
 from rhodecode.model.scm import ScmModel
-from rhodecode.model.db import User, UsersGroup, RepoGroup, Repository
+from rhodecode.model.db import User, UsersGroup, Repository
 from rhodecode.model.repo import RepoModel
 from rhodecode.model.user import UserModel
 from rhodecode.model.users_group import UsersGroupModel
-from rhodecode.model.repos_group import ReposGroupModel
 from rhodecode.lib.utils import map_groups
 
-
 log = logging.getLogger(__name__)
 
 
             email=user.email,
             active=user.active,
             admin=user.admin,
-            ldap_dn=user.ldap_dn
+            ldap_dn=user.ldap_dn,
+            last_login=user.last_login,
+            permissions=AuthUser(user_id=user.user_id).permissions
         )
 
     @HasPermissionAllDecorator('hg.admin')
                     email=user.email,
                     active=user.active,
                     admin=user.admin,
-                    ldap_dn=user.ldap_dn
+                    ldap_dn=user.ldap_dn,
+                    last_login=user.last_login,
                 )
             )
         return result

File rhodecode/lib/compat.py

 # along with this program.  If not, see <http://www.gnu.org/licenses/>.
 
 import os
+import datetime
+import functools
 from rhodecode import __platform__, PLATFORM_WIN
 
 #==============================================================================
 # json
 #==============================================================================
+
+
+def __obj_dump(obj):
+    DATETIME_FORMAT = "%Y-%m-%dT%H:%M:%S"
+    DATE_FORMAT = "%Y-%m-%d"
+    if isinstance(obj, complex):
+        return [obj.real, obj.imag]
+    elif isinstance(obj, datetime.datetime):
+        return obj.strftime(DATETIME_FORMAT)
+    elif isinstance(obj, datetime.date):
+        return obj.strftime(DATE_FORMAT)
+    elif isinstance(obj, set):
+        return list(obj)
+    elif isinstance(obj, OrderedDict):
+        return obj.as_dict()
+    else:
+        raise NotImplementedError
+
 try:
     import json
+
+    # extended JSON encoder for json
+    class ExtendedEncoder(json.JSONEncoder):
+        def default(self, obj):
+            try:
+                return __obj_dump(obj)
+            except NotImplementedError:
+                pass
+            return json.JSONEncoder.default(self, obj)
+    # monkey-patch JSON encoder to use extended version
+    json.dumps = functools.partial(json.dumps, cls=ExtendedEncoder)
 except ImportError:
     import simplejson as json
 
+    def extended_encode(obj):
+        try:
+            return __obj_dump(obj)
+        except NotImplementedError:
+            pass
+        raise TypeError("%r is not JSON serializable" % (obj,))
+    json.dumps = functools.partial(json.dumps, default=extended_encode)
+
 
 #==============================================================================
 # izip_longest
 except ImportError:
     import itertools
 
-    def izip_longest(*args, **kwds): # noqa
+    def izip_longest(*args, **kwds):
         fillvalue = kwds.get("fillvalue")
 
         def sentinel(counter=([fillvalue] * (len(args) - 1)).pop):
-            yield counter() # yields the fillvalue, or raises IndexError
+            yield counter()  # yields the fillvalue, or raises IndexError
 
         fillers = itertools.repeat(fillvalue)
         iters = [itertools.chain(it, sentinel(), fillers)