Exemplo n.º 1
0
 def test_render(self):
     # Create test user/group data with changes/deletes.
     with impersonate(self.superuser):
         self.create_test_users_and_groups()
         user = self.users[0]
         user.first_name = "Firsty"
         user.last_name = "The Userman"
         user.save()
         user = self.users[1]
         user.delete()
         group = self.groups[0]
         group.name = "Grouper Gropers"
         group.save()
         group = self.groups[1]
         group.delete()
         site = Site.objects.get_current()
         site.name = "example.org"
         site.domain = "example.org"
         site.save()
     # Verify that each trail is rendered with the appropriate template.
     for trail in Trail.objects.all():
         template_key = (trail.content_type.model_class(), trail.action)
         html_template = {
             (Group, "add"): "trails/auth/group/add.html",
             (Group, "change"): "trails/auth/group/default.html",
             (Group, "delete"): "trails/auth/group/default.html",
             (User, "add"): "trails/auth/default.html",
             (User, "change"): "trails/auth/user/change.html",
             (User, "delete"): "trails/auth/delete.html",
         }.get(template_key, "trails/default.html")
         txt_template = {(Site, "change"): "trails/sites/change.txt"}.get(template_key, "trails/_default.txt")
         with AssertTemplateUsedContext(self, html_template):
             trail.render("html")
         with AssertTemplateUsedContext(self, txt_template):
             trail.render("txt")
Exemplo n.º 2
0
 def test_middleware(self):
     self.create_test_users_and_groups()
     self.assertEqual(get_current_user(), None)
     url = reverse("test_app:index")
     # Test anonymous user.
     response = self.client.get(url)
     self.assertEqual(response.status_code, 200)
     self.assertEqual(response.content, "AnonymousUser")
     self.assertEqual(get_current_user(), None)
     # Test logged in user.
     self.client.login(username=self.users[0].username, password=self.user_passwords[0])
     response = self.client.get(url)
     self.assertEqual(response.status_code, 200)
     self.assertEqual(response.content, unicode(self.users[0]))
     self.assertEqual(get_current_user(), None)
     # Test impersonate context manager.
     with impersonate(self.users[0]):
         self.assertEqual(get_current_user(), self.users[0])
     self.assertEqual(get_current_user(), None)
     # Test impersonate(None) within view requested by logged in user.
     self.client.login(username=self.users[0].username, password=self.user_passwords[0])
     response = self.client.get(url + "?impersonate=1")
     self.assertEqual(response.status_code, 200)
     self.assertEqual(response.content, unicode(None))
     self.assertEqual(get_current_user(), None)
     # Test when request raises exception.
     try:
         response = self.client.get(url + "?raise=1")
     except RuntimeError:
         response = None
     self.assertEqual(response, None)
     self.assertEqual(get_current_user(), None)
Exemplo n.º 3
0
 def get(self, request, format=None):
     if request.query_params.get('raise', ''):
         raise RuntimeError()
     if request.query_params.get('impersonate', ''):
         with impersonate(None):
             current_user = six.text_type(get_current_user())
     else:
         current_user = six.text_type(get_current_user())
     return Response(current_user)
Exemplo n.º 4
0
def index(request):
    if request.GET.get('raise', ''):
        raise RuntimeError()
    if request.GET.get('impersonate', ''):
        with impersonate(None):
            current_user = smart_text(get_current_user())
    else:
        current_user = smart_text(get_current_user())
    return HttpResponse(current_user, content_type='text/plain')
