Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Final #18

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
16 changes: 12 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,20 @@ python -m venv venv
```
pip install -r requirements.txt
```
3. Install custos client SDK in the virtual env (Follow instructions in "Install Custos Client SDK")
4. Run django server using manage.py file in custos_portal directory.
3. Install custos client SDK in the virtual env (Follow instructions in "Install Custos Client SDK")
4. Make migrations
```
python manage.py migrate
```
5. Run django server using manage.py file in custos_portal directory.
```
python manage.py runserver
```
5. Run webpack development server from custos_portal/custos_portal/static/common using:
7. Install all the npm dependencies
```
npm install
```
6. Run webpack development server from custos_portal/custos_portal/static/common using:
```
npm run serve
```
Expand All @@ -39,4 +47,4 @@ This Django projects consists of 3 apps
- Workspace: Handles all the requests for a regular users like 'create new tenant requests'

We also use vuejs for the screens in Admin and Workspace folders. The components and other javascript files can be found
at ```custos_portal\static\common```
at ```custos_portal\static\common```
19 changes: 15 additions & 4 deletions custos_portal/custos_portal/__init__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,16 @@
from clients.identity_management_client import IdentityManagementClient
from clients.user_management_client import UserManagementClient
from custos.clients.identity_management_client import IdentityManagementClient
from custos.clients.user_management_client import UserManagementClient
from custos.transport.settings import CustosServerClientSettings
import os

user_management_client = UserManagementClient()
identity_management_client = IdentityManagementClient()
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
settings = os.path.join(BASE_DIR, 'transport', 'settings.ini')

custos_settings = CustosServerClientSettings(custos_host=custos_host,
custos_port=custos_port,
custos_client_id=custos_client_id,
custos_client_sec=custos_client_sec,
configuration_file_location=None)

