# 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
An **admin** can see all groups, can add any user to any group (this is the
only way to add members to groups that do not allow self enrollment), and can
also update groups.

A group has a **moderator**, specified by the `moderator` field. The moderator
has the same permissions as an admin, but only for the moderated group.
An exception to this are group permissions (see below): These can only be
changed by admins.

<br />

## Mailing Lists

Groups act as mailing lists, so that all members of a group can be reached
quickly.

A group mailing list can receive mail from multiple addresses specified by the
`receive_from` field. This can only be the *local part* of the address
(e.g. `john` instead of `john@smith.com`), as the mail server address cannot
be influenced by the API.

All emails sent to the mailing list are forwarded to

- all members of the group,
- and additional email addresses specified in the `forward_to` field

### Example

| Group          |                               |
|----------------|-------------------------------|

# 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

An **admin** can see all groups, can add any user to any group (this is the
only way to add members to groups that do not allow self enrollment), and can
also update groups.

A group has a **moderator**, specified by the `moderator` field. The moderator
has the same permissions as an admin, but only for the moderated group.
An exception to this are group permissions (see below): These can only be
changed by admins.

<br />

## Mailing Lists

Groups act as mailing lists, so that all members of a group can be reached
quickly.

A group mailing list can receive mail from multiple addresses specified by the
`receive_from` field. This can only be the *local part* of the address
(e.g. `john` instead of `john@smith.com`), as the mail server address cannot
be influenced by the API.

All emails sent to the mailing list are forwarded to

- all members of the group,
- and additional email addresses specified in the `forward_to` field

### Example

| Group          |                               |
|----------------|-------------------------------|

| Members        | Pablo (email: `pablo@api.ch`) |