Exemplo n.º 5
0
 def test_admin(self):
     app_label = Trail._meta.app_label
     model_name = getattr(Trail._meta, "model_name", None) or getattr(Trail._meta, "module_name", None)
     self.assertTrue(model_name)
     self.client.login(username=self.superuser.username, password=self.superuser_password)
     with impersonate(self.superuser):
         self.create_test_users_and_groups()
     with impersonate(self.users[0]):
         self.create_test_users_and_groups(prefix="extra")
     with impersonate(self.superuser):
         self.users[0].delete()
         self.users.pop(0)
         self.user_passwords.pop(0)
     self.assertTrue(Trail.objects.count())
     # Change list view.
     changelist_url = reverse("admin:%s_%s_changelist" % (app_label, model_name))
     response = self.client.get(changelist_url)
     self.assertEquals(response.status_code, 200)
     for trail in Trail.objects.all():
         change_url = reverse("admin:%s_%s_change" % (app_label, model_name), args=(trail.pk,))
         change_url_found = False
         soup = BeautifulSoup(response.content)
         for atag in soup.findAll("a", href=True):
             target_url = urlparse.urljoin(changelist_url, atag["href"])
             if target_url == change_url:
                 change_url_found = True
                 break
         self.assertTrue(change_url_found)
     # Change view (should have no editable fields).
     response = self.client.get(change_url)
     self.assertEquals(response.status_code, 200)
     soup = BeautifulSoup(response.content)
     for fs in soup.findAll("fieldset"):
         self.assertFalse(fs.findAll("input"))
         self.assertFalse(fs.findAll("select"))
         self.assertFalse(fs.findAll("textarea"))
     # Delete view via GET, then POST.
     delete_url = reverse("admin:%s_%s_delete" % (app_label, model_name), args=(trail.pk,))
     response = self.client.get(delete_url)
     self.assertEquals(response.status_code, 200)
     # Add view should raise a 403.
     add_url = reverse("admin:%s_%s_add" % (app_label, model_name))
     response = self.client.get(add_url)
     self.assertEquals(response.status_code, 403)
Exemplo n.º 6
0
 def test_manager_for_models(self):
     with impersonate(self.superuser):
         self.create_test_users_and_groups()
     # All normal users.
     instances = self.users
     trails = Trail.objects.for_models(*instances)
     self.assertTrue(trails.count())
     for trail in trails:
         self.assertTrue(trail.content_object in instances)
     # All normal groups.
     instances = self.groups
     trails = Trail.objects.for_models(*instances)
     self.assertTrue(trails.count())
     for trail in trails:
         self.assertTrue(trail.content_object in instances)
     # Mix of user and group.
     instances = [self.users[0], self.groups[0]]
     trails = Trail.objects.for_models(*instances)
     self.assertTrue(trails.count())
     for trail in trails:
         self.assertTrue(trail.content_object in instances)
     # Multiples of one type, mixed with another type.
     instances = self.users + [self.groups[0]]
     trails = Trail.objects.for_models(*instances)
     self.assertTrue(trails.count())
     for trail in trails:
         self.assertTrue(trail.content_object in instances)
     # Passing None as an instance should work, but return no trails.
     instances = [None]
     trails = Trail.objects.for_models(*instances)
     self.assertFalse(trails.count())
     # Passing a single Queryset instead of a list.
     instances = Group.objects.all()
     trails = Trail.objects.for_models(*instances)
     self.assertTrue(trails.count())
     for trail in trails:
         self.assertTrue(trail.content_object in instances)
     # Passing a list of Querysets.
     instances = [Group.objects.all(), User.objects.all()]
     trails = Trail.objects.for_models(*instances)
     self.assertTrue(trails.count())
     for trail in trails:
         self.assertTrue(trail.content_object in instances[0] or trail.content_object in instances[1])
