893 lines
32 KiB
Python
893 lines
32 KiB
Python
# authentic2 - versatile identity manager
|
|
# Copyright (C) 2010-2020 Entr'ouvert
|
|
#
|
|
# This program is free software: you can redistribute it and/or modify it
|
|
# under the terms of the GNU Affero General Public License as published
|
|
# by the Free Software Foundation, either version 3 of the License, or
|
|
# (at your option) any later version.
|
|
#
|
|
# This program is distributed in the hope that it will be useful,
|
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
# GNU Affero General Public License for more details.
|
|
#
|
|
# You should have received a copy of the GNU Affero General Public License
|
|
# along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
|
import datetime
|
|
import mock
|
|
|
|
from authentic2.custom_user.models import User
|
|
from authentic2.a2_rbac.utils import get_default_ou
|
|
from authentic2.a2_rbac.models import Role
|
|
from authentic2.models import Service
|
|
from authentic2.apps.journal.models import Event, _registry
|
|
from authentic2.journal import journal
|
|
|
|
from django.contrib.sessions.models import Session
|
|
from django.utils.timezone import make_aware
|
|
|
|
import pytest
|
|
|
|
from .utils import login, text_content
|
|
|
|
|
|
def test_journal_authorization(app, db, admin):
|
|
response = login(app, admin, path='/manage/')
|
|
assert 'Journal' not in response
|
|
app.get('/manage/journal/', status=403)
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def events(db, freezer):
|
|
session1 = Session(session_key="1234")
|
|
session2 = Session(session_key="abcd")
|
|
|
|
ou = get_default_ou()
|
|
user = User.objects.create(
|
|
username="user", email="user@example.com", ou=ou, uuid="1" * 32, first_name='Johnny', last_name='doe'
|
|
)
|
|
agent = User.objects.create(username="agent", email="agent@example.com", ou=ou, uuid="2" * 32)
|
|
role_user = Role.objects.create(name="role1", ou=ou)
|
|
role_agent = Role.objects.create(name="role2", ou=ou)
|
|
service = Service.objects.create(name="service")
|
|
|
|
class EventFactory:
|
|
date = make_aware(datetime.datetime(2020, 1, 1))
|
|
|
|
def __call__(self, name, **kwargs):
|
|
freezer.move_to(self.date)
|
|
journal.record(name, **kwargs)
|
|
assert Event.objects.latest("timestamp").type.name == name
|
|
self.date += datetime.timedelta(hours=1)
|
|
|
|
make = EventFactory()
|
|
make("user.registration.request", email=user.email)
|
|
make(
|
|
"user.registration", user=user, session=session1, service=service, how="franceconnect",
|
|
)
|
|
make("user.logout", user=user, session=session1)
|
|
|
|
make("user.login.failure", username="user")
|
|
make("user.login.failure", username="agent")
|
|
make("user.login", user=user, session=session1, how="password")
|
|
make("user.password.change", user=user, session=session1)
|
|
edit_profile_form = mock.Mock()
|
|
edit_profile_form.initial = {'email': "user@example.com", 'first_name': "John"}
|
|
edit_profile_form.changed_data = ["first_name"]
|
|
edit_profile_form.cleaned_data = {'first_name': "Jane"}
|
|
make("user.profile.edit", user=user, session=session1, form=edit_profile_form)
|
|
make("user.service.sso.authorization", user=user, session=session1, service=service)
|
|
make("user.service.sso", user=user, session=session1, service=service, how="password")
|
|
make("user.service.sso.unauthorization", user=user, session=session1, service=service)
|
|
make("user.deletion", user=user, session=session1, service=service)
|
|
|
|
make("user.password.reset.request", email="USER@example.com", user=user)
|
|
make("user.password.reset.failure", email="USER@example.com")
|
|
make("user.password.reset", user=user)
|
|
|
|
make("user.login", user=agent, session=session2, how="saml")
|
|
|
|
create_form = mock.Mock(spec=["instance"])
|
|
create_form.instance = user
|
|
make("manager.user.creation", user=agent, session=session2, form=create_form)
|
|
|
|
edit_form = mock.Mock(spec=["instance", "initial", "changed_data", "cleaned_data"])
|
|
edit_form.instance = user
|
|
edit_form.initial = {'email': "user@example.com", 'first_name': "John"}
|
|
edit_form.changed_data = ["first_name"]
|
|
edit_form.cleaned_data = {'first_name': "Jane"}
|
|
make("manager.user.profile.edit", user=agent, session=session2, form=edit_form)
|
|
|
|
change_email_form = mock.Mock(spec=["instance", "cleaned_data"])
|
|
change_email_form.instance = user
|
|
change_email_form.cleaned_data = {'new_email': "jane@example.com"}
|
|
make(
|
|
"manager.user.email.change.request", user=agent, session=session2, form=change_email_form,
|
|
)
|
|
|
|
password_change_form = mock.Mock(spec=["instance", "cleaned_data"])
|
|
password_change_form.instance = user
|
|
password_change_form.cleaned_data = {'generate_password': False, 'send_mail': False}
|
|
make(
|
|
"manager.user.password.change", user=agent, session=session2, form=password_change_form,
|
|
)
|
|
|
|
password_change_form.cleaned_data["send_mail"] = True
|
|
make(
|
|
"manager.user.password.change", user=agent, session=session2, form=password_change_form,
|
|
)
|
|
|
|
make(
|
|
"manager.user.password.reset.request", user=agent, session=session2, target_user=user,
|
|
)
|
|
|
|
make(
|
|
"manager.user.password.change.force", user=agent, session=session2, target_user=user,
|
|
)
|
|
make(
|
|
"manager.user.password.change.unforce", user=agent, session=session2, target_user=user,
|
|
)
|
|
|
|
make("manager.user.activation", user=agent, session=session2, target_user=user)
|
|
make("manager.user.deactivation", user=agent, session=session2, target_user=user)
|
|
make("manager.user.deletion", user=agent, session=session2, target_user=user)
|
|
make(
|
|
"manager.user.sso.authorization.deletion",
|
|
user=agent,
|
|
session=session2,
|
|
service=service,
|
|
target_user=user,
|
|
)
|
|
|
|
make("manager.role.creation", user=agent, session=session2, role=role_user)
|
|
role_edit_form = mock.Mock(spec=["instance", "initial", "changed_data", "cleaned_data"])
|
|
role_edit_form.instance = role_user
|
|
role_edit_form.initial = {'name': role_user.name}
|
|
role_edit_form.changed_data = ["name"]
|
|
role_edit_form.cleaned_data = {'name': "changed role name"}
|
|
make(
|
|
"manager.role.edit", user=agent, session=session2, role=role_user, form=role_edit_form,
|
|
)
|
|
make("manager.role.deletion", user=agent, session=session2, role=role_user)
|
|
make(
|
|
"manager.role.membership.grant", user=agent, session=session2, role=role_user, member=user,
|
|
)
|
|
make(
|
|
"manager.role.membership.removal", user=agent, session=session2, role=role_user, member=user,
|
|
)
|
|
|
|
make(
|
|
"manager.role.inheritance.addition", user=agent, session=session2, parent=role_agent, child=role_user,
|
|
)
|
|
make(
|
|
"manager.role.inheritance.removal", user=agent, session=session2, parent=role_agent, child=role_user,
|
|
)
|
|
|
|
make(
|
|
"manager.role.administrator.role.addition",
|
|
user=agent,
|
|
session=session2,
|
|
role=role_user,
|
|
admin_role=role_agent,
|
|
)
|
|
make(
|
|
"manager.role.administrator.role.removal",
|
|
user=agent,
|
|
session=session2,
|
|
role=role_user,
|
|
admin_role=role_agent,
|
|
)
|
|
|
|
make(
|
|
"manager.role.administrator.user.addition",
|
|
user=agent,
|
|
session=session2,
|
|
role=role_user,
|
|
admin_user=user,
|
|
)
|
|
make(
|
|
"manager.role.administrator.user.removal",
|
|
user=agent,
|
|
session=session2,
|
|
role=role_user,
|
|
admin_user=user,
|
|
)
|
|
|
|
# verify we created at least one event for each type
|
|
assert set(Event.objects.values_list("type__name", flat=True)) == set(_registry)
|
|
|
|
return locals()
|
|
|
|
|
|
def extract_journal(response):
|
|
rows = []
|
|
seen_event_ids = set()
|
|
while True:
|
|
for tr in response.pyquery("tr[data-event-type]"):
|
|
# page can overlap when they contain less than 20 items (to prevent orphan rows)
|
|
event_id = tr.attrib["data-event-id"]
|
|
if event_id not in seen_event_ids:
|
|
rows.append(response.pyquery(tr))
|
|
seen_event_ids.add(event_id)
|
|
if "Previous page" not in response:
|
|
break
|
|
response = response.click("Previous page", index=0)
|
|
|
|
rows.reverse()
|
|
content = [
|
|
{
|
|
'timestamp': text_content(row.find(".journal-list--timestamp-column")[0]).strip(),
|
|
'type': row[0].attrib["data-event-type"],
|
|
'user': text_content(row.find(".journal-list--user-column")[0]).strip(),
|
|
'message': text_content(row.find(".journal-list--message-column")[0]),
|
|
}
|
|
for row in rows
|
|
]
|
|
return content
|
|
|
|
|
|
def test_global_journal(app, superuser, events):
|
|
response = login(app, user=superuser, path="/manage/")
|
|
|
|
# remove event about admin login
|
|
Event.objects.filter(user=superuser).delete()
|
|
|
|
response = response.click(href="journal")
|
|
|
|
content = extract_journal(response)
|
|
|
|
assert content == [
|
|
{
|
|
'message': 'registration request with email "user@example.com"',
|
|
'timestamp': 'Jan. 1, 2020, midnight',
|
|
'type': 'user.registration.request',
|
|
'user': '-',
|
|
},
|
|
{
|
|
'message': 'registration using franceconnect',
|
|
'timestamp': 'Jan. 1, 2020, 1 a.m.',
|
|
'type': 'user.registration',
|
|
'user': 'Johnny doe',
|
|
},
|
|
{
|
|
'message': 'logout',
|
|
'timestamp': 'Jan. 1, 2020, 2 a.m.',
|
|
'type': 'user.logout',
|
|
'user': 'Johnny doe',
|
|
},
|
|
{
|
|
'message': 'login failure with username "user"',
|
|
'timestamp': 'Jan. 1, 2020, 3 a.m.',
|
|
'type': 'user.login.failure',
|
|
'user': '-',
|
|
},
|
|
{
|
|
'message': 'login failure with username "agent"',
|
|
'timestamp': 'Jan. 1, 2020, 4 a.m.',
|
|
'type': 'user.login.failure',
|
|
'user': '-',
|
|
},
|
|
{
|
|
'message': 'login using password',
|
|
'timestamp': 'Jan. 1, 2020, 5 a.m.',
|
|
'type': 'user.login',
|
|
'user': 'Johnny doe',
|
|
},
|
|
{
|
|
'message': 'password change',
|
|
'timestamp': 'Jan. 1, 2020, 6 a.m.',
|
|
'type': 'user.password.change',
|
|
'user': 'Johnny doe',
|
|
},
|
|
{
|
|
'message': 'profile edit (first name)',
|
|
'timestamp': 'Jan. 1, 2020, 7 a.m.',
|
|
'type': 'user.profile.edit',
|
|
'user': 'Johnny doe',
|
|
},
|
|
{
|
|
'message': 'authorization of single sign on with "service"',
|
|
'timestamp': 'Jan. 1, 2020, 8 a.m.',
|
|
'type': 'user.service.sso.authorization',
|
|
'user': 'Johnny doe',
|
|
},
|
|
{
|
|
'message': 'service single sign on with "service"',
|
|
'timestamp': 'Jan. 1, 2020, 9 a.m.',
|
|
'type': 'user.service.sso',
|
|
'user': 'Johnny doe',
|
|
},
|
|
{
|
|
'message': 'unauthorization of single sign on with "service"',
|
|
'timestamp': 'Jan. 1, 2020, 10 a.m.',
|
|
'type': 'user.service.sso.unauthorization',
|
|
'user': 'Johnny doe',
|
|
},
|
|
{
|
|
'message': 'user deletion',
|
|
'timestamp': 'Jan. 1, 2020, 11 a.m.',
|
|
'type': 'user.deletion',
|
|
'user': 'Johnny doe',
|
|
},
|
|
{
|
|
'message': 'password reset request with email "user@example.com"',
|
|
'timestamp': 'Jan. 1, 2020, noon',
|
|
'type': 'user.password.reset.request',
|
|
'user': 'Johnny doe',
|
|
},
|
|
{
|
|
'message': 'password reset failure with email "USER@example.com"',
|
|
'timestamp': 'Jan. 1, 2020, 1 p.m.',
|
|
'type': 'user.password.reset.failure',
|
|
'user': '-',
|
|
},
|
|
{
|
|
'message': 'password reset',
|
|
'timestamp': 'Jan. 1, 2020, 2 p.m.',
|
|
'type': 'user.password.reset',
|
|
'user': 'Johnny doe',
|
|
},
|
|
{
|
|
'message': 'login using SAML',
|
|
'timestamp': 'Jan. 1, 2020, 3 p.m.',
|
|
'type': 'user.login',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'creation of user "Johnny doe"',
|
|
'timestamp': 'Jan. 1, 2020, 4 p.m.',
|
|
'type': 'manager.user.creation',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'edit of user "Johnny doe" (first name)',
|
|
'timestamp': 'Jan. 1, 2020, 5 p.m.',
|
|
'type': 'manager.user.profile.edit',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'email change of user "Johnny doe" for email address "jane@example.com"',
|
|
'timestamp': 'Jan. 1, 2020, 6 p.m.',
|
|
'type': 'manager.user.email.change.request',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'password change of user "Johnny doe"',
|
|
'timestamp': 'Jan. 1, 2020, 7 p.m.',
|
|
'type': 'manager.user.password.change',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'password change of user "Johnny doe" and notification by mail',
|
|
'timestamp': 'Jan. 1, 2020, 8 p.m.',
|
|
'type': 'manager.user.password.change',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'password reset request of "Johnny doe" sent to "user@example.com"',
|
|
'timestamp': 'Jan. 1, 2020, 9 p.m.',
|
|
'type': 'manager.user.password.reset.request',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'mandatory password change at next login set for user "Johnny doe"',
|
|
'timestamp': 'Jan. 1, 2020, 10 p.m.',
|
|
'type': 'manager.user.password.change.force',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'mandatory password change at next login unset for user "Johnny doe"',
|
|
'timestamp': 'Jan. 1, 2020, 11 p.m.',
|
|
'type': 'manager.user.password.change.unforce',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'activation of user "Johnny doe"',
|
|
'timestamp': 'Jan. 2, 2020, midnight',
|
|
'type': 'manager.user.activation',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'deactivation of user "Johnny doe"',
|
|
'timestamp': 'Jan. 2, 2020, 1 a.m.',
|
|
'type': 'manager.user.deactivation',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'deletion of user "Johnny doe"',
|
|
'timestamp': 'Jan. 2, 2020, 2 a.m.',
|
|
'type': 'manager.user.deletion',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'deletion of authorization of single sign on with "service" of ' 'user "Johnny doe"',
|
|
'timestamp': 'Jan. 2, 2020, 3 a.m.',
|
|
'type': 'manager.user.sso.authorization.deletion',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'creation of role "role1"',
|
|
'timestamp': 'Jan. 2, 2020, 4 a.m.',
|
|
'type': 'manager.role.creation',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'edit of role "role1" (name)',
|
|
'timestamp': 'Jan. 2, 2020, 5 a.m.',
|
|
'type': 'manager.role.edit',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'deletion of role "role1"',
|
|
'timestamp': 'Jan. 2, 2020, 6 a.m.',
|
|
'type': 'manager.role.deletion',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'membership grant to user "user (111111)" in role "role1"',
|
|
'timestamp': 'Jan. 2, 2020, 7 a.m.',
|
|
'type': 'manager.role.membership.grant',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'membership removal of user "user (111111)" from role "role1"',
|
|
'timestamp': 'Jan. 2, 2020, 8 a.m.',
|
|
'type': 'manager.role.membership.removal',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'inheritance addition from parent role "role2" to child role ' '"role1"',
|
|
'timestamp': 'Jan. 2, 2020, 9 a.m.',
|
|
'type': 'manager.role.inheritance.addition',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'inheritance removal from parent role "role2" to child role ' '"role1"',
|
|
'timestamp': 'Jan. 2, 2020, 10 a.m.',
|
|
'type': 'manager.role.inheritance.removal',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'addition of role "role2" as administrator of role "role1"',
|
|
'timestamp': 'Jan. 2, 2020, 11 a.m.',
|
|
'type': 'manager.role.administrator.role.addition',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'removal of role "role2" as administrator of role "role1"',
|
|
'timestamp': 'Jan. 2, 2020, noon',
|
|
'type': 'manager.role.administrator.role.removal',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'addition of user "user (111111)" as administrator of role ' '"role1"',
|
|
'timestamp': 'Jan. 2, 2020, 1 p.m.',
|
|
'type': 'manager.role.administrator.user.addition',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'removal of user "user (111111)" as administrator of role "role1"',
|
|
'timestamp': 'Jan. 2, 2020, 2 p.m.',
|
|
'type': 'manager.role.administrator.user.removal',
|
|
'user': 'agent',
|
|
},
|
|
]
|
|
|
|
|
|
def test_user_journal(app, superuser, events):
|
|
response = login(app, user=superuser, path="/manage/")
|
|
user = User.objects.get(username="user")
|
|
|
|
response = app.get("/manage/users/%s/journal/" % user.id)
|
|
content = extract_journal(response)
|
|
|
|
assert content == [
|
|
{
|
|
'message': 'registration using franceconnect',
|
|
'timestamp': 'Jan. 1, 2020, 1 a.m.',
|
|
'type': 'user.registration',
|
|
'user': 'Johnny doe',
|
|
},
|
|
{
|
|
'message': 'logout',
|
|
'timestamp': 'Jan. 1, 2020, 2 a.m.',
|
|
'type': 'user.logout',
|
|
'user': 'Johnny doe',
|
|
},
|
|
{
|
|
'message': 'login using password',
|
|
'timestamp': 'Jan. 1, 2020, 5 a.m.',
|
|
'type': 'user.login',
|
|
'user': 'Johnny doe',
|
|
},
|
|
{
|
|
'message': 'password change',
|
|
'timestamp': 'Jan. 1, 2020, 6 a.m.',
|
|
'type': 'user.password.change',
|
|
'user': 'Johnny doe',
|
|
},
|
|
{
|
|
'message': 'profile edit (first name)',
|
|
'timestamp': 'Jan. 1, 2020, 7 a.m.',
|
|
'type': 'user.profile.edit',
|
|
'user': 'Johnny doe',
|
|
},
|
|
{
|
|
'message': 'authorization of single sign on with "service"',
|
|
'timestamp': 'Jan. 1, 2020, 8 a.m.',
|
|
'type': 'user.service.sso.authorization',
|
|
'user': 'Johnny doe',
|
|
},
|
|
{
|
|
'message': 'service single sign on with "service"',
|
|
'timestamp': 'Jan. 1, 2020, 9 a.m.',
|
|
'type': 'user.service.sso',
|
|
'user': 'Johnny doe',
|
|
},
|
|
{
|
|
'message': 'unauthorization of single sign on with "service"',
|
|
'timestamp': 'Jan. 1, 2020, 10 a.m.',
|
|
'type': 'user.service.sso.unauthorization',
|
|
'user': 'Johnny doe',
|
|
},
|
|
{
|
|
'message': 'user deletion',
|
|
'timestamp': 'Jan. 1, 2020, 11 a.m.',
|
|
'type': 'user.deletion',
|
|
'user': 'Johnny doe',
|
|
},
|
|
{
|
|
'message': 'password reset request with email "user@example.com"',
|
|
'timestamp': 'Jan. 1, 2020, noon',
|
|
'type': 'user.password.reset.request',
|
|
'user': 'Johnny doe',
|
|
},
|
|
{
|
|
'message': 'password reset',
|
|
'timestamp': 'Jan. 1, 2020, 2 p.m.',
|
|
'type': 'user.password.reset',
|
|
'user': 'Johnny doe',
|
|
},
|
|
{
|
|
'message': 'creation by administrator',
|
|
'timestamp': 'Jan. 1, 2020, 4 p.m.',
|
|
'type': 'manager.user.creation',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'edit by administrator (first name)',
|
|
'timestamp': 'Jan. 1, 2020, 5 p.m.',
|
|
'type': 'manager.user.profile.edit',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'email change for email address "jane@example.com" requested by administrator',
|
|
'timestamp': 'Jan. 1, 2020, 6 p.m.',
|
|
'type': 'manager.user.email.change.request',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'password change by administrator',
|
|
'timestamp': 'Jan. 1, 2020, 7 p.m.',
|
|
'type': 'manager.user.password.change',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'password change by administrator and notification by mail',
|
|
'timestamp': 'Jan. 1, 2020, 8 p.m.',
|
|
'type': 'manager.user.password.change',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': "password reset request by administrator sent to " '"user@example.com"',
|
|
'timestamp': 'Jan. 1, 2020, 9 p.m.',
|
|
'type': 'manager.user.password.reset.request',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'mandatory password change at next login set by administrator',
|
|
'timestamp': 'Jan. 1, 2020, 10 p.m.',
|
|
'type': 'manager.user.password.change.force',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'mandatory password change at next login unset by administrator',
|
|
'timestamp': 'Jan. 1, 2020, 11 p.m.',
|
|
'type': 'manager.user.password.change.unforce',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'activation by administrator',
|
|
'timestamp': 'Jan. 2, 2020, midnight',
|
|
'type': 'manager.user.activation',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'deactivation by administrator',
|
|
'timestamp': 'Jan. 2, 2020, 1 a.m.',
|
|
'type': 'manager.user.deactivation',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'deletion by administrator',
|
|
'timestamp': 'Jan. 2, 2020, 2 a.m.',
|
|
'type': 'manager.user.deletion',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'deletion of authorization of single sign on with "service" by ' "administrator",
|
|
'timestamp': 'Jan. 2, 2020, 3 a.m.',
|
|
'type': 'manager.user.sso.authorization.deletion',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'membership grant in role "role1"',
|
|
'timestamp': 'Jan. 2, 2020, 7 a.m.',
|
|
'type': 'manager.role.membership.grant',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'membership removal from role "role1"',
|
|
'timestamp': 'Jan. 2, 2020, 8 a.m.',
|
|
'type': 'manager.role.membership.removal',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'addition as administrator of role "role1"',
|
|
'timestamp': 'Jan. 2, 2020, 1 p.m.',
|
|
'type': 'manager.role.administrator.user.addition',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'removal as administrator of role "role1"',
|
|
'timestamp': 'Jan. 2, 2020, 2 p.m.',
|
|
'type': 'manager.role.administrator.user.removal',
|
|
'user': 'agent',
|
|
},
|
|
]
|
|
|
|
|
|
def test_role_journal(app, superuser, events):
|
|
response = login(app, user=superuser, path="/manage/")
|
|
role1 = Role.objects.get(name="role1")
|
|
role2 = Role.objects.get(name="role2")
|
|
|
|
response = app.get("/manage/roles/%s/journal/" % role1.id)
|
|
content = extract_journal(response)
|
|
|
|
assert content == [
|
|
{
|
|
'message': 'creation',
|
|
'timestamp': 'Jan. 2, 2020, 4 a.m.',
|
|
'type': 'manager.role.creation',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'edit (name)',
|
|
'timestamp': 'Jan. 2, 2020, 5 a.m.',
|
|
'type': 'manager.role.edit',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'deletion',
|
|
'timestamp': 'Jan. 2, 2020, 6 a.m.',
|
|
'type': 'manager.role.deletion',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'membership grant to user "user (111111)"',
|
|
'timestamp': 'Jan. 2, 2020, 7 a.m.',
|
|
'type': 'manager.role.membership.grant',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'membership removal of user "user (111111)"',
|
|
'timestamp': 'Jan. 2, 2020, 8 a.m.',
|
|
'type': 'manager.role.membership.removal',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'inheritance addition from parent role "role2"',
|
|
'timestamp': 'Jan. 2, 2020, 9 a.m.',
|
|
'type': 'manager.role.inheritance.addition',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'inheritance removal from parent role "role2"',
|
|
'timestamp': 'Jan. 2, 2020, 10 a.m.',
|
|
'type': 'manager.role.inheritance.removal',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'addition of role "role2" as administrator',
|
|
'timestamp': 'Jan. 2, 2020, 11 a.m.',
|
|
'type': 'manager.role.administrator.role.addition',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'removal of role "role2" as administrator',
|
|
'timestamp': 'Jan. 2, 2020, noon',
|
|
'type': 'manager.role.administrator.role.removal',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'addition of user "user (111111)" as administrator',
|
|
'timestamp': 'Jan. 2, 2020, 1 p.m.',
|
|
'type': 'manager.role.administrator.user.addition',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'removal of user "user (111111)" as administrator',
|
|
'timestamp': 'Jan. 2, 2020, 2 p.m.',
|
|
'type': 'manager.role.administrator.user.removal',
|
|
'user': 'agent',
|
|
},
|
|
]
|
|
|
|
response = app.get("/manage/roles/%s/journal/" % role2.id)
|
|
content = extract_journal(response)
|
|
|
|
assert content == [
|
|
{
|
|
'message': 'inheritance addition to child role "role1"',
|
|
'timestamp': 'Jan. 2, 2020, 9 a.m.',
|
|
'type': 'manager.role.inheritance.addition',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'inheritance removal to child role "role1"',
|
|
'timestamp': 'Jan. 2, 2020, 10 a.m.',
|
|
'type': 'manager.role.inheritance.removal',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'addition as administrator of role "role1"',
|
|
'timestamp': 'Jan. 2, 2020, 11 a.m.',
|
|
'type': 'manager.role.administrator.role.addition',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'removal as administrator of role "role1"',
|
|
'timestamp': 'Jan. 2, 2020, noon',
|
|
'type': 'manager.role.administrator.role.removal',
|
|
'user': 'agent',
|
|
},
|
|
]
|
|
|
|
|
|
def test_roles_journal(app, superuser, events):
|
|
response = login(app, user=superuser, path='/manage/')
|
|
response = response.click('Role')
|
|
response = response.click('Journal')
|
|
|
|
content = extract_journal(response)
|
|
|
|
assert content == [
|
|
{
|
|
'message': 'creation of role "role1"',
|
|
'timestamp': 'Jan. 2, 2020, 4 a.m.',
|
|
'type': 'manager.role.creation',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'edit of role "role1" (name)',
|
|
'timestamp': 'Jan. 2, 2020, 5 a.m.',
|
|
'type': 'manager.role.edit',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'deletion of role "role1"',
|
|
'timestamp': 'Jan. 2, 2020, 6 a.m.',
|
|
'type': 'manager.role.deletion',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'membership grant to user "user (111111)" in role "role1"',
|
|
'timestamp': 'Jan. 2, 2020, 7 a.m.',
|
|
'type': 'manager.role.membership.grant',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'membership removal of user "user (111111)" from role "role1"',
|
|
'timestamp': 'Jan. 2, 2020, 8 a.m.',
|
|
'type': 'manager.role.membership.removal',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'inheritance addition from parent role "role2" to child role ' '"role1"',
|
|
'timestamp': 'Jan. 2, 2020, 9 a.m.',
|
|
'type': 'manager.role.inheritance.addition',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'inheritance removal from parent role "role2" to child role ' '"role1"',
|
|
'timestamp': 'Jan. 2, 2020, 10 a.m.',
|
|
'type': 'manager.role.inheritance.removal',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'addition of role "role2" as administrator of role "role1"',
|
|
'timestamp': 'Jan. 2, 2020, 11 a.m.',
|
|
'type': 'manager.role.administrator.role.addition',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'removal of role "role2" as administrator of role "role1"',
|
|
'timestamp': 'Jan. 2, 2020, noon',
|
|
'type': 'manager.role.administrator.role.removal',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'addition of user "user (111111)" as administrator of role ' '"role1"',
|
|
'timestamp': 'Jan. 2, 2020, 1 p.m.',
|
|
'type': 'manager.role.administrator.user.addition',
|
|
'user': 'agent',
|
|
},
|
|
{
|
|
'message': 'removal of user "user (111111)" as administrator of role "role1"',
|
|
'timestamp': 'Jan. 2, 2020, 2 p.m.',
|
|
'type': 'manager.role.administrator.user.removal',
|
|
'user': 'agent',
|
|
},
|
|
]
|
|
|
|
|
|
def test_date_navigation(app, superuser, events):
|
|
response = login(app, user=superuser, path="/manage/journal/")
|
|
response = response.click('2020')
|
|
response = response.click('January')
|
|
response = response.click('1')
|
|
response = response.click('January 2020')
|
|
response = response.click('2020')
|
|
response = response.click('All dates')
|
|
|
|
|
|
def test_search(app, superuser, events):
|
|
response = login(app, user=superuser, path="/manage/journal/")
|
|
response.form.set('search', 'event:registration')
|
|
response = response.form.submit()
|
|
assert len(response.pyquery('tbody tr')) == 1
|
|
|
|
response.form.set('search', 'username:agent event:login')
|
|
response = response.form.submit()
|
|
assert len(response.pyquery('tbody tr')) == 1
|
|
assert all(
|
|
'agent' == text_content(node) for node in response.pyquery('tbody tr td.journal-list--user-column')
|
|
)
|
|
|
|
response.form.set('search', 'uuid:%s event:reset' % events['user'].uuid)
|
|
response = response.form.submit()
|
|
assert len(response.pyquery('tbody tr')) == 1
|
|
|
|
response.form.set('search', 'session:1234')
|
|
response = response.form.submit()
|
|
assert len(response.pyquery('tbody tr')) == 9
|
|
assert all(
|
|
text_content(node) == 'Johnny doe'
|
|
for node in response.pyquery('tbody tr td.journal-list--user-column')
|
|
)
|
|
|
|
response.form.set('search', 'email:jane@example.com')
|
|
response = response.form.submit()
|
|
assert (
|
|
text_content(response.pyquery('tbody tr td.journal-list--message-column')[0]).strip()
|
|
== 'email change of user "Johnny doe" for email address "jane@example.com"'
|
|
)
|
|
|
|
response.form.set('search', 'jane@example.com')
|
|
response = response.form.submit()
|
|
assert (
|
|
text_content(response.pyquery('tbody tr td.journal-list--message-column')[0]).strip()
|
|
== 'email change of user "Johnny doe" for email address "jane@example.com"'
|
|
)
|
|
|
|
response.form.set('search', 'johny doe event:login')
|
|
response = response.form.submit()
|
|
pq = response.pyquery
|
|
|
|
assert [
|
|
list(map(text_content, p))
|
|
for p in zip(pq('tbody td.journal-list--user-column'), pq('tbody td.journal-list--message-column'))
|
|
] == [['Johnny doe', 'login using password']]
|