Skip to content

Commit

Permalink
Add only school users to game (#622)
Browse files Browse the repository at this point in the history
* Reduced no. of students being added to game

* Changed get_users again

* Refactored get_users function

* Imported Models from portal

* Preview user required

* Is preview user permission

* Remove debugging statements

* Remove redundant return statement

* install portal for tests and aimmo_runner as well

* install sass for portal

* Add user profile to tests

* add test_settings

* Wrote a default preview_user decorator

* Testing import  get_users_for_new_game

* Added prints for debugging

* Debugging

* More debugging

* Stuff

* Temporarily breaking new game for testing

* Changed version of aimmo

* testing

* Testing

* Testing aimmo version again

* Temporarily commented out preview user decorator for testing

* Added decorator back

* More changes

* Testing build

* Testing again

* ChANGES

* More changes

* STill not working

* rm portal refs

* trying add projects

* Still testing

* Attempt at fixing logging

* It's gonna work!

* Removed prints

* Removed integration-tests app from all_tests

* Removed more prints

* Removed prints

* Removed another print

* Fixed something

* More fixes

* Refactored to follow pep8

* Refactored stuff

* More refactoring

* Refactored

* Refactors

* Renamed decorator to preview_user_required

* Added comments for both functions in app_settings that import things from portal
  • Loading branch information
riaJha97 authored and CelineBoudier committed Jun 19, 2018
1 parent b957777 commit 3cf2214
Show file tree
Hide file tree
Showing 15 changed files with 96 additions and 45 deletions.
2 changes: 2 additions & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,8 @@ jobs:
- minikube update-context
# Wait for Kubernetes to be up and ready.
- JSONPATH='{range .items[*]}{@.metadata.name}:{range @.status.conditions[*]}{@.type}={@.status};{end}{end}'; until kubectl get nodes -o jsonpath="$JSONPATH" 2>&1 | grep -q "Ready=True"; do sleep 1; done
before_install:
- gem install sass --version 3.3.4
install:
- pip install .
- pip install coveralls
Expand Down
2 changes: 0 additions & 2 deletions aimmo_runner/minikube.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@
import kubernetes
import os
import re
import socket
import yaml
import platform
from shell_api import (run_command, create_test_bin, BASE_DIR)
from aimmo_runner.kubernetes_setup import KubernetesBaseSetup
Expand Down
17 changes: 12 additions & 5 deletions aimmo_runner/runner.py
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import django
import logging
import os
import sys
Expand Down Expand Up @@ -42,27 +43,33 @@ def install_kubernetes_dependencies(capture_output):

os.environ['AIMMO_MODE'] = 'minikube'


def setup_minikube(capture_output):
install_kubernetes_dependencies(capture_output)
# Import minikube here, so we can install the deps first
from aimmo_runner.minikube import MinikubeRunner
MinikubeRunner().start()


def setup_vagrant(capture_output):
install_kubernetes_dependencies(capture_output)
# Import vagrant here, so we can install the deps first
from aimmo_runner.vagrant import VagrantRunner
VagrantRunner().start()


def run(use_minikube, use_vagrant=False, server_wait=True, capture_output=False):
def run(use_minikube, use_vagrant=False, server_wait=True, capture_output=False, test_env=False):
logging.basicConfig()
sys.path.append(os.path.join(ROOT_DIR_LOCATION, 'example_project'))
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example_project.settings")
if test_env:
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "test_settings")
else:
sys.path.append(os.path.join(ROOT_DIR_LOCATION, 'example_project'))
os.environ.setdefault("DJANGO_SETTINGS_MODULE", "example_project.settings")

run_command(['pip', 'install', '-e', ROOT_DIR_LOCATION], capture_output=capture_output)
run_command(['python', _MANAGE_PY, 'migrate', '--noinput'], capture_output=capture_output)
run_command(['python', _MANAGE_PY, 'collectstatic', '--noinput'], capture_output=capture_output)
if not test_env:
run_command(['python', _MANAGE_PY, 'migrate', '--noinput'], capture_output=capture_output)
run_command(['python', _MANAGE_PY, 'collectstatic', '--noinput'], capture_output=capture_output)

create_superuser_if_missing(username='admin', password='admin')

Expand Down
3 changes: 1 addition & 2 deletions all_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,7 @@
from aimmo_runner import runner

BASE_DIR = os.path.abspath(os.path.dirname(__file__))
APPS = ('', 'aimmo-game/', 'aimmo-game-worker/', 'aimmo-game-creator/',
'integration-tests/')
APPS = ('', 'aimmo-game/', 'aimmo-game-worker/', 'aimmo-game-creator/',)