Exemplo n.º 7
0
 def test_middleware(self):
     # For test coverage.
     import crum
     imp.reload(crum)
     # Test anonymous user.
     self.assertEqual(get_current_user(), None)
     url = reverse('test_app:index')
     response = self.client.get(url)
     response_content = response.content.decode('utf-8')
     self.assertEqual(response.status_code, 200)
     self.assertEqual(response_content, 'AnonymousUser')
     self.assertEqual(get_current_user(), None)
     # Test logged in user.
     self.client.login(username=self.user.username,
                       password=self.user_password)
     response = self.client.get(url)
     response_content = response.content.decode('utf-8')
     self.assertEqual(response.status_code, 200)
     self.assertEqual(response_content, six.text_type(self.user))
     self.assertEqual(get_current_user(), None)
     # Test impersonate context manager.
     with impersonate(self.user):
         self.assertEqual(get_current_user(), self.user)
     self.assertEqual(get_current_user(), None)
     # Test impersonate(None) within view requested by logged in user.
     self.client.login(username=self.user.username,
                       password=self.user_password)
     response = self.client.get(url + '?impersonate=1')
     response_content = response.content.decode('utf-8')
     self.assertEqual(response.status_code, 200)
     self.assertEqual(response_content, six.text_type(None))
     self.assertEqual(get_current_user(), None)
     # Test when request raises exception.
     try:
         response = self.client.get(url + '?raise=1')
     except RuntimeError:
         response = None
     self.assertEqual(response, None)
     self.assertEqual(get_current_user(), None)
Exemplo n.º 8
0
def test_job_relaunch_permission_denied_response_other_user(
        get, post, inventory, project, alice, bob, survey_spec_factory):
    '''
    Asserts custom permission denied message corresponding to
    awx/main/tests/functional/test_rbac_job.py::TestJobRelaunchAccess::test_other_user_prompts
    '''
    jt = JobTemplate.objects.create(name='testjt',
                                    inventory=inventory,
                                    project=project,
                                    ask_credential_on_launch=True,
                                    ask_variables_on_launch=True,
                                    survey_spec=survey_spec_factory([{
                                        'variable':
                                        'secret_key',
                                        'default':
                                        '6kQngg3h8lgiSTvIEb21',
                                        'type':
                                        'password'
                                    }]),
                                    survey_enabled=True)
    jt.execute_role.members.add(alice, bob)
    with impersonate(bob):
        job = jt.create_unified_job(extra_vars={
            'job_var': 'foo2',
            'secret_key': 'sk4t3Rb01'
        })

    # User capability is shown for this
    r = get(job.get_absolute_url(), alice, expect=200)
    assert r.data['summary_fields']['user_capabilities']['start']

    # Job has prompted data, launch denied w/ message
    r = post(url=reverse('api:job_relaunch', kwargs={'pk': job.pk}),
             data={},
             user=alice,
             expect=403)
    assert 'Job was launched with secret prompts provided by another user' in r.data[
        'detail']
Exemplo n.º 9
0
def test_activity_stream_deleted_actor(alice, bob):
    alice.first_name = 'Alice'
    alice.last_name = 'Doe'
    alice.save()
    with impersonate(alice):
        o = Organization.objects.create(name='test organization')
    entry = o.activitystream_set.get(operation='create')
    assert entry.actor == alice

    alice.delete()
    entry = o.activitystream_set.get(operation='create')
    assert entry.actor is None
    deleted = entry.deleted_actor
    assert deleted['username'] == 'alice'
    assert deleted['first_name'] == 'Alice'
    assert deleted['last_name'] == 'Doe'

    entry.actor = bob
    entry.save(update_fields=['actor'])
    deleted = entry.deleted_actor

    entry = ActivityStream.objects.get(id=entry.pk)
    assert entry.deleted_actor['username'] == 'bob'
Exemplo n.º 10
0
def test_job_relaunch_permission_denied_response(post, get, inventory, project,
                                                 credential, net_credential,
                                                 machine_credential):
    jt = JobTemplate.objects.create(name='testjt',
                                    inventory=inventory,
                                    project=project)
    jt.credentials.add(machine_credential)
    jt_user = User.objects.create(username='******')
    jt.execute_role.members.add(jt_user)
    with impersonate(jt_user):
        job = jt.create_unified_job()

    # User capability is shown for this
    r = get(job.get_absolute_url(), jt_user, expect=200)
    assert r.data['summary_fields']['user_capabilities']['start']

    # Job has prompted extra_credential, launch denied w/ message
    job.launch_config.credentials.add(net_credential)
    r = post(reverse('api:job_relaunch', kwargs={'pk': job.pk}), {},
             jt_user,
             expect=403)
    assert 'launched with prompted fields' in r.data['detail']
    assert 'do not have permission' in r.data['detail']
