You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@airavata.apache.org by ma...@apache.org on 2017/09/21 17:00:02 UTC
[32/54] [abbrv] [partial] airavata-django-portal git commit: Moving
admin_view JS into django app and moving django project back
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/auth/models.py
----------------------------------------------------------------------
diff --git a/django_airavata/apps/auth/models.py b/django_airavata/apps/auth/models.py
new file mode 100644
index 0000000..71a8362
--- /dev/null
+++ b/django_airavata/apps/auth/models.py
@@ -0,0 +1,3 @@
+from django.db import models
+
+# Create your models here.
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/auth/templates/django_airavata_auth/auth_error.html
----------------------------------------------------------------------
diff --git a/django_airavata/apps/auth/templates/django_airavata_auth/auth_error.html b/django_airavata/apps/auth/templates/django_airavata_auth/auth_error.html
new file mode 100644
index 0000000..b7f5d58
--- /dev/null
+++ b/django_airavata/apps/auth/templates/django_airavata_auth/auth_error.html
@@ -0,0 +1,11 @@
+<html>
+ <head>
+ <title>Authentication Error</title>
+ </head>
+ <body>
+ <h1>Authentication Error</h1>
+ <p>
+ Failed to process authentication callback. You might want to <a href="{{ login_url }}">try logging in again</a>.
+ </p>
+ </body>
+</html>
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/auth/templates/django_airavata_auth/login.html
----------------------------------------------------------------------
diff --git a/django_airavata/apps/auth/templates/django_airavata_auth/login.html b/django_airavata/apps/auth/templates/django_airavata_auth/login.html
new file mode 100644
index 0000000..fb326b0
--- /dev/null
+++ b/django_airavata/apps/auth/templates/django_airavata_auth/login.html
@@ -0,0 +1,28 @@
+{% extends 'main_base.html' %}
+
+{% block content %}
+
+<div class="container">
+ <div class="row">
+ <div class="col-md-6 col-md-offset-3">
+ <div class="panel panel-default">
+ <div class="panel-body">
+ <h3>Login</h3>
+ <form action="{% url 'django_airavata_auth:handle_login' %}" method="post">
+ {% csrf_token %}
+ <div class="form-group">
+ <label for="username">Username</label>
+ <input type="text" class="form-control" id="username" name="username" placeholder="Username" value="{{ username }}">
+ </div>
+ <div class="form-group">
+ <label for="password">Password</label>
+ <input type="password" class="form-control" id="password" name="password" placeholder="Password">
+ </div>
+ <button type="submit" class="btn btn-default">Submit</button>
+ </form>
+ </div>
+ </div>
+ </div>
+ </div>
+</div>
+{% endblock content %}
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/auth/tests.py
----------------------------------------------------------------------
diff --git a/django_airavata/apps/auth/tests.py b/django_airavata/apps/auth/tests.py
new file mode 100644
index 0000000..7ce503c
--- /dev/null
+++ b/django_airavata/apps/auth/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/auth/urls.py
----------------------------------------------------------------------
diff --git a/django_airavata/apps/auth/urls.py b/django_airavata/apps/auth/urls.py
new file mode 100644
index 0000000..4cb5b35
--- /dev/null
+++ b/django_airavata/apps/auth/urls.py
@@ -0,0 +1,13 @@
+
+from django.conf.urls import url
+
+from . import views
+
+app_name = 'django_airavata_auth'
+urlpatterns = [
+ url(r'^login$', views.start_login, name='login'),
+ url(r'^handle_login$', views.handle_login, name='handle_login'),
+ url(r'^logout$', views.start_logout, name='logout'),
+ url(r'^callback', views.callback, name='callback'),
+ url(r'^error', views.auth_error, name='error'),
+]
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/auth/utils.py
----------------------------------------------------------------------
diff --git a/django_airavata/apps/auth/utils.py b/django_airavata/apps/auth/utils.py
new file mode 100644
index 0000000..7d0bee4
--- /dev/null
+++ b/django_airavata/apps/auth/utils.py
@@ -0,0 +1,13 @@
+
+from apache.airavata.model.security.ttypes import AuthzToken
+
+from django.conf import settings
+
+def get_authz_token(request):
+ if 'ACCESS_TOKEN' in request.session:
+ access_token = request.session['ACCESS_TOKEN']
+ username = request.user.username
+ gateway_id = settings.GATEWAY_ID
+ return AuthzToken(accessToken=access_token, claimsMap={'gatewayID': gateway_id, 'userName': username})
+ else:
+ return None
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/auth/views.py
----------------------------------------------------------------------
diff --git a/django_airavata/apps/auth/views.py b/django_airavata/apps/auth/views.py
new file mode 100644
index 0000000..a066bc8
--- /dev/null
+++ b/django_airavata/apps/auth/views.py
@@ -0,0 +1,63 @@
+from django.conf import settings
+from django.contrib.auth import authenticate, login, logout
+from django.http import HttpResponse
+from django.shortcuts import render, redirect
+from django.urls import reverse
+
+from requests_oauthlib import OAuth2Session
+
+import logging
+from urllib.parse import quote
+
+logger = logging.getLogger(__name__)
+
+# Create your views here.
+
+def start_login(request):
+ # TODO: If the gateway is configured to not allow username password authentication, then redirect to Keycloak
+ # client_id = settings.KEYCLOAK_CLIENT_ID
+ # base_authorize_url = settings.KEYCLOAK_AUTHORIZE_URL
+ # oauth2_session = OAuth2Session(client_id, scope='openid', redirect_uri=request.build_absolute_uri(reverse('django_airavata_auth:callback')))
+ # authorization_url, state = oauth2_session.authorization_url(base_authorize_url)
+ # logger.debug("authorization_url={}, state={}".format(authorization_url, state))
+ # # Store state in session for later validation
+ # request.session['OAUTH2_STATE'] = state
+ # return redirect(authorization_url)
+ return render(request, 'django_airavata_auth/login.html')
+
+def handle_login(request):
+ username = request.POST['username']
+ password = request.POST['password']
+ user = authenticate(username=username, password=password, request=request)
+ logger.debug("authenticated user: {}".format(user))
+ try:
+ if user is not None:
+ login(request, user)
+ return redirect(settings.LOGIN_REDIRECT_URL)
+ else:
+ # TODO: add error message that login failed
+ return render(request, 'django_airavata_auth/login.html', {
+ 'username': username
+ })
+ except Exception as err:
+ logger.exception("An error occurred while logging in with username and password")
+ return redirect(reverse('django_airavata_auth:error'))
+
+def start_logout(request):
+ logout(request)
+ redirect_url = request.build_absolute_uri(reverse(settings.LOGOUT_REDIRECT_URL))
+ return redirect(settings.KEYCLOAK_LOGOUT_URL + "?redirect_uri=" + quote(redirect_url))
+
+def callback(request):
+ try:
+ user = authenticate(request=request)
+ login(request, user)
+ return redirect(settings.LOGIN_REDIRECT_URL)
+ except Exception as err:
+ logger.exception("An error occurred while processing OAuth2 callback: {}".format(request.build_absolute_uri()))
+ return redirect(reverse('django_airavata_auth:error'))
+
+def auth_error(request):
+ return render(request, 'django_airavata_auth/auth_error.html', {
+ 'login_url': settings.LOGIN_URL
+ })
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/groups/__init__.py
----------------------------------------------------------------------
diff --git a/django_airavata/apps/groups/__init__.py b/django_airavata/apps/groups/__init__.py
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/groups/admin.py
----------------------------------------------------------------------
diff --git a/django_airavata/apps/groups/admin.py b/django_airavata/apps/groups/admin.py
new file mode 100644
index 0000000..8c38f3f
--- /dev/null
+++ b/django_airavata/apps/groups/admin.py
@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/groups/apps.py
----------------------------------------------------------------------
diff --git a/django_airavata/apps/groups/apps.py b/django_airavata/apps/groups/apps.py
new file mode 100644
index 0000000..e66c251
--- /dev/null
+++ b/django_airavata/apps/groups/apps.py
@@ -0,0 +1,6 @@
+from django.apps import AppConfig
+
+
+class GroupsConfig(AppConfig):
+ name = 'django_airavata.apps.groups'
+ label = 'django_airavata_group'
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/groups/forms.py
----------------------------------------------------------------------
diff --git a/django_airavata/apps/groups/forms.py b/django_airavata/apps/groups/forms.py
new file mode 100644
index 0000000..d3ba029
--- /dev/null
+++ b/django_airavata/apps/groups/forms.py
@@ -0,0 +1,31 @@
+# Create your forms here.
+from django import forms
+
+class CreateForm(forms.Form):
+ domain_id = forms.CharField(required=True, widget=forms.HiddenInput)
+ group_name = forms.CharField(required=True)
+ description = forms.CharField(
+ required=True,
+ widget=forms.Textarea
+ )
+ group_owner = forms.CharField(required=True, widget=forms.HiddenInput)
+ CHOICES1 = (('1', 'User Level',), ('2', 'Admin Level',))
+ group_type = forms.ChoiceField(widget=forms.HiddenInput, choices=CHOICES1, required=True)
+ CHOICES2 = (('0', 'Single User',), ('1', 'Multi User',))
+ group_cardinality = forms.ChoiceField(widget=forms.HiddenInput, choices=CHOICES2, required=True)
+
+#class AddForm(forms.Form):
+# users = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple, required=False)
+
+#class RemoveForm(forms.Form):
+# members = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple, required=False)
+
+class AddForm(forms.Form):
+ def __init__(self, data=None, user_choices=None):
+ super().__init__(data=data)
+ self.fields["users"] = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple, choices=user_choices)
+
+class RemoveForm(forms.Form):
+ def __init__(self, data=None, user_choices=None):
+ super().__init__(data=data)
+ self.fields["members"] = forms.MultipleChoiceField(widget=forms.CheckboxSelectMultiple, choices=user_choices)
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/groups/migrations/__init__.py
----------------------------------------------------------------------
diff --git a/django_airavata/apps/groups/migrations/__init__.py b/django_airavata/apps/groups/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/groups/models.py
----------------------------------------------------------------------
diff --git a/django_airavata/apps/groups/models.py b/django_airavata/apps/groups/models.py
new file mode 100644
index 0000000..71a8362
--- /dev/null
+++ b/django_airavata/apps/groups/models.py
@@ -0,0 +1,3 @@
+from django.db import models
+
+# Create your models here.
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/groups/templates/django_airavata_groups/group_details.html
----------------------------------------------------------------------
diff --git a/django_airavata/apps/groups/templates/django_airavata_groups/group_details.html b/django_airavata/apps/groups/templates/django_airavata_groups/group_details.html
new file mode 100644
index 0000000..45364c5
--- /dev/null
+++ b/django_airavata/apps/groups/templates/django_airavata_groups/group_details.html
@@ -0,0 +1,61 @@
+{% extends 'base.html' %}
+
+{% block content %}
+
+<h1 align="center">Group Details</h1>
+
+<div class="jumbotron">
+ <div class="container">
+ {% if user.is_authenticated %}
+ <div class="row">
+ <div class="col-md-12 table-responsive">
+ <table class="table table-striped table-bordered">
+ <thead>
+ <tr>
+ <th style="text-align:center">PROPERTY</th>
+ <th style="text-align:center">VALUE</th>
+ </tr>
+ </thead>
+ <tbody align="center">
+ <tr>
+ <td>Group Name</td>
+ <td>{{ group.name }}</td>
+ </tr>
+ <tr>
+ <td>Description</td>
+ <td>{{ group.description }}</td>
+ </tr>
+ <tr>
+ <td>Onwer ID</td>
+ <td>{{ group.ownerId }}</td>
+ </tr>
+ {% if u_id == group.ownerId %}
+ <tr>
+ <td>Group Members</td>
+ <td>
+ {% for member in members %}
+ {{ member.userId }}<br>
+ {% endfor %}
+ </td>
+ </tr>
+ {% endif %}
+ <tr>
+ <td>Created</td>
+ <td>{{ c_time }}</td>
+ </tr>
+ <tr>
+ <td>Updated</td>
+ <td>{{ u_time }}</td>
+ </tr>
+ </tbody>
+ </table>
+ </div>
+ </div>
+ <p align="right"><a class="btn btn-primary btn-xs" href="{% url 'django_airavata_groups:manage' %}" role="button">Back</a></p>
+ {% else %}
+ <p><a class="btn btn-primary btn-lg" href="{% url 'django_airavata_auth:login' %}" role="button">Login »</a></p>
+ {% endif %}
+ </div>
+</div>
+
+{% endblock content %}
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/groups/templates/django_airavata_groups/group_edit.html
----------------------------------------------------------------------
diff --git a/django_airavata/apps/groups/templates/django_airavata_groups/group_edit.html b/django_airavata/apps/groups/templates/django_airavata_groups/group_edit.html
new file mode 100644
index 0000000..507a456
--- /dev/null
+++ b/django_airavata/apps/groups/templates/django_airavata_groups/group_edit.html
@@ -0,0 +1,38 @@
+{% extends 'base.html' %}
+
+{% block content %}
+
+<h1 align="center">Edit Group</h1>
+<br>
+{% block body %}
+<div class="container">
+ {% if user.is_authenticated %}
+ <h5>Group Name: {{ group_name }}</h5>
+ <div class="row">
+ <div class="col-lg-6">
+ <h3>Add</h3>
+ <form action="" method="post">
+ {% csrf_token %}
+ {{ add_form.as_p }}
+ <button class="btn btn-primary btn-xs" type="submit" role="button" name="add">Add</button>
+ </form>
+ </div>
+ <div class="col-lg-6">
+ <h3>Remove</h3>
+ <form action="" method="post">
+ {% csrf_token %}
+ {{ remove_form.as_p }}
+ <button class="btn btn-primary btn-xs" type="submit" role="button" name="remove" onclick="return confirm('Are you sure you want to remove the selected members from the group? This action cannot be undone!')">Remove</button>
+ </form>
+ </div>
+ </div>
+ <br>
+ <br>
+ <p align="right"><a class="btn btn-primary btn-xs" href="{% url 'django_airavata_groups:manage' %}" role="button">Back</a></p>
+ {% else %}
+ <p><a class="btn btn-primary btn-lg" href="{% url 'django_airavata_auth:login' %}" role="button">Login »</a></p>
+ {% endif %}
+</div>
+{% endblock %}
+
+{% endblock content %}
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/groups/templates/django_airavata_groups/groups_create.html
----------------------------------------------------------------------
diff --git a/django_airavata/apps/groups/templates/django_airavata_groups/groups_create.html b/django_airavata/apps/groups/templates/django_airavata_groups/groups_create.html
new file mode 100644
index 0000000..e7ac749
--- /dev/null
+++ b/django_airavata/apps/groups/templates/django_airavata_groups/groups_create.html
@@ -0,0 +1,28 @@
+{% extends 'base.html' %}
+
+{% block content %}
+
+<h1 align="center">Create a Group</h1>
+<br>
+{% block body %}
+<div class="container">
+ {% if user.is_authenticated %}
+ <div class="row">
+ <div class="col-md-12">
+ <h3>Enter Group Details</h3>
+ <form action="" method="post">
+ {% csrf_token %}
+ {{ form.as_p }}
+ <button class="btn btn-primary btn-xs" type="submit" role="button">Submit</button>
+ </form>
+ </div>
+ </div>
+ <br>
+ <p align="right"><a class="btn btn-primary btn-xs" href="{% url 'django_airavata_groups:manage' %}" role="button">Back</a></p>
+ {% else %}
+ <p><a class="btn btn-primary btn-lg" href="{% url 'django_airavata_auth:login' %}" role="button">Login »</a></p>
+ {% endif %}
+</div>
+{% endblock %}
+
+{% endblock content %}
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/groups/templates/django_airavata_groups/groups_manage.html
----------------------------------------------------------------------
diff --git a/django_airavata/apps/groups/templates/django_airavata_groups/groups_manage.html b/django_airavata/apps/groups/templates/django_airavata_groups/groups_manage.html
new file mode 100644
index 0000000..2e7fc0b
--- /dev/null
+++ b/django_airavata/apps/groups/templates/django_airavata_groups/groups_manage.html
@@ -0,0 +1,99 @@
+{% extends 'base.html' %}
+
+{% block content %}
+
+<h1 align="center">Manage Groups</h1>
+<br>
+<div class="container">
+ {% if user.is_authenticated %}
+ <div class="row">
+ <a href="{% url 'django_airavata_groups:create' %}">
+ <button type="button" class="btn btn-default toggle-add-tenant"><span
+ class="glyphicon glyphicon-plus"></span>Create a New Group
+ </button>
+ </a>
+ </div>
+ <br>
+ <hr>
+ {% if messages %}
+ <div class="alert alert-info">
+ <ul class="messages">
+ {% for message in messages %}
+ <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
+ {% endfor %}
+ </ul>
+ </div>
+ {% endif %}
+ <br>
+ <div class="row">
+ <div class="col-md-12 table-responsive">
+ <h3>Groups you own</h3>
+ <br>
+ <br>
+ <table class="table table-striped table-bordered">
+ <thead>
+ <tr>
+ <th style="text-align:center">NAME</th>
+ <th style="text-align:center">OPTIONS</th>
+ </tr>
+ </thead>
+ <tbody align="center">
+ {% for group in owner %}
+ <tr>
+ <td>{{ group.name }}</td>
+ <td>
+ <a href="{% url 'django_airavata_groups:view' %}?group_id={{ group.groupId | urlencode }}">
+ <button type="button" class="btn btn-primary btn-xs">View</button>
+ </a>
+ <a href="{% url 'django_airavata_groups:edit' %}?group_id={{ group.groupId | urlencode }}">
+ <button type="button" class="btn btn-primary btn-xs">Edit</button>
+ </a>
+ <a href="{% url 'django_airavata_groups:delete' %}?group_id={{ group.groupId | urlencode }}">
+ <button type="button" class="btn btn-danger btn-xs" onclick="return confirm('Are you sure you want to delete the group? This action cannot be undone!')">Delete</button>
+ </a>
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ </div>
+ <br>
+ <hr>
+ <br>
+ <div class="row">
+ <div class="col-md-12 table-responsive">
+ <h3>Groups you're a member of</h3>
+ <br>
+ <br>
+ <table class="table table-striped table-bordered">
+ <thead>
+ <tr>
+ <th style="text-align:center">NAME</th>
+ <th style="text-align:center">OPTIONS</th>
+ </tr>
+ </thead>
+ <tbody align="center">
+ {% for group in member %}
+ <tr>
+ <td>{{ group.name }}</td>
+ <td>
+ <a href="{% url 'django_airavata_groups:view' %}?group_id={{ group.groupId | urlencode }}">
+ <button type="button" class="btn btn-primary btn-xs">View</button>
+ </a>
+ <a href="{% url 'django_airavata_groups:leave' %}?group_id={{ group.groupId | urlencode }}">
+ <button type="button" class="btn btn-danger btn-xs" onclick="return confirm('Are you sure you want to leave the group? This action cannot be undone!')">Leave</button>
+ </a>
+ </td>
+ </tr>
+ {% endfor %}
+ </tbody>
+ </table>
+ </div>
+ </div>
+ {% else %}
+ <p><a class="btn btn-primary btn-lg" href="{% url 'django_airavata_auth:login' %}" role="button">Login »</a></p>
+ {% endif %}
+</div>
+
+{% endblock content %}
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/groups/tests.py
----------------------------------------------------------------------
diff --git a/django_airavata/apps/groups/tests.py b/django_airavata/apps/groups/tests.py
new file mode 100644
index 0000000..7ce503c
--- /dev/null
+++ b/django_airavata/apps/groups/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/groups/urls.py
----------------------------------------------------------------------
diff --git a/django_airavata/apps/groups/urls.py b/django_airavata/apps/groups/urls.py
new file mode 100644
index 0000000..d4ed1f3
--- /dev/null
+++ b/django_airavata/apps/groups/urls.py
@@ -0,0 +1,9 @@
+
+from django.conf.urls import url
+
+from . import views
+
+app_name = 'django_airavata_groups'
+urlpatterns = [
+ url(r'^$', views.groups_list, name='groups'),
+]
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/groups/views.py
----------------------------------------------------------------------
diff --git a/django_airavata/apps/groups/views.py b/django_airavata/apps/groups/views.py
new file mode 100644
index 0000000..805ceab
--- /dev/null
+++ b/django_airavata/apps/groups/views.py
@@ -0,0 +1,23 @@
+# Create your views here.
+from django.conf import settings
+from django.contrib.auth.decorators import login_required
+from django.shortcuts import render, redirect
+
+import logging
+
+logger = logging.getLogger(__name__)
+
+
+@login_required
+def groups_list(request):
+
+ gateway_id = settings.GATEWAY_ID
+
+ try:
+ groups = request.sharing_client.getGroups(gateway_id, 0, -1)
+ return render(request, 'django_airavata_groups/groups_list.html', {
+ 'groups': groups
+ })
+ except Exception as e:
+ logger.exception("Failed to load groups")
+ return redirect('/')
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/workspace/__init__.py
----------------------------------------------------------------------
diff --git a/django_airavata/apps/workspace/__init__.py b/django_airavata/apps/workspace/__init__.py
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/workspace/admin.py
----------------------------------------------------------------------
diff --git a/django_airavata/apps/workspace/admin.py b/django_airavata/apps/workspace/admin.py
new file mode 100644
index 0000000..8c38f3f
--- /dev/null
+++ b/django_airavata/apps/workspace/admin.py
@@ -0,0 +1,3 @@
+from django.contrib import admin
+
+# Register your models here.
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/workspace/apps.py
----------------------------------------------------------------------
diff --git a/django_airavata/apps/workspace/apps.py b/django_airavata/apps/workspace/apps.py
new file mode 100644
index 0000000..ffa1ad0
--- /dev/null
+++ b/django_airavata/apps/workspace/apps.py
@@ -0,0 +1,6 @@
+from django.apps import AppConfig
+
+
+class WorkspaceConfig(AppConfig):
+ name = 'django_airavata.apps.workspace'
+ label = 'django_airavata_workspace'
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/workspace/migrations/__init__.py
----------------------------------------------------------------------
diff --git a/django_airavata/apps/workspace/migrations/__init__.py b/django_airavata/apps/workspace/migrations/__init__.py
new file mode 100644
index 0000000..e69de29
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/workspace/models.py
----------------------------------------------------------------------
diff --git a/django_airavata/apps/workspace/models.py b/django_airavata/apps/workspace/models.py
new file mode 100644
index 0000000..71a8362
--- /dev/null
+++ b/django_airavata/apps/workspace/models.py
@@ -0,0 +1,3 @@
+from django.db import models
+
+# Create your models here.
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/workspace/templates/django_airavata_workspace/projects_list.html
----------------------------------------------------------------------
diff --git a/django_airavata/apps/workspace/templates/django_airavata_workspace/projects_list.html b/django_airavata/apps/workspace/templates/django_airavata_workspace/projects_list.html
new file mode 100644
index 0000000..4a52225
--- /dev/null
+++ b/django_airavata/apps/workspace/templates/django_airavata_workspace/projects_list.html
@@ -0,0 +1,16 @@
+{% extends 'base.html' %}
+
+{% load static %}
+
+{% block content %}
+
+<h1>Projects</h1>
+
+<div id="app"></div>
+
+{% endblock content %}
+
+{% block scripts %}
+
+<script src="{% static "django_airavata_workspace/build/main.js" %}"></script>
+{% endblock %}
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/workspace/tests.py
----------------------------------------------------------------------
diff --git a/django_airavata/apps/workspace/tests.py b/django_airavata/apps/workspace/tests.py
new file mode 100644
index 0000000..7ce503c
--- /dev/null
+++ b/django_airavata/apps/workspace/tests.py
@@ -0,0 +1,3 @@
+from django.test import TestCase
+
+# Create your tests here.
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/workspace/urls.py
----------------------------------------------------------------------
diff --git a/django_airavata/apps/workspace/urls.py b/django_airavata/apps/workspace/urls.py
new file mode 100644
index 0000000..6bc73a7
--- /dev/null
+++ b/django_airavata/apps/workspace/urls.py
@@ -0,0 +1,9 @@
+
+from django.conf.urls import url
+
+from . import views
+
+app_name = 'django_airavata_workspace'
+urlpatterns = [
+ url(r'^projects$', views.projects_list, name='projects'),
+]
\ No newline at end of file
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/apps/workspace/views.py
----------------------------------------------------------------------
diff --git a/django_airavata/apps/workspace/views.py b/django_airavata/apps/workspace/views.py
new file mode 100644
index 0000000..6967f25
--- /dev/null
+++ b/django_airavata/apps/workspace/views.py
@@ -0,0 +1,21 @@
+
+from django_airavata.apps.api.views import ProjectViewSet
+from rest_framework.renderers import JSONRenderer
+from django.conf import settings
+from django.contrib.auth.decorators import login_required
+from django.shortcuts import render, redirect
+
+import logging
+
+logger = logging.getLogger(__name__)
+
+
+@login_required
+def projects_list(request):
+
+ response = ProjectList().get(request)
+ projects_json = JSONRenderer().render(response.data)
+
+ return render(request, 'django_airavata_workspace/projects_list.html', {
+ 'projects_data': projects_json
+ })
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/middleware.py
----------------------------------------------------------------------
diff --git a/django_airavata/middleware.py b/django_airavata/middleware.py
new file mode 100644
index 0000000..8954d11
--- /dev/null
+++ b/django_airavata/middleware.py
@@ -0,0 +1,123 @@
+
+from apache.airavata.api import Airavata
+from apache.airavata.api.sharing import SharingRegistryService
+
+from thrift import Thrift
+from thrift.transport import TSSLSocket
+from thrift.transport import TSocket
+from thrift.transport import TTransport
+from thrift.protocol import TBinaryProtocol
+
+from django.conf import settings
+
+import logging
+
+logger = logging.getLogger(__name__)
+
+def get_unsecure_transport(hostname, port):
+ # Create a socket to the Airavata Server
+ transport = TSocket.TSocket(hostname, port)
+
+ # Use Buffered Protocol to speedup over raw sockets
+ transport = TTransport.TBufferedTransport(transport)
+ return transport
+
+def get_secure_transport(hostname, port):
+
+ # Create a socket to the Airavata Server
+ # TODO: validate server certificate
+ transport = TSSLSocket.TSSLSocket(hostname, port, validate=False)
+
+ # Use Buffered Protocol to speedup over raw sockets
+ transport = TTransport.TBufferedTransport(transport)
+ return transport
+
+def get_transport(hostname, port, secure=True):
+ if secure:
+ transport = get_secure_transport(hostname, port)
+ else:
+ transport = get_unsecure_transport(hostname, port)
+ return transport
+
+def get_airavata_client(transport):
+
+ # Airavata currently uses Binary Protocol
+ protocol = TBinaryProtocol.TBinaryProtocol(transport)
+
+ # Create a Airavata client to use the protocol encoder
+ client=Airavata.Client(protocol)
+ return client
+
+def get_sharing_client(transport):
+
+ protocol = TBinaryProtocol.TBinaryProtocol(transport)
+
+ return SharingRegistryService.Client(protocol)
+
+def airavata_client(get_response):
+ "Open and close Airavata client for each request"
+
+ def middleware(request):
+
+ # If user is logged in create an airavata api client for the request
+ if request.user.is_authenticated:
+ transport = get_transport(settings.AIRAVATA_API_HOST, settings.AIRAVATA_API_PORT, settings.AIRAVATA_API_SECURE)
+ airavata_client = get_airavata_client(transport)
+
+ try:
+ transport.open()
+ except Exception as e:
+ logger.exception("Failed to open thrift connection to API server")
+
+ if transport.isOpen():
+ request.airavata_client = airavata_client
+ else:
+ # if request.airavata_client is None, this will indicate to view
+ # code that the API server is down
+ request.airavata_client = None
+
+ response = get_response(request)
+
+ if transport.isOpen():
+ transport.close()
+ logger.debug("transport closed in middleware")
+ else:
+ response = get_response(request)
+
+ return response
+
+ return middleware
+
+def sharing_client(get_response):
+ "Open and close Sharing registry client for each request"
+
+ def middleware(request):
+
+ # If user is logged in create an airavata api client for the request
+ if request.user.is_authenticated:
+ transport = get_transport(settings.SHARING_API_HOST, settings.SHARING_API_PORT, settings.SHARING_API_SECURE)
+ sharing_client = get_sharing_client(transport)
+
+ try:
+ transport.open()
+ except Exception as e:
+ logger.exception("Failed to open thrift connection to Sharing Registry server")
+
+ if transport.isOpen():
+ request.sharing_client = sharing_client
+ else:
+ # if request.sharing_client is None, this will indicate to view
+ # code that the Sharing server is down
+ request.sharing_client = None
+
+ response = get_response(request)
+
+ if transport.isOpen():
+ transport.close()
+ logger.debug("transport closed in middleware")
+ else:
+ response = get_response(request)
+
+ return response
+
+ return middleware
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/resources/incommon_rsa_server_ca.pem
----------------------------------------------------------------------
diff --git a/django_airavata/resources/incommon_rsa_server_ca.pem b/django_airavata/resources/incommon_rsa_server_ca.pem
new file mode 100644
index 0000000..63c6bae
--- /dev/null
+++ b/django_airavata/resources/incommon_rsa_server_ca.pem
@@ -0,0 +1,68 @@
+-----BEGIN CERTIFICATE-----
+MIIF+TCCA+GgAwIBAgIQRyDQ+oVGGn4XoWQCkYRjdDANBgkqhkiG9w0BAQwFADCB
+iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
+cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV
+BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTQx
+MDA2MDAwMDAwWhcNMjQxMDA1MjM1OTU5WjB2MQswCQYDVQQGEwJVUzELMAkGA1UE
+CBMCTUkxEjAQBgNVBAcTCUFubiBBcmJvcjESMBAGA1UEChMJSW50ZXJuZXQyMREw
+DwYDVQQLEwhJbkNvbW1vbjEfMB0GA1UEAxMWSW5Db21tb24gUlNBIFNlcnZlciBD
+QTCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBAJwb8bsvf2MYFVFRVA+e
+xU5NEFj6MJsXKZDmMwysE1N8VJG06thum4ltuzM+j9INpun5uukNDBqeso7JcC7v
+HgV9lestjaKpTbOc5/MZNrun8XzmCB5hJ0R6lvSoNNviQsil2zfVtefkQnI/tBPP
+iwckRR6MkYNGuQmm/BijBgLsNI0yZpUn6uGX6Ns1oytW61fo8BBZ321wDGZq0GTl
+qKOYMa0dYtX6kuOaQ80tNfvZnjNbRX3EhigsZhLI2w8ZMA0/6fDqSl5AB8f2IHpT
+eIFken5FahZv9JNYyWL7KSd9oX8hzudPR9aKVuDjZvjs3YncJowZaDuNi+L7RyML
+fzcCAwEAAaOCAW4wggFqMB8GA1UdIwQYMBaAFFN5v1qqK0rPVIDh2JvAnfKyA2bL
+MB0GA1UdDgQWBBQeBaN3j2yW4luHS6a0hqxxAAznODAOBgNVHQ8BAf8EBAMCAYYw
+EgYDVR0TAQH/BAgwBgEB/wIBADAdBgNVHSUEFjAUBggrBgEFBQcDAQYIKwYBBQUH
+AwIwGwYDVR0gBBQwEjAGBgRVHSAAMAgGBmeBDAECAjBQBgNVHR8ESTBHMEWgQ6BB
+hj9odHRwOi8vY3JsLnVzZXJ0cnVzdC5jb20vVVNFUlRydXN0UlNBQ2VydGlmaWNh
+dGlvbkF1dGhvcml0eS5jcmwwdgYIKwYBBQUHAQEEajBoMD8GCCsGAQUFBzAChjNo
+dHRwOi8vY3J0LnVzZXJ0cnVzdC5jb20vVVNFUlRydXN0UlNBQWRkVHJ1c3RDQS5j
+cnQwJQYIKwYBBQUHMAGGGWh0dHA6Ly9vY3NwLnVzZXJ0cnVzdC5jb20wDQYJKoZI
+hvcNAQEMBQADggIBAC0RBjjW29dYaK+qOGcXjeIT16MUJNkGE+vrkS/fT2ctyNMU
+11ZlUp5uH5gIjppIG8GLWZqjV5vbhvhZQPwZsHURKsISNrqOcooGTie3jVgU0W+0
++Wj8mN2knCVANt69F2YrA394gbGAdJ5fOrQmL2pIhDY0jqco74fzYefbZ/VS29fR
+5jBxu4uj1P+5ZImem4Gbj1e4ZEzVBhmO55GFfBjRidj26h1oFBHZ7heDH1Bjzw72
+hipu47Gkyfr2NEx3KoCGMLCj3Btx7ASn5Ji8FoU+hCazwOU1VX55mKPU1I2250Lo
+RCASN18JyfsD5PVldJbtyrmz9gn/TKbRXTr80U2q5JhyvjhLf4lOJo/UzL5WCXED
+Smyj4jWG3R7Z8TED9xNNCxGBMXnMete+3PvzdhssvbORDwBZByogQ9xL2LUZFI/i
+eoQp0UM/L8zfP527vWjEzuDN5xwxMnhi+vCToh7J159o5ah29mP+aJnvujbXEnGa
+nrNxHzu+AGOePV8hwrGGG7hOIcPDQwkuYwzN/xT29iLp/cqf9ZhEtkGcQcIImH3b
+oJ8ifsCnSbu0GB9L06Yqh7lcyvKDTEADslIaeSEINxhO2Y1fmcYFX/Fqrrp1WnhH
+OjplXuXE0OPa0utaKC25Aplgom88L2Z8mEWcyfoB7zKOfD759AN7JKZWCYwk
+-----END CERTIFICATE-----
+-----BEGIN CERTIFICATE-----
+MIIF3jCCA8agAwIBAgIQAf1tMPyjylGoG7xkDjUDLTANBgkqhkiG9w0BAQwFADCB
+iDELMAkGA1UEBhMCVVMxEzARBgNVBAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0pl
+cnNleSBDaXR5MR4wHAYDVQQKExVUaGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNV
+BAMTJVVTRVJUcnVzdCBSU0EgQ2VydGlmaWNhdGlvbiBBdXRob3JpdHkwHhcNMTAw
+MjAxMDAwMDAwWhcNMzgwMTE4MjM1OTU5WjCBiDELMAkGA1UEBhMCVVMxEzARBgNV
+BAgTCk5ldyBKZXJzZXkxFDASBgNVBAcTC0plcnNleSBDaXR5MR4wHAYDVQQKExVU
+aGUgVVNFUlRSVVNUIE5ldHdvcmsxLjAsBgNVBAMTJVVTRVJUcnVzdCBSU0EgQ2Vy
+dGlmaWNhdGlvbiBBdXRob3JpdHkwggIiMA0GCSqGSIb3DQEBAQUAA4ICDwAwggIK
+AoICAQCAEmUXNg7D2wiz0KxXDXbtzSfTTK1Qg2HiqiBNCS1kCdzOiZ/MPans9s/B
+3PHTsdZ7NygRK0faOca8Ohm0X6a9fZ2jY0K2dvKpOyuR+OJv0OwWIJAJPuLodMkY
+tJHUYmTbf6MG8YgYapAiPLz+E/CHFHv25B+O1ORRxhFnRghRy4YUVD+8M/5+bJz/
+Fp0YvVGONaanZshyZ9shZrHUm3gDwFA66Mzw3LyeTP6vBZY1H1dat//O+T23LLb2
+VN3I5xI6Ta5MirdcmrS3ID3KfyI0rn47aGYBROcBTkZTmzNg95S+UzeQc0PzMsNT
+79uq/nROacdrjGCT3sTHDN/hMq7MkztReJVni+49Vv4M0GkPGw/zJSZrM233bkf6
+c0Plfg6lZrEpfDKEY1WJxA3Bk1QwGROs0303p+tdOmw1XNtB1xLaqUkL39iAigmT
+Yo61Zs8liM2EuLE/pDkP2QKe6xJMlXzzawWpXhaDzLhn4ugTncxbgtNMs+1b/97l
+c6wjOy0AvzVVdAlJ2ElYGn+SNuZRkg7zJn0cTRe8yexDJtC/QV9AqURE9JnnV4ee
+UB9XVKg+/XRjL7FQZQnmWEIuQxpMtPAlR1n6BB6T1CZGSlCBst6+eLf8ZxXhyVeE
+Hg9j1uliutZfVS7qXMYoCAQlObgOK6nyTJccBz8NUvXt7y+CDwIDAQABo0IwQDAd
+BgNVHQ4EFgQUU3m/WqorSs9UgOHYm8Cd8rIDZsswDgYDVR0PAQH/BAQDAgEGMA8G
+A1UdEwEB/wQFMAMBAf8wDQYJKoZIhvcNAQEMBQADggIBAFzUfA3P9wF9QZllDHPF
+Up/L+M+ZBn8b2kMVn54CVVeWFPFSPCeHlCjtHzoBN6J2/FNQwISbxmtOuowhT6KO
+VWKR82kV2LyI48SqC/3vqOlLVSoGIG1VeCkZ7l8wXEskEVX/JJpuXior7gtNn3/3
+ATiUFJVDBwn7YKnuHKsSjKCaXqeYalltiz8I+8jRRa8YFWSQEg9zKC7F4iRO/Fjs
+8PRF/iKz6y+O0tlFYQXBl2+odnKPi4w2r78NBc5xjeambx9spnFixdjQg3IM8WcR
+iQycE0xyNN+81XHfqnHd4blsjDwSXWXavVcStkNr/+XeTWYRUc+ZruwXtuhxkYze
+Sf7dNXGiFSeUHM9h4ya7b6NnJSFd5t0dCy5oGzuCr+yDZ4XUmFF0sbmZgIn/f3gZ
+XHlKYC6SQK5MNyosycdiyA5d9zZbyuAlJQG03RoHnHcAP9Dc1ew91Pq7P8yF1m9/
+qS3fuQL39ZeatTXaw2ewh0qpKJ4jjv9cJ2vhsE/zB+4ALtRZh8tSQZXq9EfX7mRB
+VXyNWQKV3WKdwrnuWih0hKWbt5DHDAff9Yk2dDLWKMGwsAvgnEzDHNb842m1R0aB
+L6KCq9NjRHDEjf8tM7qtj3u1cIiuPhnPQCjY/MiQu12ZIvVS5ljFH4gxQ+6IHdfG
+jjxDah2nGN59PRbxYvnKkKj9
+-----END CERTIFICATE-----
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/settings.py
----------------------------------------------------------------------
diff --git a/django_airavata/settings.py b/django_airavata/settings.py
new file mode 100644
index 0000000..cca6da1
--- /dev/null
+++ b/django_airavata/settings.py
@@ -0,0 +1,159 @@
+"""
+Django settings for django_airavata_gateway project.
+
+Generated by 'django-admin startproject' using Django 1.10.5.
+
+For more information on this file, see
+https://docs.djangoproject.com/en/1.10/topics/settings/
+
+For the full list of settings and their values, see
+https://docs.djangoproject.com/en/1.10/ref/settings/
+"""
+
+import os
+
+# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+
+# Quick-start development settings - unsuitable for production
+# See https://docs.djangoproject.com/en/1.10/howto/deployment/checklist/
+
+# SECURITY WARNING: keep the secret key used in production secret!
+SECRET_KEY = 'bots0)m91u_i4gpw+103o%2jn#j57wjh7s@9$x*27_4^*jyku4'
+
+# SECURITY WARNING: don't run with debug turned on in production!
+DEBUG = True
+INTERNAL_IPS = ["127.0.0.1"]
+
+ALLOWED_HOSTS = []
+
+
+# Application definition
+
+INSTALLED_APPS = [
+ 'django_airavata.apps.admin.apps.AdminConfig',
+ 'django.contrib.auth',
+ 'django.contrib.contenttypes',
+ 'django.contrib.sessions',
+ 'django.contrib.messages',
+ 'django.contrib.staticfiles',
+ 'django_airavata.apps.auth.apps.AuthConfig',
+ 'django_airavata.apps.workspace.apps.WorkspaceConfig',
+ 'rest_framework',
+ 'django_airavata.apps.api.apps.ApiConfig',
+ 'django_airavata.apps.groups.apps.GroupsConfig',
+]
+
+MIDDLEWARE = [
+ 'django.middleware.security.SecurityMiddleware',
+ 'django.contrib.sessions.middleware.SessionMiddleware',
+ 'django.middleware.common.CommonMiddleware',
+ 'django.middleware.csrf.CsrfViewMiddleware',
+ 'django.contrib.auth.middleware.AuthenticationMiddleware',
+ 'django.contrib.messages.middleware.MessageMiddleware',
+ 'django.middleware.clickjacking.XFrameOptionsMiddleware',
+ 'django_airavata.apps.auth.middleware.authz_token_middleware',
+ 'django_airavata.middleware.airavata_client',
+ 'django_airavata.middleware.sharing_client',
+]
+
+ROOT_URLCONF = 'django_airavata.urls'
+
+TEMPLATES = [
+ {
+ 'BACKEND': 'django.template.backends.django.DjangoTemplates',
+ 'DIRS': [os.path.join(BASE_DIR, "django_airavata", "templates")],
+ 'APP_DIRS': True,
+ 'OPTIONS': {
+ 'context_processors': [
+ 'django.template.context_processors.debug',
+ 'django.template.context_processors.request',
+ 'django.contrib.auth.context_processors.auth',
+ 'django.contrib.messages.context_processors.messages',
+ ],
+ },
+ },
+]
+
+WSGI_APPLICATION = 'django_airavata.wsgi.application'
+
+
+# Database
+# https://docs.djangoproject.com/en/1.10/ref/settings/#databases
+
+DATABASES = {
+ 'default': {
+ 'ENGINE': 'django.db.backends.sqlite3',
+ 'NAME': os.path.join(BASE_DIR, 'db.sqlite3'),
+ }
+}
+
+
+# Password validation
+# https://docs.djangoproject.com/en/1.10/ref/settings/#auth-password-validators
+
+AUTH_PASSWORD_VALIDATORS = [
+ {
+ 'NAME': 'django.contrib.auth.password_validation.UserAttributeSimilarityValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.MinimumLengthValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.CommonPasswordValidator',
+ },
+ {
+ 'NAME': 'django.contrib.auth.password_validation.NumericPasswordValidator',
+ },
+]
+
+
+# Internationalization
+# https://docs.djangoproject.com/en/1.10/topics/i18n/
+
+LANGUAGE_CODE = 'en-us'
+
+TIME_ZONE = 'UTC'
+
+USE_I18N = True
+
+USE_L10N = True
+
+USE_TZ = True
+
+
+# Static files (CSS, JavaScript, Images)
+# https://docs.djangoproject.com/en/1.10/howto/static-files/
+
+STATIC_URL = '/static/'
+STATICFILES_DIRS = [os.path.join(BASE_DIR, "django_airavata", "static")]
+
+AUTHENTICATION_BACKENDS = [
+ 'django_airavata.apps.auth.backends.KeycloakBackend'
+]
+
+LOGIN_URL = 'django_airavata_auth:login'
+LOGIN_REDIRECT_URL = 'home'
+LOGOUT_REDIRECT_URL = 'home'
+
+LOGGING = {
+ 'version': 1,
+ 'handlers': {
+ 'console': {
+ 'class': 'logging.StreamHandler',
+ },
+ },
+ 'loggers': {
+ 'django_airavata': {
+ 'handlers': ['console'],
+ 'level': 'DEBUG' if DEBUG else 'INFO'
+ },
+ },
+}
+
+# Allow all settings to be overridden by settings_local.py file
+try:
+ from django_airavata.settings_local import *
+except ImportError:
+ pass
http://git-wip-us.apache.org/repos/asf/airavata-django-portal/blob/d8d7c37a/django_airavata/settings_local.py.sample
----------------------------------------------------------------------
diff --git a/django_airavata/settings_local.py.sample b/django_airavata/settings_local.py.sample
new file mode 100644
index 0000000..b86ef0b
--- /dev/null
+++ b/django_airavata/settings_local.py.sample
@@ -0,0 +1,34 @@
+"""
+Override default Django settings for a particular instance.
+
+Copy this file to settings_local.py and modify as appropriate. This file will
+be imported into settings.py last of all so settings in this file override any
+defaults specified in settings.py.
+"""
+
+import os
+
+# Build paths inside the project like this: os.path.join(BASE_DIR, ...)
+BASE_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
+
+# Keycloak Configuration
+KEYCLOAK_CLIENT_ID = '...'
+KEYCLOAK_CLIENT_SECRET = '...'
+KEYCLOAK_AUTHORIZE_URL = '...'
+KEYCLOAK_TOKEN_URL = '...'
+KEYCLOAK_USERINFO_URL = '...'
+KEYCLOAK_LOGOUT_URL = '...'
+# Optional: specify if using self-signed certificate or certificate from unrecognized CA
+#KEYCLOAK_CA_CERTFILE = os.path.join(BASE_DIR, "django_airavata", "resources", "incommon_rsa_server_ca.pem")
+KEYCLOAK_VERIFY_SSL = True
+
+# Airavata API Configuration
+GATEWAY_ID = 'default'
+AIRAVATA_API_HOST = 'localhost'
+AIRAVATA_API_PORT = 8930
+AIRAVATA_API_SECURE = False
+
+# Sharing API Configuration
+SHARING_API_HOST = 'localhost'
+SHARING_API_PORT = 7878
+SHARING_API_SECURE = False