예제 #1
0
async def get_user(
    user_id: str, user: UserInfo = Depends(Authentication())) -> UserViewData:
    """Gets user data."""
    is_admin = 'admin' in user['roles']
    is_self = user.sub == user_id
    if not is_self and not is_admin:
        raise HTTPException(401)
    user_data = DotDict.from_obj(await async_user_collection.find_one(
        {'_id': user_id}))
    if user_data is None:
        raise HTTPException(404)
    user_data['sub'] = user_data['_id']
    if user_data.get('picture') is not None:
        user_data[
            'picture'] = f"{config.oauth2.base_url}/picture/{user_data['picture']}"
    if 'password' in user_data:
        del user_data['password']
    return UserViewData(
        user_id=user_data['_id'],
        properties=[
            UserPropertyWithValue(key=prop,
                                  value=_get_user_property_value(
                                      prop, user_data, is_self, is_admin),
                                  **config.oauth2.user.properties[prop].dict())
            for prop in config.manager.view
            if config.oauth2.user.properties[prop].can_read.has_access(
                is_self, is_admin) or config.oauth2.user.properties[prop].
            can_edit.has_access(is_self, is_admin)
        ])
예제 #2
0
async def request_reset_user_password(
        user_id: str,
        user: UserInfo = Depends(Authentication()),
):
    is_admin = 'admin' in user['roles']
    if not is_admin:
        raise HTTPException(401)
    user_data = DotDict.from_obj(await async_user_collection.find_one(
        {'_id': user_id}))
    if user_data is None:
        raise HTTPException(404, "User not found")
    if user_data.get('registration_token'):
        await update_resend_registration(user_data)
    else:
        token_valid_until = int(time.time() +
                                config.manager.token_valid.password_reset)
        user_data['password_reset_token'] = create_token(
            user_data['_id'], token_valid_until)

        await async_user_collection.update_one({'_id': user_data['_id']}, {
            '$set': {
                'password_reset_token': user_data['password_reset_token']
            },
        })
        await async_send_mail_reset_password(user_data, token_valid_until)
예제 #3
0
async def delete_group(
        group_id: str,
        user: UserInfo = Depends(Authentication()),
):
    """Deletes a group."""
    if 'admin' not in user['roles']:
        raise HTTPException(401)
    await async_user_collection.update_many(
        {'groups': group_id},
        {
            '$pull': {
                'groups': group_id,
                'email_forward_groups': group_id,
                'email_allowed_forward_groups': group_id,
                'email_postbox_access_groups': group_id,
            },
            '$set': {'updated_at': int(time.time())},
        }
    )
    await async_client_collection.update_many(
        {'access_groups.group': group_id},
        {'$pull': {'access_groups': {'group': group_id}}},
    )
    await async_client_user_cache_collection.delete_many({'groups': group_id})
    await async_user_group_collection.update_many(
        {'member_groups': group_id},
        {'$pull': {
            'member_groups': group_id,
        }}
    )
    result = await async_user_group_collection.delete_one({'_id': group_id})
    if result.deleted_count != 1:
        raise HTTPException(404)
예제 #4
0
async def get_clients(
        user: UserInfo = Depends(Authentication()), ) -> List[ClientInList]:
    """Gets all clients."""
    if 'admin' not in user['roles']:
        raise HTTPException(401)
    return [
        ClientInList.validate(Client.validate(client))
        async for client in async_client_collection.find()
    ]
예제 #5
0
async def create_client(
        client_data: ClientInCreate = Body(...),
        user: UserInfo = Depends(Authentication()),
):
    """Creates a client."""
    if 'admin' not in user['roles']:
        raise HTTPException(401)
    new_client = Client.validate(client_data)
    await async_client_collection.insert_one(
        new_client.dict(exclude_none=True, by_alias=True))
