Repository: fossasia/open-event-server

Issue:
Trying to access (is_user_itself) permission for endpoints "any/<any_id>/user" gives KeyError: 'id'
**I'm submitting a ...**  (check one with "x")
- [X] bug report
- [ ] feature request
- [ ] support request => Please do not submit support requests here, instead ask your query in out Gitter channel at https://gitter.im/fossasia/open-event-orga-server

**Reproduce:**
<!-- Describe how the bug manifests. -->
Example: `/users-events-roles/<int:users_events_role_id>/user` or `/event-invoices/<int:event_invoice_id>/user`

**Reason for error:**
check for `user.id != kwargs['id']` in permission



Discussion:

Resolving patch:
diff --git a/app/api/helpers/permission_manager.py b/app/api/helpers/permission_manager.py
--- a/app/api/helpers/permission_manager.py
+++ b/app/api/helpers/permission_manager.py
@@ -241,7 +241,7 @@ def permission_manager(view, view_args, view_kwargs, *args, **kwargs):
                     break
         elif kwargs['fetch'] in view_kwargs:
             fetched = view_kwargs[kwargs['fetch']]
-        elif not fetched:
+        if not fetched:
             model = kwargs['model']
             fetch = kwargs['fetch']
             fetch_as = kwargs['fetch_as']
diff --git a/app/api/helpers/permissions.py b/app/api/helpers/permissions.py
--- a/app/api/helpers/permissions.py
+++ b/app/api/helpers/permissions.py
@@ -95,12 +95,6 @@ def is_user_itself(f):
     @wraps(f)
     def decorated_function(*args, **kwargs):
         user = current_identity
-        if 'email_notification_id' in kwargs:
-            try:
-                email_notification = EmailNotification.query.filter_by(id=kwargs['email_notification_id']).one()
-            except NoResultFound, e:
-                return NotFoundError({'parameter': 'email_notification_id'}, 'EmailNotification not found.').respond()
-            kwargs['id'] = email_notification.user_id
         if not user.is_admin and not user.is_super_admin and user.id != kwargs['id']:
             return ForbiddenError({'source': ''}, 'Access Forbidden').respond()
         return f(*args, **kwargs)
diff --git a/app/api/users.py b/app/api/users.py
--- a/app/api/users.py
+++ b/app/api/users.py
@@ -9,8 +9,10 @@
 from app.models.user import User
 from app.models.notification import Notification
 from app.models.users_events_role import UsersEventsRoles
+from app.models.email_notification import EmailNotification
 from app.models.event_invoice import EventInvoice
 from app.models.access_code import AccessCode
+from app.models.discount_code import DiscountCode
 from app.api.helpers.permissions import is_user_itself, jwt_required
 from app.models.speaker import Speaker
 from app.api.helpers.exceptions import ConflictException
@@ -159,6 +161,13 @@ def before_get_object(self, view_kwargs):
             else:
                 view_kwargs['id'] = None
 
+        if view_kwargs.get('email_notification_id') is not None:
+            email_notification = safe_query(self, EmailNotification, 'id', view_kwargs['email_notification_id'], 'email_notification_id')
+            if email_notification.user_id is not None:
+                view_kwargs['id'] = email_notification.user_id
+            else:
+                view_kwargs['id'] = None
+
     def before_update_object(self, user, data, view_kwargs):
         if data.get('original_image_url') and data['original_image_url'] != user.original_image_url:
             uploaded_images = create_save_image_sizes(data['original_image_url'], 'user', user.id)
@@ -174,7 +183,11 @@ def before_update_object(self, user, data, view_kwargs):
             if data.get('icon_image_url'):
                 del data['icon_image_url']
 
-    decorators = (is_user_itself, )
+    decorators = (api.has_permission('is_user_itself', fetch="user_id,id", fetch_as="id",
+                  model=[Notification, UsersEventsRoles, EventInvoice, AccessCode,
+                         DiscountCode, EmailNotification, User],
+                  fetch_key_url="notification_id, users_events_role_id,\
+                  event_invoice_id, access_code_id, discount_code_id, email_notification_id, id"),)
     schema = UserSchema
     data_layer = {'session': db.session,
                   'model': User,


Test patch: