diff --git a/services/webapp/code/rosetta/core_app/templates/navigation.html b/services/webapp/code/rosetta/core_app/templates/navigation.html index d9225a522837e417873501227287e389bd3ea252..b18e4f6da6dd9771b41682876a55f37eb5811950 100644 --- a/services/webapp/code/rosetta/core_app/templates/navigation.html +++ b/services/webapp/code/rosetta/core_app/templates/navigation.html @@ -4,7 +4,6 @@ <nav id="sidebar-wrapper"> <ul class="sidebar-nav"> <a id="menu-close" href="#" class="btn btn-light btn-lg pull-right toggle"><i class="fa fa-times"></i></a> - {% if not data.dedicated %} <br/> <br/> <li class="sidebar-brand"> @@ -13,28 +12,27 @@ <li> <a href="/main/#top" onclick = $("#menu-close").click(); >Home</a> </li> - + {% if not user.is_authenticated %} + <li> + <a href="/register" onclick = $("#menu-close").click(); >Register</a> + </li> + {% endif %} <br/> <hr> - {% else %} - <br/><br/> - {% endif %} {% if user.is_authenticated %} - <li> - <a href="/computings" onclick = $("#menu-close").click(); >Computing</a> - </li> + <a href="/account" onclick = $("#menu-close").click(); >Account</a> + </li> <li> - <a href="/containers" onclick = $("#menu-close").click(); >Containers</a> + <a href="/tasks" onclick = $("#menu-close").click(); >Tasks</a> </li> <li> - <a href="/tasks" onclick = $("#menu-close").click(); >Tasks</a> + <a href="/computings" onclick = $("#menu-close").click(); >Computing</a> </li> <li> - <a href="/account" onclick = $("#menu-close").click(); >Account</a> - </li> - + <a href="/containers" onclick = $("#menu-close").click(); >Containers</a> + </li> {% else %} <li> <center> diff --git a/services/webapp/code/rosetta/core_app/templates/register.html b/services/webapp/code/rosetta/core_app/templates/register.html index 0c06a5635e79681d8330b1030979024aa6aac036..26d8bd4b7eddafacf71b973000b50fe0d6e9e3f1 100644 --- a/services/webapp/code/rosetta/core_app/templates/register.html +++ b/services/webapp/code/rosetta/core_app/templates/register.html @@ -9,7 +9,7 @@ <div class="dashboard"> <div class="span8 offset2" style="font-size:18px"> - <h1>Sign up</h1> + <h1>Register</h1> <hr> {% if data.status == "wrong_invite" %} @@ -39,9 +39,10 @@ Start by clicking on the top-right menu icon. {% else %} - <p><b>Welcome to Dropely!</b></p> + <p><b>Welcome to Rosetta!</b></p> + + <p>We are now in closed beta testing, which means that we can only accept invite-based new users. If you have an invitation code, you can sign up right now. Otherwise, please contact the support ot get one. - <p>We are now in closed beta testing, which means that we can only accept invite-based new users. If you have an invitation code, you can sign up right now. Otherwise, <a href="/newsletter">leave your email</a> to reserve your spot in the queue and we will let you know as soon as you can sign up.</p> <br/> <br/> @@ -50,8 +51,8 @@ {% csrf_token %} <input type="email" class="form-control" placeholder="Email" name='email' required autofocus> <input type="password" class="form-control" placeholder="Password" name='password' required> - <input type="text" class="form-control" placeholder="Invitation code" name='invitation' value='Invite: {{ data.invite }}' required autofocus> - <input type='submit' class="btn btn-lg ha-btn-lg" value='Sign up' /> + <input type="text" class="form-control" placeholder="Invitation code" name='invitation' value='' required autofocus> + <input type='submit' class="btn btn-lg ha-btn-lg" value='Go' /> </form> </div> <br /></br> diff --git a/services/webapp/code/rosetta/core_app/views.py b/services/webapp/code/rosetta/core_app/views.py index 5a4d6532309fa66255745164c23af49c91b3636f..344c5353bd2c4b232f2da46695e56a21d1ec78e4 100644 --- a/services/webapp/code/rosetta/core_app/views.py +++ b/services/webapp/code/rosetta/core_app/views.py @@ -1,3 +1,4 @@ +import os import uuid import json import subprocess @@ -8,7 +9,7 @@ from django.http import HttpResponse, HttpResponseRedirect from django.contrib.auth.models import User from django.shortcuts import redirect from .models import Profile, LoginToken, Task, TaskStatuses, Container, Computing, Keys, ComputingSysConf, ComputingUserConf -from .utils import send_email, format_exception, timezonize, os_shell, booleanize, debug_param, get_tunnel_host +from .utils import send_email, format_exception, timezonize, os_shell, booleanize, debug_param, get_tunnel_host, random_username from .decorators import public_view, private_view from .exceptions import ErrorMessage @@ -135,6 +136,74 @@ def logout_view(request): logout(request) return HttpResponseRedirect('/') + +@public_view +def register_view(request): + + data = {} + data['title'] = "{} - Register".format(settings.DJANGO_PROJECT_NAME) + + # If authenticated user reloads the main URL + if request.method == 'GET' and request.user.is_authenticated: + return HttpResponseRedirect('/main/') + + # If unauthenticated register if post + if request.method == 'POST': + if not request.user.is_authenticated: + email = request.POST.get('email') + password = request.POST.get('password') + invitation = request.POST.get('invitation') + + if invitation != os.environ.get('INVITATION_CODE', 'Rosetta'): + raise ErrorMessage('Wrong invitation code') + + if '@' not in email: + raise ErrorMessage('Detected invalid email address') + + # Register the user + user = User.objects.create_user(random_username(), password=password, email=email) + + # Is this necessary? + user.save() + + data['user'] = user + + # Create profile + logger.debug('Creating user profile for user "{}"'.format(user.email)) + Profile.objects.create(user=user) + + # Generate user keys + out = os_shell('mkdir -p /data/resources/keys/', capture=True) + if not out.exit_code == 0: + logger.error(out) + raise ErrorMessage('Something went wrong in creating user keys folder. Please contact support') + + command= "/bin/bash -c \"ssh-keygen -q -t rsa -N '' -f /data/resources/keys/{}_id_rsa 2>/dev/null <<< y >/dev/null\"".format(user.username) + out = os_shell(command, capture=True) + if not out.exit_code == 0: + logger.error(out) + raise ErrorMessage('Something went wrong in creating user keys. Please contact support') + + + # Create key objects + Keys.objects.create(user = user, + default = True, + private_key_file = '/data/resources/keys/{}_id_rsa'.format(user.username), + public_key_file = '/data/resources/keys/{}_id_rsa.pub'.format(user.username)) + + + # Manually set the auth backend for the user + user.backend = 'django.contrib.auth.backends.ModelBackend' + login(request, user) + + data['status'] = 'activated' + + # All other cases, render the login page again with no other data than title + return render(request, 'register.html', {'data': data}) + + + + @public_view def entrypoint(request): return HttpResponseRedirect('/main/') diff --git a/services/webapp/code/rosetta/urls.py b/services/webapp/code/rosetta/urls.py index a6121e69b9afa7436ced16837b5f859ef96caaff..99c2c84319697c70233bd903cd8c2c4c5c0101e7 100644 --- a/services/webapp/code/rosetta/urls.py +++ b/services/webapp/code/rosetta/urls.py @@ -39,6 +39,7 @@ urlpatterns = [ path('main/', core_app_views.main_view), path('login/', core_app_views.login_view), path('logout/', core_app_views.logout_view), + url(r'^register/$', core_app_views.register_view), url(r'^account/$', core_app_views.account), url(r'^tasks/$', core_app_views.tasks), url(r'^create_task/$', core_app_views.create_task),