Exemplo n.º 11
0
    def test_update_old_mitigated_with_custom_edit(self, mock_can_edit,
                                                   mock_tz):
        mock_tz.return_value = frozen_datetime

        custom_mitigated = datetime.datetime.now()

        with impersonate(self.user_1):
            test = Test.objects.last()
            finding = Finding(test=test,
                              is_mitigated=True,
                              active=False,
                              mitigated=frozen_datetime,
                              mitigated_by=self.user_1)
            finding.save()
            finding.is_mitigated = True
            finding.active = False
            finding.mitigated = custom_mitigated
            finding.mitigated_by = self.user_2
            finding.save()

            self.assertEqual(self.get_status_fields(finding),
                             (False, True, False, False, True,
                              custom_mitigated, self.user_2, frozen_datetime))
Exemplo n.º 12
0
def test_audit_log_read_actor_role(user, role, caplog, staff_user, anon_user):
    youth_profile = YouthProfileFactory()
    if role == "SYSTEM":
        user = None
    elif role == "OWNER":
        user = youth_profile.user
    elif role == "ADMIN":
        user = staff_user
    elif role == "ANONYMOUS":
        user = anon_user
    caplog.clear()

    with impersonate(user):
        YouthProfile.objects.first()

    logs = get_log_records(caplog)
    assert len(logs) == 1
    log_message = json.loads(logs[0])
    assert log_message["audit_event"]["actor"]["role"] == role
    if user:
        assert log_message["audit_event"]["actor"]["user_id"] == (str(
            user.uuid) if user != anon_user else None)
        assert log_message["audit_event"]["actor"][
            "user_name"] == user.username
Exemplo n.º 13
0
    def test_update_old_mitigated_with_missing_data(self, mock_can_edit,
                                                    mock_tz):
        mock_tz.return_value = frozen_datetime

        custom_mitigated = datetime.datetime.now()

        with impersonate(self.user_1):
            test = Test.objects.last()
            finding = Finding(test=test,
                              is_mitigated=True,
                              active=False,
                              mitigated=custom_mitigated,
                              mitigated_by=self.user_2)
            finding.save()
            finding.is_mitigated = True
            finding.active = False
            # trying to remove mitigated fields will trigger the signal to set them to now/current user
            finding.mitigated = None
            finding.mitigated_by = None
            finding.save()

            self.assertEqual(self.get_status_fields(finding),
                             (False, True, False, False, True, frozen_datetime,
                              self.user_1, frozen_datetime))
Exemplo n.º 14
0
def delete_inventory(inventory_id, user_id, retries=5):
    # Delete inventory as user
    if user_id is None:
        user = None
    else:
        try:
            user = User.objects.get(id=user_id)
        except Exception:
            user = None
    with ignore_inventory_computed_fields(), ignore_inventory_group_removal(
    ), impersonate(user):
        try:
            i = Inventory.objects.get(id=inventory_id)
            for host in i.hosts.iterator():
                host.job_events_as_primary_host.update(host=None)
            i.delete()
            emit_channel_notification(
                'inventories-status_changed', {
                    'group_name': 'inventories',
                    'inventory_id': inventory_id,
                    'status': 'deleted'
                })
            logger.debug('Deleted inventory {} as user {}.'.format(
                inventory_id, user_id))
        except Inventory.DoesNotExist:
            logger.exception(
                "Delete Inventory failed due to missing inventory: " +
                str(inventory_id))
            return
        except DatabaseError:
            logger.exception(
                'Database error deleting inventory {}, but will retry.'.format(
                    inventory_id))
            if retries > 0:
                time.sleep(10)
                delete_inventory(inventory_id, user_id, retries=retries - 1)