def print_help():
Expand Down
File renamed without changes.
File renamed without changes.
Empty file.
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,6 @@ def is_server_healthy(url):

attempts += 1
time.sleep(1)

return False


Expand Down
Original file line number Diff line number Diff line change
@@ -1,19 +1,19 @@
import os
import signal
import time
import subprocess
import logging
import unittest

from django.test.client import Client
import psutil
from aimmo_runner import runner
from connection_api import (create_session, send_get_request, send_post_request,
obtain_csrftoken, delete_old_database, is_server_healthy)

from django.core.urlresolvers import reverse
logging.basicConfig(level=logging.WARNING)


class TestIntegration(unittest.TestCase):
def __init__(self, *args, **kwargs):
super(TestIntegration, self).__init__(*args, **kwargs)
self.processes = []

def tearDown(self):
"""
Expand All @@ -40,30 +40,21 @@ def test_superuser_authentication(self):
Server gets killed at the end of the test.
"""
url = 'http://localhost:8000/players/accounts/login/'

url_string = 'aimmo/login'
delete_old_database()

os.chdir(runner.ROOT_DIR_LOCATION)
self.processes = runner.run(use_minikube=False, server_wait=False, capture_output=True)

self.assertTrue(is_server_healthy(url))

logging.debug("Creating session...")
session = create_session()

send_get_request(session, url)

logging.debug("Obtaining CSRF Token...")
csrftoken = obtain_csrftoken(session)
self.processes = runner.run(use_minikube=False, server_wait=False, capture_output=True, test_env=True)
client = Client()
response = client.get(reverse(url_string))
self.assertEquals(response.status_code, 200)
csrf_token = response.context['csrf_token']

login_info = {
'username': 'admin',
'password': 'admin',
'csrfmiddlewaretoken': csrftoken,
'csrftoken': csrf_token,
}

logging.debug("Sending post response...")

response = send_post_request(session, url, login_info)
self.assertEquals(response.status_code, 200)
response = client.post(reverse(url_string), login_info)
self.assertEquals(response.status_code, 302)
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ def setUp(self):
api instance from the kubernetes client.
"""
delete_old_database()
self.processes = runner.run(use_minikube=True, server_wait=False, capture_output=True)
self.processes = runner.run(use_minikube=True, server_wait=False, capture_output=True, test_env=True)
time.sleep(120)
kubernetes.config.load_kube_config(context='minikube')
self.api_instance = kubernetes.client.CoreV1Api()
Expand Down Expand Up @@ -150,4 +150,4 @@ def test_remove_old_ingress_paths_on_startup(self):
cluster is then stopped and started again with a fresh database. When this happens,
we check that the ingress paths are returned to default again.
"""
pass
pass
34 changes: 34 additions & 0 deletions players/app_settings.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,42 @@
from django.conf import settings
from django.utils.module_loading import import_string
from permissions import default_preview_user
from django.contrib.auth.models import User

#: URL function for locating the game server, takes one parameter `game`
GAME_SERVER_URL_FUNCTION = getattr(settings, 'AIMMO_GAME_SERVER_URL_FUNCTION', None)
GAME_SERVER_PORT_FUNCTION = getattr(settings, 'AIMMO_GAME_SERVER_PORT_FUNCTION', None)
GAME_SERVER_SSL_FLAG = getattr(settings, 'AIMMO_GAME_SERVER_SSL_FLAG', False)
PREVIEW_USER_AIMMO_DECORATOR = getattr(settings, 'PREVIEW_USER_AIMMO_DECORATOR', None)
USERS_FOR_NEW_AIMMO_GAME = getattr(settings, 'USERS_FOR_NEW_AIMMO_GAME', None)


def get_aimmo_preview_user_decorator():
"""
This function is used to import a decorator from portal, which
checks whether the logged in user is a preview user.
:return: A function decorator
"""
if PREVIEW_USER_AIMMO_DECORATOR:
func = import_string(PREVIEW_USER_AIMMO_DECORATOR)
return func
return default_preview_user


def get_users_for_new_game(request):
"""
Imports and calls a function defined in portal, that decides
which users should be added to the newly created game.
:param request:
:return: List of User objects
"""
if USERS_FOR_NEW_AIMMO_GAME:
func = import_string(USERS_FOR_NEW_AIMMO_GAME)
return func(request)
return User.objects.all()


preview_user_required = get_aimmo_preview_user_decorator()

MAX_LEVEL = 1
8 changes: 8 additions & 0 deletions players/permissions.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
from functools import wraps