예제 #6
0
async def get_client(
        client_id: str,
        user: UserInfo = Depends(Authentication()),
):
    """Gets a client."""
    if 'admin' not in user['roles']:
        raise HTTPException(401)
    client_data = await async_client_collection.find_one({'_id': client_id})
    if client_data is None:
        raise HTTPException(404)
    return ClientInRead.validate(Client.validate(client_data))
예제 #7
0
async def get_group(
        group_id: str,
        user: UserInfo = Depends(Authentication()),
):
    """Gets a group."""
    if 'admin' not in user['roles']:
        raise HTTPException(401)
    group_data = await async_user_group_collection.find_one({'_id': group_id})
    if group_data is None:
        raise HTTPException(404)
    return GroupInRead.validate(UserGroup.validate(group_data))
예제 #8
0
async def delete_client(
        client_id: str,
        user: UserInfo = Depends(Authentication()),
):
    """Deletes a client."""
    if 'admin' not in user['roles']:
        raise HTTPException(401)
    await async_client_user_cache_collection.delete_many(
        {'client_id': client_id})
    result = await async_client_collection.delete_one({'_id': client_id})
    if result.deleted_count != 1:
        raise HTTPException(404)
예제 #9
0
async def get_groups(
        user: UserInfo = Depends(Authentication()),
) -> List[GroupInList]:
    """Gets all groups."""
    if 'admin' in user['roles']:
        group_filter = {}
    else:
        group_filter = {'visible': True}
    return [
        GroupInList.validate(UserGroup.validate(group))
        async for group in async_user_group_collection.find(group_filter)
    ]
예제 #10
0
async def create_user(no_registration: bool = Query(False),
                      create_data: Dict[str, Any] = Body(...),
                      user: UserInfo = Depends(Authentication())):
    """Updates user data."""
    is_admin = 'admin' in user['roles']
    if not is_admin:
        raise HTTPException(401)

    user_data = DotDict()
    await _update_user(user_data,
                       create_data,
                       is_new=True,
                       is_admin=True,
                       no_registration=no_registration)
예제 #11
0
async def create_group(
        group_data: GroupInCreate = Body(...),
        user: UserInfo = Depends(Authentication()),
):
    """Creates a group."""
    if 'admin' not in user['roles']:
        raise HTTPException(401)
    new_group = UserGroup.validate(group_data)
    new_group.id = new_group.id.lower()
    if not new_group.enable_email:
        new_group.email_forward_members = []
        new_group.email_allowed_forward_members = []
    if not new_group.enable_postbox:
        new_group.email_postbox_access_members = []
    await async_user_group_collection.insert_one(new_group.dict(exclude_none=True, by_alias=True))
    timestamp = int(time.time())
    if new_group.members:
        await async_client_user_cache_collection.delete_many({'user_id': {'$in': new_group.members}})
        await async_user_collection.update_many(
            {'_id': {'$in': new_group.members}},
            {
                '$addToSet': {'groups': new_group.id},
                '$set': {'updated_at': timestamp},
            }
        )
    if new_group.email_forward_members:
        await async_user_collection.update_many(
            {'_id': {'$in': new_group.email_forward_members}},
            {
                '$addToSet': {'email_forward_groups': new_group.id},
                '$set': {'updated_at': timestamp},
            }
        )
    if new_group.email_allowed_forward_members:
        await async_user_collection.update_many(
            {'_id': {'$in': new_group.email_allowed_forward_members}},
            {
                '$addToSet': {'email_allowed_forward_groups': new_group.id},
                '$set': {'updated_at': timestamp},
            }
        )
    if new_group.email_postbox_access_members:
        await async_user_collection.update_many(
            {'_id': {'$in': new_group.email_postbox_access_members}},
            {
                '$addToSet': {'email_postbox_access_groups': new_group.id},
                '$set': {'updated_at': timestamp},
            }
        )