Exemplo n.º 15
0
    def handle(self, *args, **kwargs):
        # Sanity check: Is there already an organization in the system?
        if Setting.objects.count():
            print('System is already configured, exiting.')
            print('(changed: False)')
            return

        User = get_user_model()
        User.objects.create_superuser('*****@*****.**', 'adminadmin')

        call_command("loaddata", "settings")

        # Create a default organization as the first superuser found.
        try:
            superuser = User.objects.filter(
                is_superuser=True).order_by('pk')[0]
        except IndexError:
            superuser = None
        with impersonate(superuser):
            r = Repository.objects.create(name='Demo Repository',
                                          path='/tmp/repository',
                                          repository_key='0123456789abcdef',
                                          enabled=False)
            s = Schedule.objects.create(name='Demo Schedule',
                                        crontab='0 5 * * MON *',
                                        enabled=False)
            c = Client.objects.create(hostname='localhost', enabled=False)
            p = Policy(name='Demo Policy',
                       mode_pull=False,
                       enabled=False,
                       repository=r,
                       schedule=s)
            p.save()
            p.clients.add(c)
        print('Demo Client, Repository, Schedule and Policy added.')
        print('(changed: True)')
 def create_engagement_epic(self, engagement):
     with impersonate(self.testuser):
         return jira_helper.add_epic(engagement)
Exemplo n.º 17
0
    def handle(self, *args, **kwargs):
        changed = False

        # Create a default organization as the first superuser found.
        try:
            superuser = User.objects.filter(
                is_superuser=True).order_by('pk')[0]
        except IndexError:
            superuser = None
        with impersonate(superuser):
            with disable_computed_fields():
                if not Organization.objects.exists():
                    o, _ = Organization.objects.get_or_create(name='Default')

                    # Avoid calling directly the get_or_create() to bypass project update
                    p = Project.objects.filter(name='Demo Project',
                                               scm_type='git').first()
                    if not p:
                        p = Project(
                            name='Demo Project',
                            scm_type='git',
                            scm_url=
                            'https://github.com/ansible/ansible-tower-samples',
                            scm_update_cache_timeout=0,
                            status='successful',
                            scm_revision=
                            '347e44fea036c94d5f60e544de006453ee5c71ad',
                            playbook_files=['hello_world.yml'],
                        )

                    p.organization = o
                    p.save(skip_update=True)

                    ssh_type = CredentialType.objects.filter(
                        namespace='ssh').first()
                    c, _ = Credential.objects.get_or_create(
                        credential_type=ssh_type,
                        name='Demo Credential',
                        inputs={'username': superuser.username},
                        created_by=superuser)

                    c.admin_role.members.add(superuser)

                    public_galaxy_credential, _ = Credential.objects.get_or_create(
                        name='Ansible Galaxy',
                        managed=True,
                        credential_type=CredentialType.objects.get(
                            kind='galaxy'),
                        inputs={'url': 'https://galaxy.ansible.com/'},
                    )
                    o.galaxy_credentials.add(public_galaxy_credential)

                    i, _ = Inventory.objects.get_or_create(
                        name='Demo Inventory',
                        organization=o,
                        created_by=superuser)

                    Host.objects.get_or_create(
                        name='localhost',
                        inventory=i,
                        variables=
                        "ansible_connection: local\nansible_python_interpreter: '{{ ansible_playbook_python }}'",
                        created_by=superuser,
                    )

                    jt = JobTemplate.objects.filter(
                        name='Demo Job Template').first()
                    if jt:
                        jt.project = p
                        jt.inventory = i
                        jt.playbook = 'hello_world.yml'
                        jt.save()
                    else:
                        jt, _ = JobTemplate.objects.get_or_create(
                            name='Demo Job Template',
                            playbook='hello_world.yml',
                            project=p,
                            inventory=i)
                    jt.credentials.add(c)

                    print('Default organization added.')
                    print(
                        'Demo Credential, Inventory, and Job Template added.')
                    changed = True

        if changed:
            print('(changed: True)')
        else:
            print('(changed: False)')