def default_preview_user(view_func):
@wraps(view_func)
def wrapped(request, *args, **kwargs):
return view_func(request, *args, **kwargs)
return wrapped
13 changes: 7 additions & 6 deletions players/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,18 +5,19 @@
from django.views.generic import RedirectView

from players import views
from app_settings import preview_user_required

urlpatterns = [
url(r'^$', TemplateView.as_view(template_name='players/home.html'), name='aimmo/home'),
url(r'^$', login_required(preview_user_required(TemplateView.as_view(template_name='players/home.html'))), name='aimmo/home'),

url(r'^accounts/login/$', auth_views.login),
url(r'^accounts/login/$', auth_views.login, name='aimmo/login'),
url(r'^accounts/logout/$', auth_views.logout, {'next_page' : 'aimmo/logout_success'}, name='aimmo/logout'),
url(r'^accounts/logout_success/$', TemplateView.as_view(template_name='registration/success_logout.html'), name='aimmo/logout_success'),

url(r'^program/(?P<id>[0-9]+)/$', login_required(views.ProgramView.as_view()), name='aimmo/program'),
url(r'^program_level/(?P<num>[0-9]+)/$', login_required(views.program_level), name='aimmo/program_level'),
url(r'^watch/(?P<id>[0-9]+)/$', login_required(views.watch_game), name='aimmo/watch'),
url(r'^watch_level/(?P<num>[0-9]+)/$', login_required(views.watch_level), name='aimmo/watch_level'),
url(r'^program/(?P<id>[0-9]+)/$', login_required(preview_user_required(views.ProgramView.as_view())), name='aimmo/program'),
url(r'^program_level/(?P<num>[0-9]+)/$', login_required(preview_user_required(views.program_level)), name='aimmo/program_level'),
url(r'^watch/(?P<id>[0-9]+)/$', login_required(preview_user_required(views.watch_game)), name='aimmo/watch'),
url(r'^watch_level/(?P<num>[0-9]+)/$', login_required(preview_user_required(views.watch_level)), name='aimmo/watch_level'),
url(r'^statistics/$', TemplateView.as_view(template_name='players/statistics.html'), name='aimmo/statistics'),
url(r'^game_ide/$', TemplateView.as_view(template_name='players/game_ide.html'), name='aimmo/game_ide'),

Expand Down
10 changes: 8 additions & 2 deletions players/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@
import os

from django.contrib.auth.decorators import login_required
from django.contrib.auth.models import User
from django.core.exceptions import ValidationError
from django.core.urlresolvers import reverse
from django.http import HttpResponse, Http404
Expand All @@ -16,9 +15,12 @@
from models import Avatar, Game, LevelAttempt
from players import forms
from . import app_settings
from app_settings import get_users_for_new_game

LOGGER = logging.getLogger(__name__)

preview_user_required = app_settings.preview_user_required


def _post_code_success_response(message):
return _create_response("SUCCESS", message)
Expand All @@ -33,6 +35,7 @@ def _create_response(status, message):


@login_required
@preview_user_required
def code(request, id):
game = get_object_or_404(Game, id=id)
if not game.can_user_play(request.user):
Expand Down Expand Up @@ -166,6 +169,7 @@ def _add_and_return_level(num, user):


@login_required
@preview_user_required
def add_game(request):
if request.method == 'POST':
form = forms.AddGameForm(request.POST)
Expand All @@ -175,7 +179,9 @@ def add_game(request):
game.owner = request.user
game.main_user = request.user
game.save()
game.can_play.add(*User.objects.all())
users = get_users_for_new_game(request)
if users is not None:
game.can_play.add(*users)
return redirect('aimmo/program', id=game.id)
else:
form = forms.AddGameForm()
Expand Down
10 changes: 8 additions & 2 deletions test_settings.py
Original file line number Diff line number Diff line change
@@ -1,19 +1,25 @@
import os
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.sqlite3',
'NAME': os.path.join(os.path.abspath(os.path.dirname(__file__)), 'db.sqlite3'),
},
}

INSTALLED_APPS = [
'django.contrib.admin',
'django.contrib.auth',
'players',
'integration_tests',
'aimmo_runner',
]

PIPELINE_ENABLED = False
ROOT_URLCONF = 'django_autoconfig.autourlconf'
STATIC_ROOT = '.tests_static/'

SECRET_KEY = 'test_key'
GAME_SERVER_URL_FUNCTION = lambda game_id: ('base %s' % game_id, 'path %s' % game_id)
GAME_SERVER_PORT_FUNCTION = lambda game_id: 8001
GAME_SERVER_SSL_FLAG = False

from django_autoconfig.autoconfig import configure_settings # noqa: E402
configure_settings(globals())

0 comments on commit 3cf2214

Please sign in to comment.