identity_management_client = IdentityManagementClient(custos_settings)
user_management_client = UserManagementClient(custos_settings)
10 changes: 9 additions & 1 deletion custos_portal/custos_portal/apps/admin/apps.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,15 @@ class AdminConfig(CustosAppConfig):
"""
nav = [
{
'label': 'Application Catalog',
'label': 'Create new tenant request',
'icon': 'fa fa-plus-square',
'url': 'custos_portal_admin:request_new_tenant',
'active_prefixes': ['applications', 'request-new-tenant'],
'enabled': lambda req: (req.is_gateway_admin or
req.is_read_only_gateway_admin),
},
{
'label': 'List of all existing tenant requests',
'icon': 'fa fa-list',
'url': 'custos_portal_admin:list_requests',
'active_prefixes': ['applications', 'list-requests'],
Expand Down
5 changes: 3 additions & 2 deletions custos_portal/custos_portal/apps/admin/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,8 @@

app_name = 'custos_portal_admin'
urlpatterns = [
url(r'^request-new-tenant', views.request_new_tenant, name='request_new_tenant'),
url(r'^list-requests', views.list_new_tenant_requests, name='list_requests'),
url(r'^request/(?P<tenant_request_id>[^/]+)/$', views.view_tenant_request, name="view_tenant_request"),
url(r'^edit-tenant-request/(?P<tenant_request_id>[^/]+)/$', views.edit_tenant_request, name="edit_tenant_request")
url(r'^request/(?P<client_id>[^/]+)/$', views.view_tenant_request, name="view_tenant_request"),
url(r'^edit-tenant-request/(?P<client_id>[^/]+)/$', views.edit_tenant_request, name="edit_tenant_request")
]
34 changes: 26 additions & 8 deletions custos_portal/custos_portal/apps/admin/views.py
Original file line number Diff line number Diff line change
@@ -1,26 +1,44 @@
from django.shortcuts import render
from custos_portal import identity_management_client
from django.conf import settings

def request_new_tenant(request):
if request.method == 'POST':
logger.debug("Form is posted")
request.active_nav_item = 'admin-request-new-tenant'
token = request.COOKIES['token']

return render(request, 'workspace/request_new_tenant.html', {
'bundle_name': 'admin-request-new-tenant',
'data': token
})

def list_new_tenant_requests(request):
request.active_nav_item = 'list-requests'

# TODO fetch all the tenant requests from airavata here.
token = request.COOKIES['token']
return render(request, 'workspace/list_requests.html', {
'bundle_name': 'admin-list-requests',
'data': token
})


def view_tenant_request(request, tenant_request_id):
print("Admin view Tenant request Id: {}".format(tenant_request_id)),
def view_tenant_request(request, client_id):
token = request.COOKIES['token']

return render(request, 'workspace/view_tenant_request.html', {
'bundle_name': 'admin-view-request',
'tenant_request_id': tenant_request_id
'tenant_client_id': client_id,
'data': token
})


def edit_tenant_request(request, tenant_request_id):
print("Edit Tenant request Id: {}".format(tenant_request_id)),
def edit_tenant_request(request, client_id):
token = request.COOKIES['token']

return render(request, 'workspace/view_tenant_request.html', {
'bundle_name': 'admin-edit-request',
'tenant_request_id': tenant_request_id
})
'tenant_client_id': client_id,
'data': token
})
3 changes: 1 addition & 2 deletions custos_portal/custos_portal/apps/auth/backends.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ class CustosAuthBackend(ModelBackend):
def authenticate(self, request=None, username=None, password=None, refresh_token=None):
try:
if username and password:
print("Entered username and password")
token = self._get_token_and_userinfo_password_flow(username, password)
request.session["ACCESS_TOKEN"] = token
userinfo = self._get_userinfo_from_token(token)
Expand Down Expand Up @@ -69,8 +70,6 @@ def _get_token_and_userinfo_redirect_flow(self, request):
if state == saved_state:
response = identity_management_client.token(settings.CUSTOS_TOKEN, redirect_uri, code)
token = MessageToDict(response)

logger.debug(token["access_token"])
return token

return
Expand Down
19 changes: 14 additions & 5 deletions custos_portal/custos_portal/apps/auth/forms.py
Original file line number Diff line number Diff line change
@@ -1,13 +1,22 @@
import logging

from clients.user_management_client import UserManagementClient
from custos.core import IamAdminService_pb2
from custos.clients.user_management_client import UserManagementClient
from custos.transport.settings import CustosServerClientSettings
from custos.server.core import IamAdminService_pb2
from django import forms
from django.conf import settings
from django.core import validators
import os

logger = logging.getLogger(__name__)
user_management_client = UserManagementClient()
BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
settings = os.path.join(BASE_DIR, 'transport', 'settings.ini')
custos_settings = CustosServerClientSettings(custos_host=custos_host,
custos_port=custos_port,
custos_client_id=custos_client_id,
custos_client_sec=custos_client_sec,
configuration_file_location=None)
user_management_client = UserManagementClient(custos_settings)

USERNAME_VALIDATOR = validators.RegexValidator(
regex=r"^[a-z0-9_-]+$",
Expand Down Expand Up @@ -219,9 +228,9 @@ def clean(self):
username = cleaned_data.get('username')

check_username = user_management_client.is_username_available(settings.CUSTOS_TOKEN, username)
print(check_username.is_exist)

try:
if user_management_client.is_username_available(settings.CUSTOS_TOKEN, username).is_exist:
if user_management_client.is_username_available(settings.CUSTOS_TOKEN, username).status:
logger.info("Username is available");
else:
logger.info("Username is not available");
Expand Down
67 changes: 24 additions & 43 deletions custos_portal/custos_portal/apps/auth/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,14 @@
from django.views.decorators.debug import sensitive_variables
from google.protobuf.json_format import MessageToDict
from requests_oauthlib import OAuth2Session
from google.auth import jwt

from . import utils
from . import models
from . import forms
from ... import identity_management_client
from ... import user_management_client
from . import backends

logger = logging.getLogger(__name__)

Expand All @@ -33,7 +35,15 @@ def callback(request):
user = authenticate(request=request)
logger.debug("Saving user to session: {}".format(user))
login(request, user)
return _handle_login_redirect(request)
sess = request.session
token = sess['ACCESS_TOKEN']
code = request.GET.get('code').strip()
logger.info(code)
redirect_uri = request.build_absolute_uri(reverse('custos_portal_auth:callback'))
response = _handle_login_redirect(request)
response.set_cookie('token', value=token, secure=False, httponly=True)
return response

except Exception as err:
logger.exception("An error occurred while processing OAuth2 "
"callback: {}".format(request.build_absolute_uri()))
Expand All @@ -59,43 +69,9 @@ def callback_error(request, idp_alias):


def create_account(request):
if request.method == 'POST':
form = forms.CreateAccountForm(request.POST)
if form.is_valid():
try:
username = form.cleaned_data['username']
email = form.cleaned_data['email']
first_name = form.cleaned_data['first_name']
last_name = form.cleaned_data['last_name']
password = form.cleaned_data['password']
is_temp_password = False
result = user_management_client.register_user(settings.CUSTOS_TOKEN, username, first_name, last_name,
password, email, is_temp_password)
if result.is_registered:
logger.debug("User account successfully created for : {}".format(username))
_create_and_send_email_verification_link(request, username, email, first_name, last_name,
settings.LOGIN_URL)
messages.success(
request,
"Account request processed successfully. Before you "
"can login you need to confirm your email address. "
"We've sent you an email with a link that you should "
"click on to complete the account creation process.")
else:
form.add_error(None, ValidationError("Failed to register the user with IAM service"))
except TypeError as e:
logger.exception(
"Failed to create account for user", exc_info=e)
form.add_error(None, ValidationError(e))
return render(request, 'custos_portal_auth/create_account.html', {
'options': settings.AUTHENTICATION_OPTIONS,
'form': form
})
else:
form = forms.CreateAccountForm()
return render(request, 'custos_portal_auth/create_account.html', {
return render(request, 'custos_portal_auth/form_create_account.html', {
'next': request.GET.get('next', None),
'options': settings.AUTHENTICATION_OPTIONS,
'form': form
})


Expand Down Expand Up @@ -174,7 +150,11 @@ def handle_login(request):
try:
if user is not None:
login(request, user)
return _handle_login_redirect(request)
response = identity_management_client.authenticate(settings.CUSTOS_TOKEN, username, password)
token = MessageToDict(response)["accessToken"]
response = _handle_login_redirect(request)
response.set_cookie('token', value=token, secure=False, httponly=True)
return response
else:
messages.error(request, "Login failed. Please try again.")
except Exception as err:
Expand All @@ -194,8 +174,7 @@ def redirect_login(request, idp_alias):
client_id = settings.KEYCLOAK_CLIENT_ID

auth_base_url = identity_management_client.get_oidc_configuration(settings.CUSTOS_TOKEN, client_id)
# auth_base_url = json.loads(auth_base_url.)
# print(auth_base_url)

base_authorize_url = settings.KEYCLOAK_AUTHORIZE_URL

redirect_uri = request.build_absolute_uri(
Expand All @@ -208,6 +187,7 @@ def redirect_login(request, idp_alias):
authorization_url += '&kc_idp_hint=' + quote("oidc")

# Store state in session for later validation (see backends.py)

request.session['OAUTH2_STATE'] = state
request.session['OAUTH2_REDIRECT_URI'] = redirect_uri

Expand Down Expand Up @@ -318,7 +298,9 @@ def start_login(request):
def start_logout(request):
logout(request)
redirect_url = request.build_absolute_uri(resolve_url(settings.LOGOUT_REDIRECT_URL))
return redirect(settings.KEYCLOAK_LOGOUT_URL + "?redirect_uri=" + quote(redirect_url))
response = redirect(settings.KEYCLOAK_LOGOUT_URL + "?redirect_uri=" + quote(redirect_url))
response.delete_cookie('token')
return response


def start_username_password_login(request):
Expand Down Expand Up @@ -346,8 +328,7 @@ def verify_email(request, code):
if email_verification.next:
login_url += "?" + urlencode({'next': email_verification.next})

print(user_management_client.is_user_enabled(settings.CUSTOS_TOKEN, "shivam_testing_3"))
if user_management_client.is_user_enabled(settings.CUSTOS_TOKEN, username).is_exist:
if user_management_client.is_user_enabled(settings.CUSTOS_TOKEN, username).status:
logger.debug("User {} is already enabled".format(username))
messages.success(
request,
Expand Down
3 changes: 2 additions & 1 deletion custos_portal/custos_portal/apps/workspace/urls.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,5 +6,6 @@
urlpatterns = [
url(r'^request-new-tenant', views.request_new_tenant, name='request_new_tenant'),
url(r'^list-requests', views.list_new_tenant_requests, name='list_requests'),
url(r'request/(?P<tenant_request_id>[^/]+)/$', views.view_tenant_request, name="view_tenant_request")
url(r'^request/(?P<client_id>[^/]+)/$', views.view_tenant_request, name="view_tenant_request"),
# url(r'request/(?P<tenant_request_id>[^/]+)/$', views.view_tenant_request, name="view_tenant_request")
]
14 changes: 11 additions & 3 deletions custos_portal/custos_portal/apps/workspace/views.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,23 +10,31 @@ def request_new_tenant(request):
if request.method == 'POST':
logger.debug("Form is posted")
request.active_nav_item = 'request-new-tenant'
token = request.COOKIES['token']

return render(request, 'workspace/request_new_tenant.html', {
'bundle_name': 'request-new-tenant',
'data': token
})


def list_new_tenant_requests(request):
request.active_nav_item = 'list-requests'

if request.user:
print("hell")
token = request.COOKIES['token']

return render(request, 'workspace/list_requests.html', {
'bundle_name': 'list-requests',
'data': token
})


def view_tenant_request(request, tenant_request_id):
def view_tenant_request(request, client_id):
token = request.COOKIES['token']

return render(request, 'workspace/view_tenant_request.html', {
'bundle_name': 'view-request',
'tenant_request_id': tenant_request_id
'tenant_client_id': client_id,
'data': token
})
Loading