Exemplo n.º 18
0
    def handle(self, *args, **kwargs):
        changed = False

        # Create a default organization as the first superuser found.
        try:
            superuser = User.objects.filter(
                is_superuser=True).order_by('pk')[0]
        except IndexError:
            superuser = None
        with impersonate(superuser):
            with disable_computed_fields():
                if not Organization.objects.exists():
                    o = Organization.objects.create(name='Default')

                    p = Project(
                        name='Demo Project',
                        scm_type='git',
                        scm_url=
                        'https://github.com/ansible/ansible-tower-samples',
                        scm_update_on_launch=True,
                        scm_update_cache_timeout=0,
                        organization=o)
                    p.save(skip_update=True)

                    ssh_type = CredentialType.objects.filter(
                        namespace='ssh').first()
                    c = Credential.objects.create(
                        credential_type=ssh_type,
                        name='Demo Credential',
                        inputs={'username': superuser.username},
                        created_by=superuser)

                    c.admin_role.members.add(superuser)

                    public_galaxy_credential = Credential(
                        name='Ansible Galaxy',
                        managed_by_tower=True,
                        credential_type=CredentialType.objects.get(
                            kind='galaxy'),
                        inputs={'url': 'https://galaxy.ansible.com/'})
                    public_galaxy_credential.save()
                    o.galaxy_credentials.add(public_galaxy_credential)

                    i = Inventory.objects.create(name='Demo Inventory',
                                                 organization=o,
                                                 created_by=superuser)

                    Host.objects.create(
                        name='localhost',
                        inventory=i,
                        variables=
                        "ansible_connection: local\nansible_python_interpreter: '{{ ansible_playbook_python }}'",
                        created_by=superuser)

                    jt = JobTemplate.objects.create(name='Demo Job Template',
                                                    playbook='hello_world.yml',
                                                    project=p,
                                                    inventory=i)
                    jt.credentials.add(c)

                    print('Default organization added.')
                    print(
                        'Demo Credential, Inventory, and Job Template added.')
                    changed = True

                default_ee = settings.AWX_EXECUTION_ENVIRONMENT_DEFAULT_IMAGE
                ee, created = ExecutionEnvironment.objects.get_or_create(
                    name='Default EE',
                    defaults={
                        'image': default_ee,
                        'managed_by_tower': True
                    })

                if created:
                    changed = True
                    print('Default Execution Environment registered.')

        if changed:
            print('(changed: True)')
        else:
            print('(changed: False)')
Exemplo n.º 19
0
 def handle(self, *args, **options):
     # use admin user to make sure we have access to its properties i.e. to determine wants_async
     with impersonate(Dojo_User.objects.get(username='******')):
         ra_helper.expiration_handler()
Exemplo n.º 20
0
def test_activity_stream_actor(admin_user):
    with impersonate(admin_user):
        o = Organization.objects.create(name='test organization')
    entry = o.activitystream_set.get(operation='create')
    assert entry.actor == admin_user
