# Path: amivapi/utils.py
# def get_id(item):
#     """Get the id of a field in a relation. Depending on the embedding clause
#     a field returned by a mongo query may be an ID or an object. This function
#     will get the ID in both cases.
# 
#     Args:
#         item: Either an object from the database as a dict or an object id as
#             str or objectid.
# 
#     Returns:
#         ObjectId with the user ID
#     """
#     try:
#         return ObjectId(item)
#     except TypeError:
#         return ObjectId(item['_id'])
# 
# Path: amivapi/auth/auth.py
# class AmivTokenAuth(BasicAuth):
#     """Amiv authentication and authorization base class.
# 
#     Subclass and overwrite functions if you don't want default behaviour.
#     """
# 
#     def authorized(self, allowed_roles, resource, method):
#         """Authorize Request.
# 
#         This is the method Eve will call if the endpoint is not public.
# 
#         We use this by setting `g.auth_required` to inform auth hook to abort
#         later if user can't be identified.
# 
#         Do NOT overwrite this when subclassing `AmivTokenAuth`.
#         """
#         g.auth_required = True
#         return True
# 
#     def has_resource_write_permission(self, user_id):
#         """Check if the user is alllowed to write to the resource.
# 
#         Implement this function for your resource.
#         Default behaviour: No user has write permission.
# 
#         Args:
#             user_id (str): The if of the user
# 
#         Returns:
#             bool: True if user has permission to write, False otherwise.
#         """
#         return False
# 
#     def has_item_write_permission(self, user_id, item):
#         """Check if the user is allowed to modify the item.
# 
#         Implement this function for your resource.
#         Default behaviour: No user has write permission.
# 
#         Args:
#             user (str): The id of the user that wants to access the item
#             item (dict): The item the user wants to change or delete.
#                 Attention! If they are any ObjectIds in here, Eve will not have
#                 converted them yet, so be sure to cast them to str if you want
#                 to compare them to e.g. g.current_user
# 
#         Returns:
#             bool: True if user has permission to change the item, False if not.
#         """
#         return False
# 
#     def create_user_lookup_filter(self, user_id):
#         """Create a filter for item lookup in GET, PATCH and DELETE.
# 
#         Implement this function for your resource.
#         Default behaviour: No lookup filter.
# 
#         Args:
#             user_id (str): The id of the user
# 
#         Returns:
#             dict: The filter, will be combined with other filters in the hook.
#                 Return empty dict if no filters should be applied.
#                 Return None if no lookup should be possible for the user.
#         """
#         return {}
# 
# Path: amivapi/settings.py
# EMAIL_REGEX = '^.+@.+$'


from bson import ObjectId
from flask import current_app
from amivapi.utils import get_id
from amivapi.auth import AmivTokenAuth
from amivapi.settings import EMAIL_REGEX
        Groups can be seen:
        - by the moderator and member
        - everyone, if self enrollment is allowed
        """
        # Find groups the user is in
        collection = current_app.data.driver.db['groupmemberships']
        memberships = collection.find({'user': ObjectId(user_id)},
                                      {'group': 1})
        groups = [item['group'] for item in memberships]

        return {'$or': [
            {'_id': {'$in': groups}},
            {'moderator': ObjectId(user_id)},
            {'allow_self_enrollment': True}
        ]}


class GroupMembershipAuth(AmivTokenAuth):
    """Auth for group memberships."""

    def has_resource_write_permission(self, user_id):
        """All users can enroll in groups.

        Group-specific settings related to the question "who is allowed to
        enroll for this group?" are done in the validator.
        """
        return True

    def has_item_write_permission(self, user_id, item):
        """The group moderator and the member can change an enrollment."""

# Path: amivapi/utils.py
# def get_id(item):
#     """Get the id of a field in a relation. Depending on the embedding clause
#     a field returned by a mongo query may be an ID or an object. This function
#     will get the ID in both cases.
# 
#     Args:
#         item: Either an object from the database as a dict or an object id as
#             str or objectid.
# 
#     Returns:
#         ObjectId with the user ID
#     """
#     try:
#         return ObjectId(item)
#     except TypeError:
#         return ObjectId(item['_id'])
# 
# Path: amivapi/auth/auth.py
# class AmivTokenAuth(BasicAuth):
#     """Amiv authentication and authorization base class.
# 
#     Subclass and overwrite functions if you don't want default behaviour.
#     """
# 
#     def authorized(self, allowed_roles, resource, method):
#         """Authorize Request.
# 
#         This is the method Eve will call if the endpoint is not public.
# 
#         We use this by setting `g.auth_required` to inform auth hook to abort
#         later if user can't be identified.
# 
#         Do NOT overwrite this when subclassing `AmivTokenAuth`.
#         """
#         g.auth_required = True
#         return True
# 
#     def has_resource_write_permission(self, user_id):
#         """Check if the user is alllowed to write to the resource.
# 
#         Implement this function for your resource.
#         Default behaviour: No user has write permission.
# 
#         Args:
#             user_id (str): The if of the user
# 
#         Returns:
#             bool: True if user has permission to write, False otherwise.
#         """
#         return False
# 
#     def has_item_write_permission(self, user_id, item):
#         """Check if the user is allowed to modify the item.
# 
#         Implement this function for your resource.
#         Default behaviour: No user has write permission.
# 
#         Args:
#             user (str): The id of the user that wants to access the item
#             item (dict): The item the user wants to change or delete.
#                 Attention! If they are any ObjectIds in here, Eve will not have
#                 converted them yet, so be sure to cast them to str if you want
#                 to compare them to e.g. g.current_user
# 
#         Returns:
#             bool: True if user has permission to change the item, False if not.
#         """
#         return False
# 
#     def create_user_lookup_filter(self, user_id):
#         """Create a filter for item lookup in GET, PATCH and DELETE.
# 
#         Implement this function for your resource.
#         Default behaviour: No lookup filter.
# 
#         Args:
#             user_id (str): The id of the user
# 
#         Returns:
#             dict: The filter, will be combined with other filters in the hook.
#                 Return empty dict if no filters should be applied.
#                 Return None if no lookup should be possible for the user.
#         """
#         return {}
# 
# Path: amivapi/settings.py
# EMAIL_REGEX = '^.+@.+$'


# Path: amivapi/groups/model.py
from bson import ObjectId
from flask import current_app
from amivapi.utils import get_id
from amivapi.auth import AmivTokenAuth
from amivapi.settings import EMAIL_REGEX

        Groups can be seen:
        - by the moderator and member
        - everyone, if self enrollment is allowed
        """
        # Find groups the user is in
        collection = current_app.data.driver.db['groupmemberships']
        memberships = collection.find({'user': ObjectId(user_id)},
                                      {'group': 1})
        groups = [item['group'] for item in memberships]

        return {'$or': [
            {'_id': {'$in': groups}},
            {'moderator': ObjectId(user_id)},
            {'allow_self_enrollment': True}
        ]}


class GroupMembershipAuth(AmivTokenAuth):
    """Auth for group memberships."""

    def has_resource_write_permission(self, user_id):
        """All users can enroll in groups.

        Group-specific settings related to the question "who is allowed to
        enroll for this group?" are done in the validator.
        """
        return True

    def has_item_write_permission(self, user_id, item):
        """The group moderator and the member can change an enrollment."""

        if user_id == str(get_id(item['user'])):