예제 #12
0
async def update_user(user_id: str,
                      update_data: Dict[str, Any] = Body(...),
                      user: UserInfo = Depends(Authentication())):
    """Updates user data."""
    is_admin = 'admin' in user['roles']
    is_self = user.sub == user_id
    if not is_self and not is_admin:
        raise HTTPException(401)
    user_data = DotDict.from_obj(await async_user_collection.find_one(
        {'_id': user_id}))
    if user_data is None:
        raise HTTPException(404)
    if not update_data:
        return
    await _update_user(user_data,
                       update_data,
                       is_admin=is_admin,
                       is_self=is_self)
예제 #13
0
def get_create_user(user: UserInfo = Depends(
    Authentication())) -> UserViewData:
    """Gets user data for creation."""
    is_admin = 'admin' in user['roles']
    if not is_admin:
        raise HTTPException(401)

    return UserViewData(
        user_id="new",
        properties=[
            UserPropertyWithValue(
                key=prop,
                value=config.oauth2.user.properties[prop].default,
                **config.oauth2.user.properties[prop].dict())
            for prop in config.manager.view
            if config.oauth2.user.properties[prop].can_read.has_access(
                is_admin=is_admin) or config.oauth2.user.properties[prop].
            can_edit.has_access(is_admin=is_admin)
        ])
예제 #14
0
async def update_client(
        client_id: str,
        client_update: ClientInWrite,
        user: UserInfo = Depends(Authentication()),
):
    """Updates a client."""
    if 'admin' not in user['roles']:
        raise HTTPException(401)
    if await async_client_collection.count_documents({'_id': client_id}) != 1:
        raise HTTPException(404)

    client = Client.validate(client_update)
    await async_client_user_cache_collection.delete_many(
        {'client_id': client_id})
    result = await async_client_collection.replace_one(
        {'_id': client_id},
        client.dict(exclude_none=True, by_alias=True),
    )
    if result.matched_count != 1:
        raise HTTPException(404)
예제 #15
0
async def update_group(
        group_id: str,
        group_update: GroupInWrite,
        user: UserInfo = Depends(Authentication()),
):
    """Updates a group."""
    if 'admin' not in user['roles']:
        raise HTTPException(401)
    group_data = await async_user_group_collection.find_one({'_id': group_id})
    if group_data is None:
        raise HTTPException(404)
    group = UserGroup.validate(group_data)

    if not group_update.enable_email:
        group_update.email_forward_members = []
        group_update.email_allowed_forward_members = []
    if not group_update.enable_postbox:
        group_update.email_postbox_access_members = []

    await _update_groups(
        group,
        group_update,
        attr_name='members',
        add_user_attr_name='groups',
        pull_user_attr_names=('groups', 'email_forward_groups', 'email_allowed_forward_groups'),
        pull_group_attr_names=(
            'email_forward_members', 'email_allowed_forward_members', 'email_postbox_access_members'
        ),
        clear_cache=True,
    )
    await _update_groups(
        group,
        group_update,
        attr_name='email_allowed_forward_members',
        add_user_attr_name='email_allowed_forward_groups',
        pull_user_attr_names=('email_forward_groups', 'email_allowed_forward_groups'),
        pull_group_attr_names=('email_forward_members',),
        clear_cache=False,
    )
    await _update_groups(
        group,
        group_update,
        attr_name='email_forward_members',
        add_user_attr_name='email_forward_groups',
        pull_user_attr_names=('email_forward_groups',),
        clear_cache=False,
    )
    await _update_groups(
        group,
        group_update,
        attr_name='email_postbox_access_members',
        add_user_attr_name='email_postbox_access_groups',
        pull_user_attr_names=('email_postbox_access_groups',),
        clear_cache=False,
    )

    group.update_from(group_update)
    result = await async_user_group_collection.replace_one(
        {'_id': group_id},
        group.dict(exclude_none=True, by_alias=True),
    )
    if result.matched_count != 1:
        raise HTTPException(404)