Exemplo n.º 21
0
def can_receive_discount(user, course, discount_expiration_date=None):
    """
    Check all the business logic about whether this combination of user and course
    can receive a discount.
    """
    # Always disable discounts until we are ready to enable this feature
    with impersonate(user):
        if not DISCOUNT_APPLICABILITY_FLAG.is_enabled():
            return False

    # TODO: Add additional conditions to return False here

    # Check if discount has expired
    if not discount_expiration_date:
        discount_expiration_date = get_discount_expiration_date(user, course)

    if discount_expiration_date is None:
        return False

    if discount_expiration_date < timezone.now():
        return False

    # Course end date needs to be in the future
    if course.has_ended():
        return False

    # Course needs to have a non-expired verified mode
    modes_dict = CourseMode.modes_for_course_dict(course=course,
                                                  include_expired=False)
    verified_mode = modes_dict.get('verified', None)
    if not verified_mode:
        return False

    # Site, Partner, Course or Course Run not excluded from lms-controlled discounts
    if DiscountRestrictionConfig.disabled_for_course_stacked_config(course):
        return False

    if user.is_anonymous:
        return False

    # Don't allow users who have enrolled in any courses in non-upsellable
    # modes
    if CourseEnrollment.objects.filter(user=user).exclude(
            mode__in=CourseMode.UPSELL_TO_VERIFIED_MODES).exists():
        return False

    # Don't allow any users who have entitlements (past or present)
    if CourseEntitlement.objects.filter(user=user).exists():
        return False

    # We can't import this at Django load time within the openedx tests settings context
    from openedx.features.enterprise_support.utils import is_enterprise_learner
    # Don't give discount to enterprise users
    if is_enterprise_learner(user):
        return False

    # Excute holdback
    if _is_in_holdback(user):
        return False

    return True
Exemplo n.º 22
0
    def handle(self, *args, **options):
        logger.info("Bootstrapping database with mock data...")

        # add Users (which then adds actors)
        self.mock(model=User, factory=UserFactory, count=100, bulk=False)

        # add admin
        admin = User.objects.create(username="******",
                                    is_staff=True,
                                    is_superuser=True)
        admin.set_password("admin")
        admin.save()

        # create all the scaffolding as the admin user
        with impersonate(admin):
            ####################
            # add teams
            carteam = Team.objects.create(
                name="Car Nerds",
                description="A group of people who drive and review cars",
                founder=Actor.objects.all().order_by("?").first(),
            )
            foodteam = Team.objects.create(
                name="Foodies",
                description=
                "Hungry people with opinions on food and places that serve food",
                founder=Actor.objects.all().order_by("?").first(),
            )
            Team.objects.create(
                name="Music Lovers",
                description=
                "Concert-going music lovers. Reviews of venues and concerts.",
                founder=Actor.objects.all().order_by("?").first(),
            )

            ###################
            # add team members for all teams
            for team in Team.objects.all():
                # add site admin as admin team member of all teams
                Membership.objects.create(team=team,
                                          actor=admin.actor,
                                          admin=True)

            # add all remaining Actors with no team to a random team
            for actor in Actor.objects.filter(memberships__isnull=True):
                Membership.objects.create(
                    team=Team.objects.all().order_by("?").first(), actor=actor)

            # add categories for carteam
            makecat = Category.objects.create(team=carteam,
                                              name="Car Makers",
                                              description="A car maker.")
            carcat = Category.objects.create(team=carteam,
                                             name="Cars",
                                             description="A car.")

            # add Contexts for carteam
            classic_car_context = Context.objects.create(
                team=carteam,
                name="Classic Car Meetup, Carville, 2018",
                description=
                "Use this context for all reviews from the 2018 meetup in Carville.",
            )
            japanese_car_context = Context.objects.create(
                team=carteam,
                name="Jap Car Fest 2018",
                description=
                'Use this context for all reviews from the 2018 "Jap Car Fest"',
            )

            # add attributes for Maker category
            Fact.objects.create(
                name="Country",
                datatype=Fact.TYPE_TEXT,
                category=makecat,
                required=True,
                slug=makecat.create_fact_slug("Country"),
                description="The country this car maker is from",
            )

            # add django-eav2 Facts for the "Car" Category
            Fact.objects.create(
                name="Make",
                datatype=Fact.TYPE_OBJECT,
                category=carcat,
                required=True,
                slug=carcat.create_fact_slug("Make"),
                description="The make of this car",
                object_category=makecat,
            )
            Fact.objects.create(
                name="Colour",
                datatype=Fact.TYPE_TEXT,
                category=carcat,
                required=True,
                slug=carcat.create_fact_slug("Colour"),
                description="The colour of this car",
            )
            Fact.objects.create(
                name="BHP",
                datatype=Fact.TYPE_INT,
                category=carcat,
                required=True,
                slug=carcat.create_fact_slug("BHP"),
                description="The BHP of this car",
            )
            # add Ratings for "Car" category
            Rating.objects.create(
                name="Looks",
                category=carcat,
                max_rating=10,
                description="Rate the looks of this car, 10 is best.",
            )
            Rating.objects.create(
                name="Handling",
                category=carcat,
                max_rating=10,
                description="How well the car handles. 10 is best.",
            )

            # add car makers
            ford = makecat.items.create(name="Ford", eav__country="US")
            bmw = makecat.items.create(name="BMW", eav__country="DE")
            peugeot = makecat.items.create(name="Peugeot", eav__country="FR")

            # add cars
            carcat.items.create(
                name="Escort RS Cosworth",
                eav__make=ford,
                eav__colour="black",
                eav__bhp="170",
            )
            carcat.items.create(name="Focus",
                                eav__make=ford,
                                eav__colour="blue",
                                eav__bhp="95")
            carcat.items.create(name="520i E34",
                                eav__make=bmw,
                                eav__colour="purple",
                                eav__bhp="200")
            carcat.items.create(name="M3",
                                eav__make=bmw,
                                eav__colour="white",
                                eav__bhp="280")
            carcat.items.create(
                name="406 Estate",
                eav__make=peugeot,
                eav__colour="white",
                eav__bhp="130",
            )

        # add reviews for cars
        for car in carcat.items.all():
            # not everyone votes :(
            votercount = random.randint(1, carcat.team.members.count())
            for actor in carcat.team.members.all()[0:votercount]:
                with impersonate(actor.user):
                    review = Review.objects.create(
                        actor=actor,
                        item=car,
                        headline=factory.Faker("sentence").generate(),
                        body=factory.Faker("text").generate()
                        if random.choice([True, False]) else None,
                        context=random.choice(
                            [classic_car_context, japanese_car_context]),
                    )
                    logger.debug("created review %s" % review)
                    # add votes to this review
                    for rating in carcat.ratings.all():
                        # 50/50 chance if this actor voted for this Rating
                        if random.choice([True, False]):
                            # 50/50 chance if this actor left a comment for this Vote
                            if random.choice([True, False]):
                                comment = factory.Faker("sentence").generate()
                            else:
                                comment = None

                            # create the Vote
                            vote = Vote.objects.create(
                                review=review,
                                rating=rating,
                                vote=random.randint(1, rating.max_rating),
                                comment=comment,
                            )
                            logger.debug("created vote %s" % vote)

        # add categories for foodteam
        restaurant = Category.objects.create(
            team=foodteam,
            name="Restaurant",
            description="A place where food is served")
        dish = Category.objects.create(team=foodteam,
                                       name="Dish",
                                       description="Some food")

        # add attributes for "Restaurant" category
        Fact.objects.create(
            name="Location",
            datatype=Fact.TYPE_POINT,
            required=True,
            category=restaurant,
            slug=restaurant.create_fact_slug("Location"),
            description="The location (coordinates) of this restaurant",
        )
        Fact.objects.create(
            name="Description",
            datatype=Fact.TYPE_TEXT,
            required=True,
            category=restaurant,
            slug=restaurant.create_fact_slug("Description"),
            description=
            "A short description of this restaurant. Markdown should be supported.",
        )

        # add attributes for "Dish" category
        Fact.objects.create(
            name="Price",
            datatype=Fact.TYPE_INT,
            required=True,
            category=dish,
            slug=restaurant.create_fact_slug("Price"),
            description="The price in EUR of this dish",
        )
        Fact.objects.create(
            name="Date Eaten",
            datatype=Fact.TYPE_DATE,
            required=True,
            category=dish,
            slug=restaurant.create_fact_slug("Date Eaten"),
            description="The date and time this Dish was eaten",
        )

        # TODO: add restaurants and dishes

        logger.info(
            "Done. A superuser was added, username admin password admin. Django admin access and member of all teams. Enjoy!"
        )