Merge branch 'onelab' of ssh://git.onelab.eu/git/myslice into onelab
authorLoic Baron <loic.baron@lip6.fr>
Thu, 15 Jan 2015 10:09:28 +0000 (11:09 +0100)
committerLoic Baron <loic.baron@lip6.fr>
Thu, 15 Jan 2015 10:09:28 +0000 (11:09 +0100)
17 files changed:
README
myslice/urls.py
portal/loginwidget.py [new file with mode: 0644]
portal/reputationview.py
portal/static/css/smartfire.css [new file with mode: 0644]
portal/static/img/SmartFIRE_logo.png [new file with mode: 0644]
portal/templates/loginwidget.html [new file with mode: 0644]
portal/templates/registration_view.html
portal/templates/reputation.html
portal/templates/smartfire/smartfire_account-view.html [new file with mode: 0644]
portal/templates/smartfire/smartfire_footer.html [new file with mode: 0644]
portal/templates/smartfire/smartfire_home-view.html [new file with mode: 0644]
portal/templates/smartfire/smartfire_institution.html [new file with mode: 0644]
portal/templates/smartfire/smartfire_management-tab-requests.html [new file with mode: 0644]
portal/templates/smartfire/smartfire_slicerequest_view.html [new file with mode: 0644]
portal/templates/smartfire/smartfire_widget-login-user.html [new file with mode: 0644]
portal/templates/smartfire/smartfire_widget-topmenu.html [new file with mode: 0644]

diff --git a/README b/README
index 0eda79a..8c6e7ef 100644 (file)
--- a/README
+++ b/README
@@ -9,9 +9,9 @@ See the devel/ subdir for more devel-oriented doc.
 *  REQUIREMENTS  is to have python + django (1.5.2) installed django
 ** should be straightforward
 ** see devel/django-install.txt in case of trouble
-$ apt-get install python-django
-$ apt-get install python-django-south
 $ apt-get install python-pip or sudo easy_install pip==1.4.1
+$ pip install django=="1.5.2
+$ apt-get install python-django-south
 $ pip install requests
 $ pip install djangorestframework
 $ pip install django-celery
index d09f480..c815148 100644 (file)
@@ -16,6 +16,7 @@ import portal.platformsview
 import portal.dashboardview
 import portal.homeview
 import portal.newsview
+import portal.loginwidget
 
 from portal.about                   import AboutView
 from portal.registrationview        import RegistrationView
@@ -99,6 +100,8 @@ urls = [
     #(r'^view/?', include('view.urls')),
     #(r'^list/slices', 'view.list.slices')
     #
+    # Login widget to be used in an iframe
+    (r'^loginwidget/?$', portal.loginwidget.LoginWidget.as_view()),
     #
     # Portal
     (r'^news/?$', portal.newsview.NewsView.as_view()),
diff --git a/portal/loginwidget.py b/portal/loginwidget.py
new file mode 100644 (file)
index 0000000..5270473
--- /dev/null
@@ -0,0 +1,12 @@
+from django.core.context_processors import csrf
+from django.shortcuts               import render_to_response
+
+from django.views.generic.base      import TemplateView
+from unfold.loginrequired           import FreeAccessView
+
+class LoginWidget(FreeAccessView):
+    
+    def get(self, request):
+        env = {}
+        env.update(csrf(request))
+        return render_to_response("loginwidget.html", env)
index 40f8506..f160d7d 100644 (file)
@@ -16,9 +16,12 @@ import hashlib
 import datetime\r
 import urllib2\r
 import ast\r
+import time\r
+\r
 from django.views.decorators.csrf import csrf_exempt\r
 from django.http                  import *\r
 \r
+\r
 def response_mimetype(request):\r
         \r
     if "application/json" in request.META['HTTP_ACCEPT']:\r
@@ -57,24 +60,26 @@ def timestamp_to_unix(timest):
 def slice_to_exp(slices_users):\r
     experiments = {}\r
     testbeds = {}\r
+    wildcard_testbeds = {}\r
+   \r
     \r
-    \r
-    for slice in slices_users:\r
+    for slice in slices_users:  \r
         nodes={}\r
         leases = slice['lease']\r
-        if leases is not None:\r
+         \r
+        if leases is not None and leases:\r
             for lease in leases:\r
                 resource = lease['resource']\r
                 start_t = lease['start_time']\r
                 end_t = lease['end_time']\r
-                #node = lease['resource']\r
                 \r
                 testbed_start = resource.index('IDN+')+4\r
                 testbed_end = resource.index('+node+')\r
                 \r
                 testbed = resource[testbed_start:testbed_end]\r
                 node = resource[testbed_end+6:]\r
-                \r
+                if 'omf:nitos' in testbed:\r
+                    testbed = 'omf:nitos'\r
                 if testbed in testbeds:\r
                     if node not in testbeds[testbed]:\r
                         testbeds[testbed].append(node)\r
@@ -93,18 +98,97 @@ def slice_to_exp(slices_users):
                                 f=1\r
                         if f==0:\r
                             nodes[node][str(start_t)]={'start_t':start_t, 'nodes':node, 'end_t':end_t}\r
+\r
+            ######### FOR PLE LIKE start ##################\r
+            for resource in slice['resource']:\r
+                testbed_start = resource.index('IDN+')+4\r
+                testbed_end = resource.index('+node+')\r
+                tb = resource[testbed_start:testbed_end]\r
+                node = resource[testbed_end+6:]\r
+                if 'ple:' in tb:\r
+                    tb = 'ple'\r
+                if 'omf:nitos' in tb:\r
+                    tb = 'omf:nitos'\r
+                if tb not in testbeds:\r
+                    try:\r
+                        if node not in wildcard_testbeds[slice['slice_hrn']][tb]:\r
+                            wildcard_testbeds[slice['slice_hrn']][tb].append([node])\r
+                    except:\r
+                        try:\r
+                            wildcard_testbeds[slice['slice_hrn']][tb] = [node]\r
+                        except:\r
+                            wildcard_testbeds[slice['slice_hrn']]={tb:[node]}\r
+                    \r
+            \r
+        else:\r
+            s = slice['slice_last_updated']\r
+            #s_time = int(time.mktime(datetime.datetime.strptime(s, "%Y%m%dT%H:%M:%Ss").timetuple()))\r
+            s_time = time.mktime(s.timetuple())                \r
+                \r
+            if slice['resource'] is not None:\r
+                                    \r
+                for resource in slice['resource']:\r
+                    testbed_start = resource.index('IDN+')+4\r
+                    testbed_end = resource.index('+node+')\r
+                    tb = resource[testbed_start:testbed_end]\r
+                    if 'ple:' in tb:\r
+                        tb = 'ple'\r
+                    if 'omf:nitos' in tb:\r
+                        tb = 'omf:nitos'\r
+                    node = resource[testbed_end+6:]\r
+                    \r
+                    if testbed in testbeds:\r
+                        if node not in testbeds[testbed]:\r
+                            testbeds[testbed].append(node)\r
+                    else:\r
+                        testbeds[testbed] = [node]       \r
+                    \r
+                    if not node in nodes:  \r
+                        #nodes[node] = {str(start_t):{'start_t':s_time, 'nodes':node, 'end_t':int(time.time())}} \r
+                        nodes[node] = {str(start_t):{'start_t':s_time, 'nodes':node, 'end_t':s_time}}    \r
+            ######### FOR PLE LIKE end ##################\r
\r
                         \r
         #group grouped nodes in experiments\r
         for n in nodes:\r
             for exp in nodes[n]:\r
-                key = str(exp) + str(nodes[n][exp]['end_t'])\r
+                key = str(exp) + str(nodes[n][exp]['end_t']) + slice['slice_hrn']\r
                 \r
                 if key not in experiments:\r
                     experiments[key]={'slice_hrn':slice['slice_hrn'], \\r
                                       'start':nodes[n][exp]['start_t'], 'end':nodes[n][exp]['end_t'], 'nodes':[nodes[n][exp]['nodes']]}   \r
+                    \r
+                    \r
+                    ######### FOR PLE LIKE start ##################\r
+                    for item in wildcard_testbeds:\r
+                        if item == experiments[key]['slice_hrn']:\r
+                            for testbed in wildcard_testbeds[item]:\r
+                                \r
+                                if testbed not in testbeds:\r
+                                    testbeds[testbed] = wildcard_testbeds[item][testbed] \r
+                                \r
+                                for n in wildcard_testbeds[item][testbed]:\r
+                                    if n not in experiments[key]['nodes']:\r
+                                        experiments[key]['nodes'].append(n)                                           \r
+                    ######### FOR PLE LIKE end ##################\r
+                    \r
                 elif nodes[n][exp]['end_t'] == experiments[key]['end']:\r
                     experiments[key]['nodes'].append(nodes[n][exp]['nodes'])\r
                     \r
+                    \r
+                    ######### FOR PLE LIKE start ##################\r
+                    for item in wildcard_testbeds:\r
+                        if item == experiments[key]['slice_hrn']:\r
+                            for testbed in wildcard_testbeds[item]:\r
+                                \r
+                                if testbed not in testbeds:\r
+                                    testbeds[testbed] = wildcard_testbeds[item][testbed] \r
+                                \r
+                                for n in wildcard_testbeds[item][testbed]:\r
+                                    if n not in experiments[key]['nodes']:\r
+                                        experiments[key]['nodes'].append(n)                       \r
+                    ######### FOR PLE LIKE end ##################\r
+                    \r
     return (experiments,testbeds)\r
    \r
 class ReputationView (LoginRequiredAutoLogoutView, ThemeView):\r
@@ -120,10 +204,7 @@ class ReputationView (LoginRequiredAutoLogoutView, ThemeView):
         env = self.default_env()\r
         env['theme'] = self.theme\r
                 \r
-        return render_to_response(self.template, env, context_instance=RequestContext(request))\r
-\r
-\r
-    \r
+        return render_to_response(self.template, env, context_instance=RequestContext(request))    \r
     \r
     def get (self, request, state=None):\r
         env = self.default_env()\r
@@ -158,13 +239,13 @@ class ReputationView (LoginRequiredAutoLogoutView, ThemeView):
         slices_users = []\r
         \r
         #get slices\r
-        userslice_query = Query().get('slice').select('slice_urn', 'slice_hrn', 'users', 'resource', 'lease')\r
+        userslice_query = Query().get('slice').select('slice_urn', 'slice_hrn', 'users', 'resource', 'lease', 'slice_last_updated')\r
         slice_details = execute_query(self.request, userslice_query)\r
         \r
         #get local users\r
         local_user_query  = Query().get('local:user').select('email','status','config')\r
         local_user_details = execute_admin_query(self.request, local_user_query)\r
-        \r
+                   \r
         #get users - create dict[email]=hrn\r
         user_query  = Query().get('user').select('user_hrn','user_urn','user_email')\r
         user_details = execute_admin_query(self.request, user_query)\r
@@ -178,19 +259,18 @@ class ReputationView (LoginRequiredAutoLogoutView, ThemeView):
         \r
         #get a list of all the slices for the logged in user\r
         testbeds = []\r
-\r
+        #env['slices_users'] = json.dumps(slice_details, ensure_ascii=False)\r
         for slice in slice_details:\r
             \r
             if users_hrn[cur_username] in slice['users']:\r
                 slices_users.append({'slice_hrn':slice['slice_hrn'], 'user':cur_username, 'user_hrn':users_hrn[cur_username] \\r
-                                     , 'resource':slice['resource'], 'lease':slice['lease'] })  \r
+                                     , 'resource':slice['resource'], 'lease':slice['lease'], 'slice_last_updated':slice['slice_last_updated']  })  \r
                 \r
                              \r
-        env['slices_users'] = slices_users  ### For logging\r
-       \r
+        #env['slices_users'] = slices_users  ### For logging\r
         #####create slicelist for template & JSON\r
         experiments,testbeds =  slice_to_exp(slices_users)\r
-    \r
+            \r
         all_exp = []\r
         iddata = []\r
                           \r
@@ -217,9 +297,10 @@ class ReputationView (LoginRequiredAutoLogoutView, ThemeView):
             \r
             iddata.append(tempid)\r
             all_exp.append(experiment)\r
-        \r
-        \r
+            env['logging_test'] = json.dumps(all_exp, ensure_ascii=False)\r
+            env['slices_users'] = json.dumps(all_exp, ensure_ascii=False)\r
         ###### Check which experiments have not been rated yet. Pop from all_exp any experiment that has already been rated\r
+        \r
         unrated_exp = json_to_rest('http://survivor.lab.netmode.ntua.gr:4567/reputation/qid', iddata)    \r
         \r
         for item in all_exp:\r
@@ -228,8 +309,6 @@ class ReputationView (LoginRequiredAutoLogoutView, ThemeView):
             else:\r
                 all_exp.pop(all_exp.index(item))\r
 \r
-\r
-\r
         ###### Get Reputation values from Reputation DB\r
         reps = json_to_rest('http://survivor.lab.netmode.ntua.gr:4567/reputation/showrep', "a")\r
         #env['logging_test'] = reps    \r
@@ -262,7 +341,7 @@ class ReputationView (LoginRequiredAutoLogoutView, ThemeView):
                     testbed['services'].append('N/A')\r
                 \r
         ###### Pass variables to template\r
-        env['logging_test'] = json.dumps(all_exp, ensure_ascii=False)\r
+        #env['logging_test'] = json.dumps(all_exp, ensure_ascii=False)\r
         env['serv_per_tb'] = json.dumps(serv_per_tb, ensure_ascii=False)\r
         env['reputation'] = reps\r
         env['rep_serv'] = services\r
diff --git a/portal/static/css/smartfire.css b/portal/static/css/smartfire.css
new file mode 100644 (file)
index 0000000..190924e
--- /dev/null
@@ -0,0 +1,820 @@
+@import url("../fonts/opensans_bold_macroman/stylesheet.css");
+
+html { height: 100% }
+
+body {
+    background-color:white;
+    color:black;
+    margin:0;
+    padding:0;
+    height: 100%;
+    letter-spacing:0.3px;
+}
+a, a:active, a:focus {
+    outline: 0;
+    text-decoration:none;
+    color:#760073;
+}
+a:hover {
+    color:#0D0049;
+}
+
+a.current {
+    text-decoration:underline;
+    color:#333333;
+}
+p.command {
+    padding:15px;
+    margin:15px 0;
+    color:#890000;
+    background-color:#E0E0E0; 
+    font-family:Courier, monospace;
+}
+h1 {
+    border-bottom:1px solid #DDDDDD;
+    padding:0 0 0 0;
+    margin:15px 0 15px 0;
+    font-size:14pt;
+}
+h1 img {
+    vertical-align:middle;
+    margin-bottom:4px;
+    margin-right:10px;
+}
+h2 {
+    margin:0 0 15px 0;
+    font-size:14pt;
+    color:#333333;
+}
+h3 {
+    margin:0 0 5px 0;
+    font-size:13pt;
+    color:#201E62;
+}
+h4 {
+    margin:0 0 5px 0;
+    font-size:12pt;
+    color:#333333;
+}
+span.subtitle {
+    color:#454545;
+    font-size:9pt;
+    font-weight:normal;
+    text-transform:uppercase;
+}
+span.small {
+    font-size:9pt;
+}
+span.gray {
+    color:gray;
+}
+span.type {
+    color:#201E62;
+    font-weight:bold;
+    font-size:9pt;
+}
+span.htitle {
+    color:#454545;
+    font-size:9pt;
+    font-weight:normal;
+}
+span.version {
+    font-size:8pt;
+    color:#888888;
+}
+input[type=text], input[type=password], input[type=email], input[type=tel], input[type=number], select, option {
+    min-width:260px;
+    padding:6px;
+    border:1pt solid #22606D;
+    vertical-align:bottom;
+    border-radius:0;
+}
+
+textarea {
+    padding:6px;
+    border:1pt solid #22606D !important;
+    border-radius:0 !important;
+}
+
+span.label {
+    font-size:11pt;
+    color:gray;
+    font-weight:normal;
+    padding:0;
+}
+div.el {
+    padding-bottom:15px;
+}
+div.breadcrumbs {
+    margin:15px 0;
+    color:gray;
+    font-size:10pt;
+}
+div.breadcrumbs a {
+    color:gray;
+}
+div.breadcrumbs a:hover {
+    text-decoration:underline;
+}
+.tab-pane {
+    padding-top:15px;
+}
+/* buttons */
+button.btn, input.btn {
+    padding:6px 10px;
+    border-radius:5px;
+    font-size:10pt;
+    font-weight:normal;
+}
+button.btn span.glyphicon {
+    margin-right:6px;
+}
+button.btn-default {
+    border-bottom:3px solid #cccccc;
+}
+button.btn-default:hover {
+    background-color:white;
+    border:1px solid #ADADAD;
+    border-bottom:3px solid #ADADAD;
+}
+button.btn-default:active {
+    background-color:white;
+    border:1px solid #ADADAD;
+    border-bottom:1px solid #ADADAD;
+    margin-top:2px;
+    box-shadow:none;
+}
+button.btn-primary {
+    border-bottom:3px solid #3071A9;
+}
+button.btn-primary:hover {
+    box-shadow:none;
+    background-color:#428bca;
+    border:1px solid #357ebd;
+    border-bottom:3px solid #3071A9;
+}
+button.btn-primary:active {
+    box-shadow:none;
+    border-bottom:1px solid #3071A9;
+    margin-top:2px;
+}
+button.btn-danger {
+    border-bottom:3px solid #A13F3A;
+}
+button.btn-danger:hover {
+    box-shadow:none;
+    background-color:#d9534f;
+    border:1px solid #d43f3a;
+    border-bottom:3px solid #A13F3A;
+}
+button.btn-danger:active {
+    border:1px solid #d43f3a;
+    box-shadow:none;
+    margin-top:2px;
+}
+button.btn-onelab, input.btn-onelab {
+    border:0;
+    border-bottom:3px solid #760073;
+    background-color:#302562;
+    color:white;
+}
+button.btn-onelab:hover, input.btn-onelab:hover {
+    border:0;
+    border-bottom:3px solid #760073;
+    background-color:#302562;
+    color:white;
+}
+button.btn-onelab:active, input.btn-onelab:active {
+    box-shadow:none;
+    border-bottom:1px solid #760073;
+    margin-top:2px;
+}
+
+.container-resource button {
+    padding:2px 4px;
+    border-radius:3px;
+    font-size:9pt;
+    font-weight:normal;
+}
+.container-resource select,.container-resource option, .container-resource input {
+    padding:2px 4px;
+    font-size:9pt;
+}
+.badge {
+    font-size:9pt;
+    margin-left:4px;
+}
+/***** Notifications *****/
+.warning {
+    border: 1px solid red;
+    margin: 20px 60px;
+    padding: 10px 20px;
+    color: red;
+    background-color: #f2dbdb;
+    text-align: center;
+}
+
+/* HOME DASHBOARD */
+div#home-dashboard {
+    color:black;
+    margin:0 auto 25px auto;
+}
+div#home-dashboard table {
+    margin:25px;
+    width:100%;
+}
+div#home-dashboard table td {
+    text-align:center;
+    padding:15px 0;
+    width:33%;
+}
+div#home-dashboard table tr:first-child td {
+    font-size:12pt;
+    font-weight:bold;
+    color:#270A5A;
+}
+div#home-dashboard table tr:last-child td {
+    vertical-align:top;
+    padding:25px 0;
+}
+div#home-dashboard table tr:last-child td.logged-in {
+    border-right:1px solid #DDDDDD;
+    padding:25px;
+}
+div#home-dashboard table tr:last-child td.support {
+    border-left:1px solid #DDDDDD;
+    padding:25px;
+}
+div#home-dashboard table tr:last-child td:first-child {
+}
+div#home-dashboard table tr:last-child td:last-child {
+    border-right:0;
+}
+div#home-dashboard table tr:last-child td.logged-in div {
+    text-align:left;
+    padding:25px 0;
+}
+div#home-dashboard table tr:last-child td.support div {
+    text-align:left;
+    padding:25px 0;
+}
+div#home-dashboard div.login-widget {
+    padding:20px;
+}
+div#home-dashboard table td.support {
+}
+div#home-dashboard table td.support a {
+}
+div#home-dashboard table td.support a:hover {
+    text-decoration:none;
+}
+
+div#home-dashboard div#manager {
+    display:none;
+}
+
+div#home-dashboard div#home-slice-list {
+    margin:25px 0;
+    padding:0 25px;
+    text-align:left;
+}
+div#home-dashboard div#home-slice-list ul {
+    list-style: none;
+    padding:0;
+    margin:0;
+}
+div#home-dashboard div#home-slice-list li {
+    
+}
+
+/**/
+
+/**/
+/* WELL */
+div.well {
+}
+/**/
+/* TABLE */
+table.table {
+    margin:0;
+}
+table.table thead {
+    padding:0;
+}
+table.table tbody {
+    padding:0;
+}
+table.table tr {
+    padding:0;
+}
+table.table td {
+    padding:0;
+}
+/* INSTITUTION */
+div#institution {
+    color:black;
+}
+.form-hint {
+    font-size:11pt;
+    font-style:italic;
+    color:gray;
+}
+
+
+.form-hint {
+    font-size:11pt;
+    font-style:italic;
+    color:gray;
+}
+
+
+
+/* TICKET REQUEST */
+div#ticket-request {
+    color:black;
+}
+.form-hint {
+    font-size:11pt;
+    font-style:italic;
+    color:gray;
+}
+div#ticket-request p {
+    margin:20px 0;
+}
+
+ul.nav-tabs {
+    margin:0 0 15px 0;
+}
+ul.nav-tabs ul {}
+ul.nav-tabs li {}
+
+ul.nav-section li a {
+    color:black;
+    border-bottom:0;
+}
+ul.nav-section li:first-child {
+    padding:0;
+}
+ul.nav-section li:first-child a {
+}
+ul.nav-section li:first-child.active a {
+}
+
+ul.nav-resources {
+    margin:15px 0;
+}
+ul.nav-resources a {
+    padding: 4px 10px 5px 10px;
+}
+
+/* SLICE VIEW */
+div.container-resource, div.container-slice {
+    padding-right:15px;
+    padding-left:15px;
+}
+.table th {
+    border-top:0 !important;
+}
+div#slice-view {
+    margin:0;
+}
+div.list-group-item {
+    border:0;
+    -moz-border-radius: 0;
+    border-radius: 0;
+    background-color:white;
+    font-weight:bold;
+    padding-left:0;
+}
+a.list-group-item {
+    -moz-border-radius: 0;
+    border-radius: 0;
+    border:0;
+    background-color:white;
+    padding:3px 2px 3px 10px;
+    border-left:2pt white solid;
+}
+a.list-group-item.active, a.list-group-item.active:hover, a.list-group-item.active:focus {
+    -moz-border-radius: 0;
+    border-radius: 0;
+    font-weight: bold;
+    color:black;
+    background-color:#F5F5F5;
+    border-left:2pt blue solid;
+}
+
+a.list-group-item:hover {
+    -moz-border-radius: 0;
+    border-radius: 0;
+    border-left:2pt blue solid;
+}
+a.list-group-item p.list-group-item-text {
+    -moz-border-radius: 0;
+    border-radius: 0;
+    font-size:9pt;
+    font-style:italic;
+    font-weight: normal;
+    color: black !important;
+}
+
+span.sl-resources {
+    font-size:9pt;
+    color:gray;
+}
+a.sl-resources, a.sl-resources:hover {
+    font-size:9pt;
+    border:0;
+    padding:2px 4px;
+    -moz-border-radius: 4px;
+    border-radius: 4px;
+    width:105px;
+    margin-left:4px;
+    margin-bottom:8px;
+    text-align: center;
+}
+a.sl-resources.active, a.sl-resources.active:hover, a.sl-resources.active:focus {
+    border:0;
+    -moz-border-radius: 4px;
+    border-radius: 4px;
+}
+a.sl-resources:first-child {
+    margin-left:12px;
+}
+button.btn-apply {
+    font-size:13px;
+    padding:2px 8px;
+}
+div#slice-info {
+    margin-top:25px;
+}
+div#slice-info table {
+    width:100%;
+    margin:0 auto;
+}
+div#slice-info table td:first-child {
+    text-align:right;
+    font-weight:bold;
+    padding-right:15px;
+}
+div#slice-info td {
+    padding:5px;
+}
+
+/* SLICE VIEW sections */
+.slice-sections, .slice-pending {
+    margin:0;
+    padding:0;
+}
+.slice-sections ul, .slice-pending ul {
+    margin:0;
+    padding:0;
+}
+.slice-pending ul {
+    width:400px;
+    margin:0 auto 15px auto;
+}
+.slice-sections li {
+    text-align:left;
+    margin:0;
+    padding:0;
+}
+.slice-pending li {
+    padding-right:15px;
+}
+.slice-sections li a, .slice-pending li a {
+    font-size:14px;
+    color:black;
+    padding:0;
+}
+.slice-sections li.active a, .slice-pending li.active a  {
+    color:#201E62;
+    background-color:#EFEFEF;
+    text-decoration:underline;
+    padding:0;
+}
+.slice-sections ul.nav-pills li a:hover, .slice-pending ul.nav-pills li a:hover {
+    text-decoration:underline;
+    background-color:#EFEFEF;
+    color:black;
+}
+.slice-sections ul.nav-pills li.active, .slice-pending ul.nav-pills li.active {
+
+}
+.slice-sections li:first-child, .slice-sections li:first-child a {
+    color:#201E62;
+    font-weight:bold;
+}
+.slice-experiment {
+    text-align:right;
+    padding:0;
+}
+.slice-experiment button {
+    margin:3px 0 0 0;
+    background-color:#CC4125;
+    color:white;
+}
+
+.slice-pending {
+}
+.slice-pending button {
+    font-size:9pt;
+    margin:-2px 0 0 0;
+    padding:3px 5px;
+}
+.slice-pending button.apply {
+    font-size:14px;
+    padding:2px 5px;
+}
+.slice-pending button.clear {
+}
+tr.active, tr.active td {
+    background-color:#FFFFCC !important;
+}
+div.dataTables_filter label{
+    float:left;
+    width:400px;
+}
+
+/* HEADER */
+
+
+.header {
+  -moz-box-shadow:    0 0 1px rgba(82,82,82,0.6);
+  -webkit-box-shadow: 0 0 1px rgba(82,82,82,0.6);
+  box-shadow:         0 0 1px rgba(82,82,82,0.6);
+  height:61px;
+  background-color:white;
+}
+
+div.navigation {
+    
+}
+div.navigation ul {
+    margin:26px 0 0 0;
+    padding:0;
+    display: inline-block;
+    list-style-type: none;
+    white-space: nowrap;
+}
+
+div.navigation li {
+    color:#0C0047;
+    font-family:open_sansbold, sans-serif;
+    font-size:9pt;
+    font-weight:normal;
+    line-height:0.8em;
+    letter-spacing:0.4pt;
+    list-style:none;
+    float:left;
+    padding:0 15px;
+    margin:0;
+    text-transform:uppercase;
+}
+div.navigation li:hover {
+}
+div.navigation li a {
+    color:#0C0047;
+}
+div.navigation li a:hover, div.navigation li a.current {
+    color:#760073;
+    text-decoration:none;
+}
+
+div.navigation li:last-child {
+    margin-right:0;
+}
+
+
+div.navigation .dropdown-menu {
+    color:black;
+    -moz-box-shadow:    1px 1px 0px 0 rgba(58, 48, 100,0.8);
+    -webkit-box-shadow: 1px 1px 0px 0 rgba(58, 48, 100,0.8);
+    box-shadow:         1px 1px 0px 0 rgba(58, 48, 100,0.8);
+    border-radius:2px;
+    padding:0 5px 5px 5px;
+    margin-top:5px;
+    margin-left:20px;
+}
+div.navigation .dropdown-menu ul {
+    margin:0;
+    padding:15px 5px 5px 5px;
+    display:list-item;
+}
+div.navigation .dropdown-menu li {
+    margin:0 10px 0 0;
+    padding:0 0 8px 0;
+    display:list-item;
+    float:none;
+    text-transform: none;
+}
+
+div.navigation .dropdown-menu a {
+    font-family:Helvetica,sans-serif;
+    font-size:10pt;
+    color:black;
+}
+div.navigation .dropdown-menu li.title {
+    margin-bottom:10px;
+}
+div.navigation .dropdown-menu li.title a {
+    font-family:open_sansbold, sans-serif;
+}
+
+
+div.navigation .dropdown-menu li:first-child {
+    border-bottom:1px solid white;
+    padding-bottom:5px;
+     
+}
+
+div.secondary {
+    text-align:right;
+}
+
+div.secondary ul {
+   margin:6px 0 0 0;
+   padding:0;
+}
+
+div.secondary li {
+    font-size:9pt;
+    display:inline;
+    list-style:none;
+    margin:0px;
+    padding:0;
+    margin-right:15px;
+    color:#747474;
+    letter-spacing:0.4px;
+}
+div.secondary li:last-child {
+    margin-right:0;
+}
+div.secondary li a {
+    color:#747474;
+}
+div.secondary li a:hover {
+    text-decoration:underline;
+}
+div.secondary .button {    
+    width:300px;
+    margin-top:15px;
+}
+div.secondary .account {
+    margin-top:10px;
+    padding:0;
+    font-size:9pt;
+    color:gray;
+    text-align:right;
+}
+div.secondary .account span {
+    font-size:8pt;
+}
+div.secondary .account a {
+    color:black;
+}
+
+
+div.footer {
+    padding-top:15px;
+}
+div.footer div.bottom {
+    position:absolute;
+    bottom:0;
+}
+div.footer ul {
+   margin:6px 0 0 0;
+   padding:0;
+}
+
+div.footer li {
+    font-size:9pt;
+    display:inline;
+    list-style:none;
+    margin:0px;
+    padding:0;
+    margin-right:15px;
+    color:#747474;
+    letter-spacing:0.4px;
+}
+
+div.footer li a {
+    color:#747474;
+}
+div.footer li a:hover {
+    text-decoration:underline;
+}
+div.copy {
+    font-size:8pt;
+    color:gray;
+    padding-top:15px;
+    padding-bottom:15px;
+}
+
+div.home {
+    font-size:11pt;
+    line-height:1.2em;
+    letter-spacing:0.3pt;
+    min-height:500px;
+    //background-image: url('../img/bg-experiment.png');
+    background-repeat:no-repeat;
+    background-size:cover;
+    background-position:center top;
+    background-color:#4FABA3;
+    padding:100px 0;
+}
+div.home h2 {
+    color:white;
+    line-height:1.2em;
+    font-size:18pt;
+}
+div.home h3 {
+    color:white;
+    line-height:1.4em;
+}
+div.dashboard {
+    text-align:center;
+}
+div.dashboard div {
+    margin:25px 0;
+}
+div.dashboard ul {
+    text-align:left;
+    margin-left:24px;
+    list-style:none;
+}
+div.registration-form {
+    padding-top:150px;
+    text-align:center;
+}
+
+.login-form input {
+    width:320px;
+}
+.login-form input[type=submit] {
+    width:108px;
+}
+
+.login-submit {
+    vertical-align:middle;
+    padding:0;
+}
+.lost-password {
+    font-size:10pt;
+    color:black;
+    text-align:right;
+    padding:0px;
+}
+.lost-password a {
+    color:white;
+    text-shadow:0.5px 0.5px black;
+}
+.login-signup {
+    font-size:12pt;
+    color:white;
+    text-shadow:0.5px 0.5px black;
+    margin-top:45px;
+    padding:5px 0 0 4px;
+    
+}
+.login-signup a {
+    color:white;
+    text-shadow:0.5px 0.5px black;
+    padding-bottom:2px;
+    border-bottom:2pt solid white;
+}
+.login-signup a:hover {
+    text-decoration:none;
+}
+.login-signup button {
+    padding:8px;
+    border:0;
+    border-bottom:2px solid #540086;
+    background-color:#302562;
+    color:white;
+    width:100px;
+    border-radius:5px;
+    font-size:12pt;
+}
+div.slogan {
+    text-align:center;
+    color:white;
+    padding-top:60px;
+    text-shadow: 1px 1px #013540;
+}
+
+th {
+    border:0 !important;
+}
+
+div.monitor {
+    padding:40px 0 25px 0;
+}
+div.monitor h1 {
+    margin-bottom:25px;
+}
+div.s-monitor {
+    padding-bottom:25px;
+}
+span#stats-period-txt {
+    text-transform:lowercase;
+}
diff --git a/portal/static/img/SmartFIRE_logo.png b/portal/static/img/SmartFIRE_logo.png
new file mode 100644 (file)
index 0000000..57b58f3
Binary files /dev/null and b/portal/static/img/SmartFIRE_logo.png differ
diff --git a/portal/templates/loginwidget.html b/portal/templates/loginwidget.html
new file mode 100644 (file)
index 0000000..763fab6
--- /dev/null
@@ -0,0 +1,17 @@
+<form action="//portal.onelab.eu/login/" method="post" role="form">
+{% csrf_token %}
+<div class="form-group">
+    <input class="input-md" type="email" name="username" placeholder="Enter Email / Username">
+</div>
+<div class="form-group">
+    <input type="password" name="password" placeholder="Password">
+</div>
+<div class="login-submit">
+    <input type="submit" class="btn btn-onelab" value="Sign In" />
+    <span class="lost-password">&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;<a href="http://portal.onelab.eu/portal/pass_reset/">Can't access your account?</a></span>
+</div>
+<div class="login-signup">
+    You don't have an account yet? 
+    <br /><a href="http://portal.onelab.eu/register">Sign Up!</a>
+</div>
+</form>
\ No newline at end of file
index ef29d3d..8ad3bf5 100644 (file)
@@ -4,38 +4,50 @@
 
 <div class="row">
        <div class="col-md-12">
-               <h1><img src="{{ STATIC_URL }}icons/user-xs.png" alt="User Registration" />User sign-up</h1>
+       <h1><img src="{{ STATIC_URL }}icons/user-xs.png" alt="User Registration" />User sign-up</h1>
        </div>
 </div>
 <div class="row">
        <div class="col-md-12">
-               <p><strong>Questions? <a href="/portal/contact" >Contact us.</a></strong></p>
-       </div>
+               <p><strong>Questions? <a href="/contact" >Contact us.</a></strong></p>
+  </div>
 </div>
 {% if errors %}
 <div class="row">
        <div class="col-md-12">
-               <ul>
+               <ul class="error">
                  {% for error in errors %}
-                 <li>{{ error }}</li>
+                 <li>{{ error | safe }}</li>
                  {% endfor %}
                </ul>
        </div>
 </div>
 {% endif %}
+                               <form action="/register" class="cmxform form-horizontal" method="post" enctype="multipart/form-data">
 <div class="row">
        <div class="col-md-12">
-               
                        <div class="form-group">
-                               <form class="cmxform form-horizontal" id="registrationForm" method="post" enctype="multipart/form-data" role="form">
-                       {% csrf_token %}
+                               {% csrf_token %}
                                <label for="authority_hrn" class="control-label">Organization</label>
                                <p></p>
-                               <input id="authority_hrn" name="org_name" class="form-control" style="width:590px" value="{{ organization }}" 
+                <div class="ui-widget">
+                               <select id="org_name" name="org_name" class="form-control" style="width:590px" value="{{ organization }}" 
                                title="Choose your organization (company/university) from the list that apears when you click in the field and start to type.
-                                Use the arrow keys to scroll through the list; type part of the name to narrow down the list. If it is not in the list, 
-                               please request its addition by clicking the link below. We will send an email to the managers that we have on record for 
-                               your organization, asking them to validate your sign-up request." required/>
+                                Use the arrow keys to scroll through the list; type part of the name to narrow down the list. We will send an email to 
+                                the managers that we have on record for your organization, asking them to validate your sign-up request." required>
+                {% if authorities %}
+                    {% for authority in authorities %}
+                        {% if authority.name %}
+                            <option value="{{ authority.authority_hrn }}">{{authority.name}}</option>
+                        {% else %}
+                            <option value="{{ authority.authority_hrn }}">{{authority.authority_hrn}}</option>
+                        {% endif %}
+                    {% endfor %}    
+                {% else %}
+                    <option value:"">No authority found !!!</option>
+                {% endif %}
+                </select>
+                </div>
                                <p></p>
                                <p>Organization not listed? <a href="/portal/join">Request its addition now.</a></p>
                        </div>
@@ -56,7 +68,7 @@
                <div class="form-group">
                <input type="email" name="email" size="25"  class="form-control" style="width:350px" value="{{ email }}" 
                        title="Your e-mail address will be your identifier for logging in. We contact you to verify your account and then, occasionally, for important issues."
-                       placeholder="Email" required/>
+                       placeholder="Email" required />
                </div>
        </div>  
 
                                placeholder="Confirm password" required />
            </div>
            <div class="form-group">
-               <!--<label for="question" class="control-label">Keys</label> -->
                        <select name="question" class="form-control" style="width:350px" id="key-policy" 
-                               title="Your public/private key pair allows you to access the testbeds." required>        
+                               title="Your public/private key pair allows you to access the testbeds." required >        
                                <option value="generate">Generate my keys for me (recommended)</option>
                                <option value="upload">Upload my public key (advanced users only)</option>
                        </select>
            </div>
            <div class="form-group" style="display:none;" id="upload_key">
                <label for="file" class="control-label">Upload public key</label>
-               <input type="file" name="user_public_key" class="form-control" style="width:200px" id="user_public_key" required/>
+               <input type="file" name="user_public_key" class="form-control" style="width:200px" id="user_public_key" />
                <br />
                        <div class="alert alert-danger" id="pkey_del_msg">
                                In order for the portal to contact testbeds on your behalf, so as to list and reserve resources, you will need to 
-                               <a href="http://trac.myslice.info/wiki/InstallSfa" target="_blank">delegate your public key to the portal.</a>
+                               <a href="/portal/manual_delegation" target="_blank">delegate your credentials to the portal.</a>
                        </div>
            </div>
        </div>
        <div class="col-md-12">
                <div class="form-group">
                        <p></p>
-                       <input type="checkbox" name="agreement" value="agreement" required/>&nbsp;&nbsp; I agree to the 
+                       <input type="checkbox" name="agreement" value="agreement" required />&nbsp;&nbsp; I agree to the 
                        <a href="#" data-toggle="modal" data-target="#myModal">terms and conditions.</a> 
                </div>
        </div>
        <div class="col-md-12">
                <div class="form-group" id="register">
                        <p></p> 
-               <button class="submit btn btn-onelab" type="submit">Sign up</button>
+               <input class="submit btn btn-onelab" type="submit" value="Sign up" />
+               </form>
            </div>
-       </form> 
        </div>
 </div>
-       
-       
+
        <!-- Modal - columns selector -->
-               <div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
+<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
                        <div class="modal-dialog">
                        <div class="modal-content">
                                <div class="modal-header">
                                </div>
                                <div class="modal-body">
                                                <p align="left">
-                                       for OneLab Basic level service
-                                       <br/>
-                                       Version 0.6 of 20 May 2014
-                                               <br>
-                                               <a href="/portal/terms" target="_blank">[Printable format]</a>
+                                                       To be added soon.
                                                </p>
-                                       <h1 align="left">1 Context</h1>
-                                       <h2 align="left">1.1 OneLab</h2>
-                                       <p align="left">
-                               OneLab is an experimental facility for testing new ideas and new technologies in the area of computer networking. It consists of a variety of types of
-                               platforms, including:</p>
-                                       <ul type="disc">
-                               <li>
-                               <strong>internet overlay testbeds</strong>
-                               , testbeds that offer virtual machines distributed across locations in different countries, allowing users to deploy overlays on the internet;
-                               </li>
-                               <li>
-                               <strong>wireless testbeds</strong>
-                               , testbeds that consist of clusters of computers that are within Wi-Fi communication range of each other, either in an office environment or in an
-                               isolated setting;
-                               </li>
-                               <li>
-                               <strong>internet of things testbeds</strong>
-                               , testbeds that consist of embedded computing nodes with sensor capabilities, communicating wirelessly in an isolated environment;
-                               </li>
-                               <li>
-                               <strong>emulation testbeds,</strong>
-                               computing clusters that offer virtual machines on servers that are interconnected by a high speed switch, enabling large scale network emulation.
-                               </li>
-                                       </ul>
-                                       <p align="left">
-                               This list of types of platforms is subject to change, and the current list, along with the identities of the specific platforms of each type, can be found
-                               on the OneLab website (onelab.eu).</p>
-                                       <p align="left">
-                               Each platform has its own owners, and OneLab is the grouping of these platforms through a consortium of institutions. The OneLab consortium is coordinated
-                               by UPMC Sorbonne Universités. It operates on a not-for-profit basis.</p>
-                                       <p align="left">
-                               Access to OneLab may also provide access to additional platforms that are not part of OneLab, due to a federation agreement between OneLab and the owners
-                               of those platforms.</p>
-                                       <h2 align="left">1.2 Fee-free Basic level service</h2>
-                                       <p align="left">These terms and conditions define and apply to OneLab's Basic level service, which is available free of charge.</p>
-                                       <p align="left">
-                               Users who would like additional services are encouraged to contact support@onelab.eu. Some additional services require a written agreement, but are
-                               otherwise free. Others require the payment of fees or in-kind contributions. (An example of an in-kind contribution is the hosting of a PlanetLab Europe
-                               server node.)</p>
-                                       <h2 align="left">1.3 Managers and standard users</h2>
-                                       <p align="left">
-                               There are two classes of OneLab user: the manager and the standard user. OneLab grants access rights to managers, who, in turn, provide access rights to
-                                       standard users. Examples are: for a small enterprise, an executive may be the manager and the employees may be standard users; for a research team, a
-                               senior scientist (faculty member or research scientist) may be a manager and doctoral students and other members of the team may be standard users; for a
-                               university course, a professor may be a manager and the students may be standard users.</p>
-                                       <h2 align="left">1.4 These terms and conditions</h2>
-                                       <p align="left">
-                               Acceptance of these terms and conditions is a condition of obtaining OneLab Basic level user service. They are posted to the OneLab portal site
-                               (portal.onelab.eu). They may be changed without other notice than the posting of a new version to the portal site.</p>
-                                       <h1 align="left">2 Services provided by OneLab</h1>
-                                       <h2 align="left">2.1 Access to the experimental facility</h2>
-                                       <p align="left">
-                               OneLab provides users with access to the platforms that make up the experimental facility. Each platform owner determines the specifics of this access (for
-                               example, how many nodes are available to a user, what happens in case of oversubscription, etc.), with the proviso that Basic level service requires that
-                                       users be able to conduct meaningful experiments on every OneLab testbed.</p>
-                                       <p align="left">
-                               Basic level service may also provide access to platforms that are federated with OneLab, but such access depends upon the terms of the federation
-                               agreements with those platforms, which may require that the user have a higher level of service in order to gain access. For example, Basic level service
-                               provides access to PlanetLab Europe, a OneLab platform, without providing access to PlanetLab Central, a federated platform. Users wanting full access
-                               across the global PlanetLab system should contact support@onelab.eu to arrange to enter into a PlanetLab Europe membership agreement.</p>
-                                       <p align="left">OneLab's role is to facilitate access to the platforms. Specifically, it provides each user with:</p>
-                                       <ul>
-                               <li align="left">
-                               <strong>a single account,</strong>
-                               the credentials for which can be used to access all of the OneLab testbeds;
-                               </li>
-                               <li align="left">
-                               <strong>tools through which to access the testbeds</strong>
-                               , including, notably, a web-based portal (portal.onelab.eu) that allows a user to see the resources available on each testbed and to reserve them,
-                               along with a number of experiment control tools that a user can employ to deploy an experiment on those resources;
-                               </li>
-                               <li align="left">
-                               <strong>support</strong>
-                               , with documentation on how to use the tools, pointers to documentation for individual testbeds, and a helpdesk to respond to user questions.
-                               </li>
-                                       </ul>
-                                       <p align="left">
-                                           Additional support, such as accompaniment through the design and deployment of experiments and the interpretation of their results, is available through
-                                           higher levels of service.
-                                       </p>
-                                       <h2 align="left">
-                                           2.2 Best effort, without guarantees
-                                       </h2>
-                                       <p align="left">
-                                           OneLab and the owners of the individual OneLab testbeds do their best to provide the services outlined here, with the understanding that Basic level
-                                           service offers no guarantees. Users should clearly understand the following limitations.
-                                       </p>
-                                       <ul type="disc">
-                                           <li>
-                                               <strong>Reliability:</strong>
-                                               OneLab does not provide any guarantees with respect to the reliability of the portal, of other tools, or of the individual nodes on platforms. These
-                                               may be taken down for maintenance, rebooted, or reinstalled at any time. Reinstallation implies that disks are wiped, meaning that users should not
-                                               consider a local disk to be a persistent form of storage.
-                                           </li>
-                                           <li>
-                                               <strong>Fitness:</strong>
-                                               OneLab does not guarantee that the platforms are suitable for the experiments that users intend to conduct. There may be limitations in the
-                                               technologies that are offered that prevent certain types of experiments from being carried out.
-                                           </li>
-                                           <li>
-                                               <strong>Privacy</strong>
-                                               : OneLab does not guarantee the privacy of traffic generated on the platforms (e.g., wireless signals, packets). Unless otherwise specified by an
-                                               individual platform owner, users should assume that traffic is monitored and logged. Such monitoring may be done intentionally, for example, to allow
-                                               platform administrators as well as other users to investigate abuse.
-                                           </li>
-                                       </ul>
-                                       <p align="left">
-                                           Users who seek such guarantees are invited to consider a higher level of service.
-                                       </p>
-                                       <h2 align="left">
-                                           2.3 Limitedliability
-                                       </h2>
-                                       <p align="left">
-                                           In no event shall the partners of the OneLab consortium be liable to any user for any consequential, incidental, punitive, or lost profit damages, or for
-                                           any damages arising out of loss of use or loss of data, to the extent that such damages arise out of the activities of OneLab consortium partners, or any
-                                           breach of the present terms and conditions, even if the consortium partner has been advised of the possibility of such damages.
-                                       </p>
-                                       <p align="left">
-                                           Nothing contained in these terms and conditions shall be deemed as creating any rights or liabilities in or for third parties who are not Basic level users
-                                           of OneLab.
-                                       </p>
-                                       <h1 align="left">
-                                           3 Acceptable use policy
-                                       </h1>
-                                       <h2 align="left">
-                                           3.1 Responsibilities of managers and standard users
-                                       </h2>
-                                       <p align="left">
-                                           OneLab creates and administers accounts for managers and delegates to managers the responsibility for creating and administering accounts for standard
-                                           users. Both managers and standard users are required to follow OneLab's acceptable use policy. In addition, managers are fully responsible for the
-                                           activities of the standard users whose accounts they create.
-                                       </p>
-                                       <p align="left">
-                                           A manager is expected to grant user access only an individual with whom he or she has a working relationship. In general, this means an individual who
-                                           works for the same institution as the manager, or, in the case of higher education and research, an individual who is a student at the university where the
-                                           manager works. Managers may also grant access to individuals from other institutions, provided that they are collaborating on a common project on OneLab.
-                                           If there is a doubt, a manager should refer the question to support@onelab.eu.
-                                       </p>
-                                       <h2 align="left">
-                                           3.2 Types of use
-                                       </h2>
-                                       <p align="left">
-                                           OneLab may be used by enterprise, by scientific researchers, and by educators.
-                                       </p>
-                                       <p align="left">
-                                           OneLab may be used for pre-commercial research and development. In keeping with OneLab's not-for-profit status, it may not be used to deploy services that
-                                           are designed to generate a commercial profit.
-                                       </p>
-                                       <p align="left">
-                                           Not-for-profit use of OneLab to deploy services that are designed to generate revenue requires prior approval through a written agreement, and thus may not
-                                           be carried out on a Basic level account. Interested users are invited to contact support@onelab.eu.
-                                       </p>
-                                       <p align="left">
-                                           OneLab may be used for scientific research.
-                                       </p>
-                                       <p align="left">
-                                           OneLab may be used to host lab exercises for university courses.
-                                       </p>
-                                       <p align="left">
-                                           Questions about other types of use should be addressed to support@onelab.eu.
-                                       </p>
-                                       <h2 align="left">
-                                           3.3 Applicable laws and regulations
-                                       </h2>
-                                       <p align="left">
-                                           OneLab is managed, and the portal is hosted, in France. Information regarding the countries in which individual testbeds are managed and hosted is
-                                           available from those testbeds. Users are responsible for being aware of the countries in which their experiments are deployed and for ensuring that their
-                                           use of OneLab fully conforms to the laws and regulations of those countries, as well as the laws and regulations of the country in which they themselves
-                                           are present when conducting their experiments.
-                                       </p>
-                                       <p align="left">
-                                           Above and beyond specific national laws, the activities email spamming, phishing through web services, and all types of Internet fraud are prohibited on
-                                           OneLab.
-                                       </p>
-                                       <h2>
-                                           3.4 Security and accounting mechanisms
-                                       </h2>
-                                       <p align="left">
-                                           Users are expected to respect the security and accounting mechanisms put in place by OneLab, its platforms, and federated platforms. For example, access to
-                                           PlanetLab Europe is designed to take place through the SSH cryptographically-secured connection protocol, which uses public/private key pair
-                                           authentication, and so users should not attempt to bypass this mechanism. As another example, OneLab's notion of a "slice" associates a set of resources
-                                           with the group of users who have reserved those resources, and users should not attempt to obscure the identities of participants in a slice.
-                                       </p>
-                                       <p align="left">
-                                           Hacking attempts against the OneLab portal and testbeds are not permitted. This includes "red team" (hacker test) experiments.
-                                       </p>
-                                       <h2>
-                                           3.5 Sharing of resources
-                                       </h2>
-                                       <p align="left">
-                                           OneLab is intended for ambitious experiments. Large numbers of resources and extended leases on resources may legitimately be granted in order to carry
-                                           these out. At the same time, OneLab and its testbeds are shared environments, and when there is contention for resources, limits must be imposed.
-                                       </p>
-                                       <p align="left">
-                                           Each OneLab platform sets its own policies for handling resource contention. As a general rule, users are encouraged to design their experiments to use
-                                           resources efficiently. In particular, spinning/busy-waiting techniques for extended periods of time are strongly discouraged. Some resource contention
-                                           policies (e.g., PlanetLab Europe's) terminate the jobs that are using the most resources in the case of contention.
-                                       </p>
-                                       <h2>
-                                           3.6 Internet-connected platforms
-                                       </h2>
-                                       <p align="left">
-                                           Some of OneLab's platforms allow experiments to take place on resources that have access to the public internet. These experiments can potentially generate
-                                           traffic to, and receive traffic from, any host or router in the internet.<a></a><a id="_anchor_1" href="#_msocom_1" name="_msoanchor_1">[LB1]</a>
-                                       </p>
-                                       <p align="left">
-                                           Furthermore, some internet-connected platforms (e.g., PlanetLab Europe) consist of servers that are hosted by a large number of member institutions.
-                                       </p>
-                                       <p align="left">
-                                           The accessibility of internet-connected platforms and the distributed hosting model of some of these platforms imply certain responsibilities on the part
-                                           of users, as detailed below.
-                                       </p>
-                                       <h3>
-                                           3.6.1 General guidance
-                                       </h3>
-                                       <p align="left">
-                                           A good litmus test when considering whether an experiment is appropriate for such internet-connected platforms is to ask what the network administrator at
-                                           one's own organisation would say about the experiment running locally. If the experiment disrupts local activity (e.g., uses more than its share of the
-                                           site's internet bandwidth) or triggers complaints from remote network administrators (e.g., performs systematic port scans), then it is not appropriate for
-                                           such internet-connected platforms.
-                                       </p>
-                                       <p align="left">
-                                           It is the responsibility of the user and the user's manager to ensure that an application that will run on an internet-connected platform is tested and
-                                           debugged in a controlled environment, to better understand its behaviour prior to deployment.
-                                       </p>
-                                       <h3>
-                                           3.6.2 Standards of network etiquette
-                                       </h3>
-                                       <p align="left">
-                                           Internet-connected platforms are designed to support experiments that generate unusual traffic, such as network measurements. However, it is expected that
-                                           all users adhere to widely accepted standards of network etiquette in an effort to minimise complaints from network administrators. Activities that have
-                                           been interpreted as worm and denial-of-service attacks in the past (and should be avoided) include sending SYN packets to port 80 on random machines,
-                                           probing random IP addresses, repeatedly pinging routers, overloading bottleneck links with measurement traffic, and probing a single target machine from
-                                           many nodes.
-                                       </p>
-                                       <p align="left">
-                                           For internet-connected platforms that have a distributed hosting model, each host institution will have its own acceptable use policy. Users should not
-                                           knowingly violate such local policies. Conflicts between local policies and OneLab's stated goal of supporting research into wide-area networks should be
-                                           brought to the attention of OneLab administrators at support@onelab.eu.
-                                       </p>
-                                       <h3>
-                                           3.6.3 Specific network usage rules
-                                       </h3>
-                                       <p align="left">
-                                           It is not allowed to use one or more nodes of an internet-connected platform to generate a high number of network flows or flood a site with high traffic
-                                           to the point of interfering with its normal operation. Use of congestion-controlled flows for large transfers is highly encouraged.
-                                       </p>
-                                       <p align="left">
-                                           It is not allowed to perform systematic or random port or address block scans from an internet-connected platform.
-                                       </p>
-                                       <p align="left">
-                                           For internet-connected platforms that use a distributed hosting model, it is not allowed to spoof or sniff traffic on a hosted server or on the network the
-                                           server belongs to.
-                                       </p>
-                                       <p align="left">
-                                           Access to a server on a distributed hosting platform may not be used to gain access to other servers or networked equipment that are not part of the
-                                           testbed.
-                                       </p>
-                                       <h2>
-                                           3.7 Wireless platforms
-                                       </h2>
-                                       <p align="left">
-                                           Wireless-connected platforms give users access to nodes that communicate via Wi-Fi and other wireless technologies. They may be capable of detecting
-                                           wireless activity in the neighbourhood of those nodes: traffic generated by other users of the platform or by individuals not associated with the platform.
-                                           In general, much of the traffic will be encrypted, with certain aspects (such as SSIDs) not encrypted, but it is also possible that there will be fully
-                                           unencrypted traffic. They may also be capable of generating wireless activity that reaches equipment outside of the testbed.
-                                       </p>
-                                       <p align="left">
-                                           Furthermore, some wireless-connected platforms may have built-in limitations to prevent them from generating signals at a strength that exceeds health and
-                                           safety regulations.
-                                       </p>
-                                       <p align="left">
-                                           These characteristics of wireless-connected platforms imply certain responsibilities on the part of users, as detailed below.
-                                       </p>
-                                       <h3>
-                                           3.7.1 Specific network usage rules
-                                       </h3>
-                                       <p align="left">
-                                           Experimenters may make no attempt to defeat the encryption of encrypted third-party traffic. Furthermore, experimenters must treat with utmost discretion
-                                           any unencrypted traffic. Limited metadata can be recorded for the bona fide purposes of an experiment, but under no case should third party communications
-                                           be recorded.
-                                       </p>
-                                       <p align="left">
-                                           No attempt may be made to reverse engineer traffic in order to learn the identities of the parties who have generated the traffic.
-                                       </p>
-                                       <p align="left">
-                                           Wireless-connected platforms may not be used to gain access to any network equipment that is not part of the testbed itself.
-                                       </p>
-                                       <p align="left">
-                                           It is not allowed to perform systematic or random scans of wireless networks that are not part of a wireless-connected platform. Similarly, it is not
-                                           allowed to spoof or sniff wireless traffic of the institution that hosts a wireless-connected platform or of other networks in the proximity.
-                                       </p>
-                                       <p align="left">
-                                           Care must be taken so that traffic on wireless-connected platforms does not interfere with the normal functioning of network equipment that is not part of
-                                           the testbed itself.
-                                       </p>
-                                       <p align="left">
-                                           No attempt may be made to defeat the mechanisms that limit signal strength on wireless-connected platforms.
-                                       </p>
-                                       <h2>
-                                           3.8 Handling suspected violations
-                                       </h2>
-                                       <p align="left">
-                                           Suspected violations of the OneLab acceptable use policy should be reported to support@onelab.eu.
-                                       </p>
-                                       <p align="left">
-                                           Upon notification or detection of a possible violation, OneLab management will attempt to understand if a violation has in fact occurred. To do so,
-                                           management will freely communicate with the users concerned, the operators of the platforms concerned, as well as any third parties that might be involved.
-                                           An example of a third party is a network operator who detects what they believe to be unauthorized traffic emanating from a OneLab platform.
-                                       </p>
-                                       <p align="left">
-                                           The priority is to resolve any real or apparent violations amicably. However, if OneLab management believes that a violation may have occurred, it can, at
-                                           its sole discretion, and without prior notice, apply any of the following measures:
-                                       </p>
-                                       <ul type="disc">
-                                           <li>
-                                               notification of the users of the concerned slice (set of resources);
-                                           </li>
-                                           <li>
-                                               disabling of the concerned slice;
-                                           </li>
-                                           <li>
-                                               disabling an individual user's account;
-                                           </li>
-                                           <li>
-                                               reporting of the user's activity to his/her manager;
-                                           </li>
-                                           <li>
-                                               disabling of the manager's account and all user accounts for which the manager is responsible;
-                                           </li>
-                                           <li>
-                                               disabling of all accounts associated with the user's institution.
-                                           </li>
-                                       </ul>
-                                       <p align="left">
-                                           In the case of suspected illegal activity, OneLab management might need, without prior notice, to notify the relevant authorities.
-                                       </p>
 
                                </div>
                                <div class="modal-footer">
 
     
 <script>
-jQuery(document).ready(function(){
+$(document).ready(function(){
     var availableTags = [
     {% if authorities %}
         {% for authority in authorities %}
             {% if authority.name %}
-                {value:"{{ authority.name }}",label:"{{authority.name}}"},
+                {value:"{{ authority.authority_hrn }}",label:"{{authority.name}}"},
                        // show hrn if we don't have the name
             {% else %}
                 {value:"{{ authority.authority_hrn }}",label:"{{authority.authority_hrn}}"},
@@ -491,6 +160,7 @@ jQuery(document).ready(function(){
     {% endif %}
     ];
        // sorting the list
+    
        availableTags.sort(function(a,b){
                var nameA=a.value.toLowerCase(), nameB=b.value.toLowerCase();
                if (nameA < nameB) {
@@ -502,21 +172,17 @@ jQuery(document).ready(function(){
        return 0;
        }); 
        // auto-complete the form
-    jQuery( "#authority_hrn" ).autocomplete({
-      source: availableTags,
-      minLength: 0,
-      change: function (event, ui) {
-          if(!ui.item){
-              //http://api.jqueryui.com/autocomplete/#event-change -
-              // The item selected from the menu, if any. Otherwise the property is null
-              //so clear the item for force selection
-              jQuery("#authority_hrn").val("");
-          }
-      }
-      //select: function( event, ui ) {console.log(jQuery(this))}
-    });
-       // for hover texts
-       jQuery('[title!=""]').qtip();
+    jQuery("#org_name").combobox();
+       $('[title!=""]').qtip();
+       $("form").validate();
+       $("form").submit(function() {
+               if ($('select option:selected').val() == 'upload') {
+                       if ($('input[name=user_public_key]').val() == '') {
+                               alert('Please specify the key file to upload');
+                               return false;
+                       }
+               }
+       });
 });
 </script>
 {% endblock %}
index c000ee9..d30d2f9 100644 (file)
          </div>\r
          <div id="tabs-2">\r
                <h1>Experiment Evaluation</h1>\r
-               <p><b>List of your unrated experiments</b></p><div id="slicelist">\r
+               <p><b>List of your unrated experiments</b></p>\r
+               <div style=" width: 70% !important" id="slicelist">\r
                        \r
                        {% for aslice in slicelist %}\r
-                       <h3>Slice <b>{{ aslice.slice_hrn }}</b></h3>\r
+                               <h3>Slice <b>{{ aslice.slice_hrn }}</b></h3>\r
                        <div style="padding-bottom:0;padding-top:0;">\r
                            <ul><li>\r
                                    experiment from <b>{{ aslice.start_t }}</b> to <b>{{ aslice.end_t }}</b> | <a href="#" class="rate_button" data-resid={{ aslice.id }}>Rate it</a>\r
 <div id="scoreform" style="display:none">\r
     <ol>\r
         <li>\r
-            <span>How was your overall experience with NETMODE Testbed?</span> \r
+            <span>How was your overall experience with this Testbed?</span> \r
             <div id="q1">\r
             </div>\r
         </li>\r
             </div>\r
         </li>\r
         <li>\r
-            Would you use NETMODE testbed again?\r
+            Would you use this testbed again?\r
             <div id="q4">\r
                 <input type="radio" name="q4" value="1" />Yes\r
                 <input type="radio" name="q4" value="0" />No\r
@@ -237,9 +238,6 @@ $(function() {
 \r
 var data = jQuery.parseJSON('{{ json_data|safe }}');\r
 \r
-\r
-\r
-\r
 var resid = -1;\r
 var q1 = -1;\r
 var q2 = -1;\r
@@ -267,7 +265,7 @@ function initDialog() {
 \r
         $("a[data-resid='"+resid+"']").css("text-decoration", "line-through").unbind("click").removeAttr("href");\r
 \r
-        //TODO: check input if valid before submitting\r
+        //TODO: validate input before submitting\r
 \r
         sum = q1 + q2 + q3 + q4 + q5 + q6 + q7 +q8;\r
 \r
@@ -283,8 +281,6 @@ function initDialog() {
                                }       \r
                        }\r
                        \r
-\r
-                       \r
                        slicedata["user_eval"] = {'overall':q1, 'problems':q2, 'support':q3, 'reuse':q4, 'pay':q5, 'availability':q6, 'link_quality':q7, 'quality':q8};\r
                        testbeds_str = JSON.stringify(slicedata['testbeds'])\r
                        delete slicedata['testbeds'];\r
diff --git a/portal/templates/smartfire/smartfire_account-view.html b/portal/templates/smartfire/smartfire_account-view.html
new file mode 100644 (file)
index 0000000..199444a
--- /dev/null
@@ -0,0 +1,371 @@
+{% extends "layout.html" %}
+{% block content %}
+
+<div class="row">
+       <div class="col-md-12">
+                <div class="breadcrumbs">
+                        Account &nbsp;>&nbsp; <a href="/account">{{ person.email }}</a>
+                </div>
+       </div>
+        {%if 'no_creds'  in user_cred %}
+    <p class="command"><a href="#" style="color:red" data-toggle="modal" data-target="#myModal">NO CREDENTIALS</a> are delegated to the portal!</p>
+{%endif%}
+
+</div>
+{% if messages %}
+<ul class="messages">
+    {% for message in messages %}
+    <li{% if message.tags %} class="{{ message.tags }}"{% endif %}>{{ message }}</li>
+    {% endfor %}
+</ul>
+{% endif %}
+<div class="row">
+       <div class="col-md-12">
+               <ul class="nav nav-tabs nav-section">
+                       <li class="active"><a href="#profile">User Profile</a></li>
+                       <li><a href="#account">Account</a></li>
+                       <li><a href="#access">Testbed Access</a></li>
+               </ul>
+    </div>
+</div>
+<div class="tab-content">
+       <div class="tab-pane active row" id="profile">
+               
+               <div class="col-md-12">
+
+                       <form id="editForm" method="post" action="account_process" enctype="multipart/form-data">
+                               {% csrf_token %}
+                                       <table class="profile">          
+                                       <tr>
+                                               <td colspan="2">
+                                                               <div><h3>Platform: Myslice</h3></div>
+                                               </td>
+                                       </tr>
+                                       <tr>
+                                               <td class="key">Email</td>
+                                               <td class="value">
+                                                               <span id="emailval" class="value" >{{ person.email }}</span>
+                                                               <button class="btn btn-default" type="button" id="edit_email" onclick="editAlert();"  title="To change your affiliation please contact the administrator">
+                                                               <span class="glyphicon glyphicon-question-sign"></span> Edit
+                                                               </button>
+                                                       </td>
+                                       </tr>
+                                       <tr class="odd">
+                                                       <td class="key">Password</td>
+                                                       <td class="value"> 
+                                                               <button class="btn btn-default btn-xs" type="button" title="Password" name="edit_pass" id="edit_pass">
+                                                                       <span class="glyphicon glyphicon-edit"></span> Edit
+                                                               </button>
+                                                               <span id="passval"class="value">******** </span>
+                                                               <span class="hide_this" id="span_pass">
+                                                               <button type="button" class="btn btn-default btn-xs" title="Cancel" id="cancel_pass_change"> Cancel </button>
+                                                               <div style='display:none;' id="pass_form">
+                                                               <input type='hidden'  value='' /></div>
+                                                               <table id="edit_password">
+                                                                       <tr>
+                                                                                       <td>Enter password: </td>
+                                                                                       <td class="field"> <input type="password" name="password" id="password" /> </td>
+                                                                               </tr>
+                                                                               <tr>
+                                                                                       <td>Confirm password: </td>
+                                                                                       <td class="field"> 
+                                                                                               <input type="password" name="confirmpassword" id="confirmpassword" /> 
+                                                                                               <input type="submit" class="btn btn-default btn-xs" name="submit_pass" value="Save"/> 
+                                                                                       </td>
+                                                                       </tr>
+                                                               </table>
+                                                               </span> 
+                                                       </td>
+                                       </tr>
+                                       <tr class="even">
+                                                       <td class="key">Full Name</td>
+                                                       <td class="value">
+                                                               <span id="nameval" class="value" >{{ fullname }} </span>
+                                                               <span class="hide_this" id="span_name">
+                                                               <button type="button" class="btn btn-default btn-xs" title="Cancel" id="cancel_name_change"> Cancel </button> 
+                                                               <div style='display:none;'><input type='hidden'  name='nameform'  /></div>
+                                                               <input id="fname" type="text" name="fname" class="required"  maxlength="200" value="{{firstname}}" />
+                                                               <input id="lname" type="text" name="lname" class="required"  maxlength="200" value="{{lastname}}" />
+                                                               <input type="submit" class="btn btn-default btn-xs" name="submit_name" value="Save"/>
+                                                               </span>
+                                                               <button class="btn btn-default btn-xs" type="button"title="Full Name" id="edit_name">
+                                                                       <span class="glyphicon glyphicon-edit"></span> Edit
+                                                               </button>
+                                                       </td>
+                                       </tr>
+                                       <tr class="odd">
+                                                       <td class="key">Authority</td>
+                                                       <td class="value">
+                                                               <span id="affval" class="value">{{ authority }}</span>
+                                                                <button class="btn btn-default btn-xs" type="button" id="edit_auth" onclick="editAlert()"  title="To change your authority please contact the administrator">
+                                                               <span class="glyphicon glyphicon-question-sign"></span> Edit
+                                                                </button>
+                                                       </td>
+                                               </tr>
+                                               {%if 'Enabled'  in user_status %}
+                                               <tr class="even">
+                                                       <td class="key">Generate Keys</td>
+                                                       <td>
+                                                               <input type="submit" name="generate" class="btn btn-primary" value="Generate a new Key Pair" id="generate_keypair" 
+                                                                          onclick="return confirm('Are you sure? If you do so, your current credentials will be overwritten.');" 
+                                                                          title="It will generate a new key Pair and your current credentials will be overwritten."/>
+                                               </td> 
+                                       </tr>
+                                       <tr class="odd">
+                                               <td class="key">Public Key</td>
+                                               <td class="value">
+                                                               <span id="keyval" class="value">******** </span>
+                                                               <span class="hide_this" id="span_upload">
+                                                                       <button type="button" class="btn btn-default" title="Cancel" id="cancel_upload"> Cancel </button>
+                                                                       <div style='display:none;'>
+                                                                               <input type='hidden'  name='upload'  /></div>
+                                                                               <input type="file" name="pubkey" class="required" id="pubkey"/>  
+                                                                               <input class="btn btn-default btn-xs" name="upload_key" id="upload_key"  type="submit" title="Upload your public key" value="Upload"
+                                                                                  onclick="return confirm('Are you sure? It will overwrite your current credentials and you have delegate it manually.');"/>
+                                                               </span>
+                                                               <div style='display:none;'> <input type='hidden'  name='dload'  /> </div> 
+                                                               <button type="submit" name="dl_pubkey" class="btn btn-default btn-xs" title="Download your public key" id="dl_file">
+                                                                       <span class="glyphicon glyphicon-download"></span> Download
+                                                               </button>
+                                                               <button class="btn btn-default btn-xs" id="upload_file" type="button" title="Upload a public key">
+                                                                       <span class="glyphicon glyphicon-upload"></span> Upload
+                                                               </button>       
+                                               </td>
+                                       </tr>
+                                       <tr class="even" id="pkey_row">
+                                                {%if 'N/A' not in user_private_key%}
+                                               <td class="key">Private Key </td> <!-- Hide if priv_key doesn't exist in myslice platform   -->
+                                               <td class="value">********<a href="#"></a>
+                                                       <button type="submit" name="dl_pkey" class="btn btn-default" title="Download your privaye key" id="dl_pkey">
+                                                                       <span class="glyphicon glyphicon-download"></span> Download     
+                                                               </button>
+                                                       <input class="btn btn-danger btn-xs" id="delete" name="delete" type="submit"  value="Delete" title="Delete your private key"
+                                                                               onclick="return confirm('Are you sure? If you do so, you have to delegate your credentials manually.');"/> 
+                                               </td>
+                                                 {%else%}
+                                                       <td class="key">Private Key </td> <!-- Hide if priv_key doesn't exist in myslice platform   -->
+                                                       <td class="value">********<a href="#"></a>
+                                                       <button type="submit" name="dl_pkey" class="btn btn-default disabled" title="Download your privaye key" id="dl_pkey">
+                                                               <span class="glyphicon glyphicon-download"></span> Download 
+                                                       </button>
+                                                       <input class="btn btn-danger btn-xs disabled" id="delete" name="delete" type="submit" title="Delete your private key" value="Delete" />
+                                                       </td>
+                                                {%endif%}              
+                                               </tr>
+                                               <tr class="even">
+                                               <td colspan="2">
+                                                       <p class="message" id="pkey_del_msg"><b> Tradeoff:</b> Ease-of-use vs Security.<br>
+                                                                       <b>Ease-of-use:</b> Automatic account delegation. Don't delete private key.<br>
+                                                                       <b>Security:</b> Manual account delegation. Download & Delete private key.
+                                                               </p>
+                                               </td>
+                                               </tr>
+                                               {%endif%}
+                                       </table>
+                       
+               </div>
+       </div>
+
+       <div class="tab-pane row" id="account">
+               <div class="col-md-12">
+       
+               <h3>Principal Account <small>Account used for delegating credentials</small></h3>
+               <table class="table"> 
+                       <tr class="odd"> 
+                       <th>Platform</th> 
+                       <th>Account Type</th>
+                               <th>Account Delegation</th>
+                       <th>User hrn</th>
+                               <th>User Status</th>
+                       <!--<th>Pub Key</th> -->
+               </tr>   
+                       {% for row in principal_acc %}         
+                       <tr class="border_bottom">
+                       <td class="odd"> {{ row.platform_name }} </td>
+                       <td class="odd"> {{ row.account_type }} </td>
+                               <td class="odd"> {{ row.delegation_type }} </td>
+                               <td class="odd"> {{ row.usr_hrn }}  </td>
+                               <td class="odd"> {{ row.user_status }}  </td>
+               <!--    <td class="even"> {{ row.usr_pubkey }} </td> -->
+               </tr> 
+                       {%endfor%}               
+               </table>
+       
+               </div>
+       
+
+       {%if 'Enabled'  in user_status %}
+               <div class="col-md-12">
+               <h3>Credentials <small>Delegated to Principal Account</small></h3>
+                       <table class="table">
+                                       <caption><b>Delegated User Credential</b></caption> 
+                           <tr class="odd"> 
+                               <th>Expiration Date</th>
+                                               <th>Download</th>
+                           </tr>
+                                       {% for row in my_users %}         
+                                       <tr class="border_bottom">
+                                       <td class="odd"> {{ row.cred_exp }} </td>
+                                               <td class="odd">
+                                                       <button class="btn btn-default btn-xs" name= "dl_user_cred" type="submit" title="Download User Credential">
+                                                               <span class="glyphicon glyphicon-download"></span> Credential
+                                                       </button>
+                                                       <button class="btn btn-default btn-xs" name= "dl_user_cert" type="submit" title="Download User Certificate">
+                                                               <span class="glyphicon glyphicon-download"></span> Certificate
+                                                       </button>
+                             <button class="btn btn-default btn-xs" name= "dl_user_p12" type="submit" title="Download User PKCS12">
+                                 <span class="glyphicon glyphicon-download"></span> PKCS p12
+                             </button>
+                                               </td>
+                                       </tr>
+                                       {%endfor%}
+                                </table>
+                               <p></p>
+                               <table class="mytable table table-bordered table-hover">
+                                       <caption><b>Delegated Slice Credentials</b></caption>  
+                               <tr class="odd"> 
+                                               <th>Slice Name</th> 
+                                       <th>Expiration Date</th>
+                                               <th>Download</th>
+                               </tr>
+                                       {% for row in my_slices %}     
+                               <tr class="border_bottom">
+                                       <td class="odd"> {{ row.slice_name }} </td>
+                                               <td class="odd"> {{ row.cred_exp }} </td>
+                                               <td class="odd"> 
+                                                       <button class="btn btn-default btn-xs" name= "dl_{{row.slice_name}}" type="submit" title="Download Slice Credentials">
+                                                               <span class="glyphicon glyphicon-download"></span> Download
+                                                       </button> 
+                                               </td>
+                               </tr>
+                               {%endfor%}
+                               </table>
+                               <p></p>
+                               <table class="mytable table table-bordered table-hover">
+                                       <caption><b>Delegated Authority Credentials</b></caption>
+                                       <tr class="odd"> 
+                                       <th>Authority Name</th> 
+                                       <th>Expiration Date</th>
+                                               <th>Download</th>
+                                       </tr>
+                                       {% for row in my_auths %}
+                                       <tr class="border_bottom">
+                                       <td class="odd"> {{ row.auth_name }} </td>
+                                       <td class="odd"> {{ row.cred_exp }} </td>
+                                               <td class="odd">
+                                                       <button class="btn btn-default btn-xs" name= "dl_{{row.auth_name}}" type="submit" title="Download Authority Credentials">
+                                                               <span class="glyphicon glyphicon-download"></span> Download
+                                                       </button>
+                                               </td>
+                                       </tr>
+                                       {%endfor%}
+                               </table>
+                               <p></p>
+                                {%if '' not in my_users%}      
+                               <p><button class="btn btn-danger btn-lg btn-block"   name= "clear_cred" type="submit" title="Clear All Credentials">Clear Credentials</button></p>
+                               {%else%}
+                               <p><button class="btn btn-danger btn-lg btn-block disabled"   name= "clear_cred" type="submit" title="Clear All Credentials">Clear Credentials</button></p>
+                               {%endif%}
+               </div>
+       </div>
+<!-- Modal- No credentials -->
+<div class="modal fade" id="myModal" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
+            <div class="modal-dialog">
+                <div class="modal-content">
+                    <div class="modal-header">
+                        <button type="button" class="close" data-dismiss="modal" aria-hidden="true">&times;</button>
+                            <h4 class="modal-title" id="myModalLabel">No credentials are delegated to the portal</h4>
+                    </div>
+                    <div class="modal-body">
+                                       <p>You may get this message for several reasons.</p>
+                                       <h3>Account Delegation: Automatic</h3>
+                                       <ul>
+                                               <li>If your account is not yet validated</li>
+                                               <li>If you press the "Clear Credentials" button</li>
+                                               <li>If you "Generate a new key pair"</li>
+                                               <li>If a new slice is added to your account</li>
+                                       </ul>
+                                       <p>In all the above mentioned cases, it is sufficient to refresh the page or go back to home page. The portal will regenrate your credentials.
+                                        In some cases it may take more time than usual. If nothing works, then please logout and login again to the portal.</p>
+                                       <h3>Account Delegation: Manual</h3>
+                                               <p>First of all your account needs to be validated by the manager of your organization.</p>
+                                               <p>As you have uploaded your own public key, the portal can no longer generate your credentials automatically.</p>
+                                               <p>In order for the portal to contact testbeds on your behalf, so as to list and reserve resources, you will need to
+                                               <a href="/portal/manual_delegation" target="_blank">delegate your credentials to the portal.</a>
+                                       </p>
+                                       <h5>Contact support</h5>
+                                       <p>If you don't have the above mentioned cases and still have this message, please  <a href="/contact/" target="_blank">contact us</a>.</p>
+                    </div>
+                    <div class="modal-footer">
+                        <button type="button" class="btn btn-default" data-dismiss="modal">Close</button>
+                    </div>
+                </div>
+            </div>
+</div>
+
+
+       <div class="tab-pane row" id="access">
+               <div class="col-md-12">
+       
+               <h3>Testbed Access <small>Reference Accounts in the following testbeds</small></h3>
+        <table class="mytable table table-bordered table-hover"> 
+            <tr class="odd"> 
+                <th>Platform</th> 
+                <th>Account Type</th>
+                               <th>Reference to</th>
+                               <th>Remove Account</th>
+            </tr>   
+            {% for row in ref_acc %}         
+            <tr class="border_bottom">
+                <td class="odd"> {{ row.platform_name }} </td>
+                <td class="odd"> {{ row.account_type }} </td>
+                               <td class="odd"> {{ row.account_reference }} </td>
+                               <td class="odd">
+                               <button class="btn btn-danger" name="delete_{{row.platform_name}}" type="submit" title="Delete account from this platform">
+                                               <span class="glyphicon glyphicon-minus"></span>
+                                       </button>
+                               </td>
+            </tr> 
+            {%endfor%}               
+        </table>               
+               
+               
+               <h3>Add reference account to the following testbeds</h3>
+        <table class="mytable table table-bordered table-hover"> 
+            <tr class="odd"> 
+                <th>Platforms</th> 
+                <th>Add Account</th>
+            </tr>   
+            {% for platform in platform_list %}         
+            <tr class="border_bottom">
+                <td class="odd"> {{ platform.platform_no_access }} </td>
+                <td class="odd">
+                                       <button class="btn btn-success btn-sm" name= "add_{{platform.platform_no_access}}" type="submit" title="Add account to this platform">
+                                               <span class="glyphicon glyphicon-plus"></span>
+                                       </button>
+                               </td>
+            </tr> 
+            {%endfor%}               
+        </table>
+       </div>
+{%endif%} 
+</div>
+</form>
+</div>
+
+<script>
+    $(document).ready(function() {
+       $('.nav-tabs a').click(function (e) {
+                       e.preventDefault();
+                       $(this).tab('show');
+                       id = $(this).attr('href').substr(1);
+               
+               });
+               
+        $('button#createslice').click(function() {
+            window.location="/portal/slice_request/";
+        });
+    });
+</script>
+
+{% endblock %}
diff --git a/portal/templates/smartfire/smartfire_footer.html b/portal/templates/smartfire/smartfire_footer.html
new file mode 100644 (file)
index 0000000..307f7d3
--- /dev/null
@@ -0,0 +1,16 @@
+<div class="footer">
+<div class="container">
+    <div class="row">
+        <div class="col-md-12">
+            <ul>
+                <li></li>
+            </ul>
+        </div>
+    </div>
+    <div class="row">
+        <div class="col-md-12 copy">
+            
+        </div>
+    </div>
+</div>
+</div>
\ No newline at end of file
diff --git a/portal/templates/smartfire/smartfire_home-view.html b/portal/templates/smartfire/smartfire_home-view.html
new file mode 100644 (file)
index 0000000..8236fc5
--- /dev/null
@@ -0,0 +1,189 @@
+{% extends "layout_base.html" %}
+{% load portal_filters %}
+
+{% block content %}
+<!-- <div class="row">
+{% widget '_widget-news.html' %}
+</div> -->
+{% if username %}
+<div class="container dashboard">
+       <div class="row">
+               {%if 'is_pi'  in pi %}
+               <div class="col-md-3">
+                       <h3>
+                               EXPERIMENT
+                       </h3>
+                       <div>
+                               <a href="#"><img src="{{ STATIC_URL }}img/icon_slices.png" alt="" /></a>
+                       </div>
+                       <div>
+                               <button id="slicerequestbtn" type="button" class="btn btn-default"><span class="glyphicon glyphicon-plus"></span> Create Slice</button>
+                       </div>
+                       <div>
+                               <p><strong>Your slices </strong>
+                                       <span title="A slice is a set of testbed resources on which you can conduct an experiment. 
+                                       Either ask your colleagues to give you access to an existing slice or request a new slice by clicking 'Request Slice'. 
+                                       However, on the OneLab portal, you will only see slices that you have created through OneLab. If you have created slices elsewhere, 
+                                       such as on the PlanetLab Europe portal, those slices will not appear here."
+                                       class="glyphicon glyphicon-info-sign">
+                               </span>
+
+                               </p>
+                       </div>
+                       <div>   
+                               <div id="home-slice-list"><img src="{{ STATIC_URL }}img/loading.gif" alt="Loading Slices" /></div>
+                       </div>
+               </div>
+               <div class="col-md-3">
+                       <h3>MANAGEMENT</h3>
+                       <div>
+                               <a href="/portal/institution"><img src="{{ STATIC_URL }}img/icon_authority_color.png" alt="" /></a>
+                       </div>
+                       <div>
+                               <button id="validaterequestbtn" type="button" class="btn btn-default"><span class="glyphicon glyphicon-ok"></span> Validate Requests</button>
+                       </div>
+               </div>
+               <div class="col-md-3">
+                       <h3>
+                               SUPPORT
+                       </h3>
+                       <div>
+                               <a href="/portal/support"><img src="{{ STATIC_URL }}img/icon_support.png" alt="" /></a>
+                       </div>
+                       <div>
+                               <button id="ticketbtn" type="button" class="btn btn-default"><span class="glyphicon glyphicon-envelope"></span> Contact</button>
+                       </div>
+               </div>
+               
+               <div class="col-md-3">
+                       <h3>
+                               ACCOUNT
+                       </h3>
+                       <div>
+                               <a href="/portal/account/"><img src="{{ STATIC_URL }}img/icon_user_color.png" alt="" /></a>
+                       </div>
+                       <div>
+                               <button id="logoutbtn" type="button" class="btn btn-default" data-username="{{ username }}"><span class="glyphicon glyphicon-off"></span> Logout</button>
+                       </div>
+                       <div>
+                               {% if person.last_name %}
+                                       {{person.first_name}} {{person.last_name}}<br />
+                               {% endif %}
+                       <span class="label">Username:</span> <a href='/portal/account/' title="Click here to see and edit your account details.">{{person.email}}</a>
+               </div>
+               </div>
+       </div>
+       {%else%}
+       <div class="row">
+               <div class="col-md-4">
+                       <h3>
+                               EXPERIMENT
+                       </h3>
+                       <div>
+                               <a href="#"><img src="{{ STATIC_URL }}img/icon_slices.png" alt="" /></a>
+                       </div>
+                       <div>
+                               <button id="slicerequestbtn" type="button" class="btn btn-default"><span class="glyphicon glyphicon-plus"></span> Request Slice</button>
+                       </div>
+                       <div>
+                               <p><strong>Your slices </strong>
+                               <span title="A slice is a set of testbed resources on which you can conduct an experiment. 
+                                       Either ask your colleagues to give you access to an existing slice or request a new slice by clicking 'Request Slice'. 
+                                       However, on the OneLab portal, you will only see slices that you have created through OneLab. If you have created slices elsewhere, 
+                                       such as on the PlanetLab Europe portal, those slices will not appear here."
+                                       class="glyphicon glyphicon-info-sign">
+                               </span>
+                               </p>
+                       </div>
+                       <div>   
+                               <div id="home-slice-list"><img src="{{ STATIC_URL }}img/loading.gif" alt="Loading Slices" /></div>
+                       </div>
+               </div>
+               <div class="col-md-4">
+                       <h3>
+                               SUPPORT
+                       </h3>
+                       <div>
+                               <a href="/portal/support"><img src="{{ STATIC_URL }}img/icon_support.png" alt="" /></a>
+                       </div>
+                       <div>
+                               <button id="ticketbtn" type="button" class="btn btn-default"><span class="glyphicon glyphicon-envelope"></span> Contact</button>
+                       </div>
+               </div>
+               
+               <div class="col-md-4">
+                       <h3>
+                               ACCOUNT
+                       </h3>
+                       <div>
+                               <a href="/portal/account/"><img src="{{ STATIC_URL }}img/icon_user_color.png" alt="" /></a>
+                       </div>
+                       <div>
+                               <button id="logoutbtn" type="button" class="btn btn-default" data-username="{{ username }}"><span class="glyphicon glyphicon-off"></span> Logout</button>
+                       </div>
+                       <div>
+                               {% if person.last_name %}
+                                       {{person.first_name}} {{person.last_name}}<br />
+                               {% endif %}
+                       <span class="label">Username:</span> <a href='/portal/account/' title="Click here to see and edit your account details.">{{person.email}}</a>
+               </div>
+               </div>
+       </div>
+       {%endif%}
+
+</div>
+{% else %}
+<div class="container-fluid home">
+       <div class="">
+               <div class="col-sm-2"></div>
+               <div class="col-sm-4 slogan">
+                       <h2>
+                               SmartFIRE
+                       </h2>
+                       <h3>
+                               EU-South Korea Cooperation<br>
+                               On Future Internet Infrastructure
+                       </h3>
+               </div>
+               <div class="col-sm-5 col-sm-offset-1">
+                       <div class="row">
+                               {% widget '_widget-login-user.html' %}
+                       </div>
+               </div>
+               <div class="col-sm-1"></div>
+       </div>
+</div>
+{% endif %}
+
+
+<script type="text/javascript">
+       $(document).ready(function() {
+               $('a.home-tab').click(function() {
+                       $('ul.nav-tabs li').removeClass('active');
+                       $(this).parent().addClass('active');
+                       $('div.home-panel').hide();
+                       $('div#'+$(this).data('panel')).show();
+               });
+               $('button#validaterequestbtn').click(function() {
+                       window.location="/portal/institution#requests";
+               });
+               $('button#ticketbtn').click(function() {
+                       window.location="/portal/contact/";
+               });
+               $('button#signupbtn').click(function() {
+                       window.location="/portal/register/";
+               });
+               $('button#slicerequestbtn').click(function() {
+                       window.location="/portal/slice_request/";
+               });
+/*-------
+List of slices has been moved in 
+portal/templates/base.html
+This should go into session
+--------*/
+});
+</script>
+{# widget "_widget-monitor.html" #}
+{# widget "_widget-stats-top-slices.html" #}
+
+{% endblock %}
diff --git a/portal/templates/smartfire/smartfire_institution.html b/portal/templates/smartfire/smartfire_institution.html
new file mode 100644 (file)
index 0000000..bd361de
--- /dev/null
@@ -0,0 +1,185 @@
+{% extends "layout_wide.html" %}
+
+{% block head %} 
+<script type="text/javascript" src="{{STATIC_URL}}/js/institution.js"></script>
+{% endblock head %}
+
+{% block content %}
+<div class="container">
+       <div class="row">
+               <div class="col-md-12">
+                        <div class="breadcrumbs">
+                                Management &nbsp;>&nbsp; Institution: <span id="authority_name"></span>
+                        </div>
+               </div>
+       </div>
+</div>
+<div class="container">
+       <div class="row">
+               <div class="col-md-12">
+                       <ul class="nav nav-tabs nav-section">
+                               <li class="active"><a href="#about">About</a></li>
+                               <li><a href="#users">Users</a></li>
+                               <li><a href="#slices">Slices</a></li>
+                               <li><a href="#requests">Requests</a></li>
+                       </ul>
+           </div>
+       </div>
+</div>
+<div class="container tab-content">
+       <div class="tab-pane active row" id="about">
+       </div>
+       
+       <div class="tab-pane row" id="users" data-authority="{{user_details.parent_authority}}">
+               <div class="col-md-12 el">
+                       <div id="user-tab-loading"><img src="{{ STATIC_URL }}img/loading.gif" alt="Loading Slices" /></div>
+                               <div id="user-tab-loaded" style="display:none;">
+                               <table id="user-tab" class="table">
+                                       <tr>
+                                       <th>+/-</th>
+                                       <th>Email</th>
+                                       <th>User hrn</th>
+                            <!--
+                                       <th>First name</th>
+                                       <th>Last name</th>
+                                       <th>Enabled</th>
+                            -->
+                                       </tr>
+                               </table>
+                               
+                       </div>
+                       {%if 'is_pi'  in pi %}  
+                       <div>
+                               <button id="deleteusers" type="button" class="btn btn-danger"><span class="glyphicon glyphicon-remove"></span> Delete selected users</button>
+                       </div>
+                       {% endif %}
+               </div>
+       </div>
+
+       <div class="tab-pane row" id="slices">
+               <div class="col-md-12 el">
+           <div id="slice-tab-loading"><img src="{{ STATIC_URL }}img/loading.gif" alt="Loading Slices" /></div>
+           <div id="slice-tab-loaded" style="display:none;">
+               <table id="slice-tab" class="table">
+                   <tr>
+                       <th>+/-</th>
+                       <th>Slice hrn</th>
+                       <th>Users</th>
+                       <th>Url</th>
+                       <!-- <th>nodes</th> -->
+                       <th>Creation</th>
+                   </tr>
+               </table>                        
+           </div>
+       {% if 'is_pi'  in pi %}
+        <div>
+               {% if 'is_pi'  in pi %}
+                       <button id="createslice" type="button" class="btn btn-default"><span class="glyphicon glyphicon-plus"></span> Create slice</button>
+                       {% else %}
+                       <button id="createslice" type="button" class="btn btn-default"><span class="glyphicon glyphicon-plus"></span> Request slice</button>
+                       {% endif %}
+            <button id="renewslices" type="button" class="btn btn-primary"><span class="glyphicon glyphicon-refresh"></span> Renew Slices</button>
+            <button id="deleteslices" type="button" class="btn btn-danger"><span class="glyphicon glyphicon-remove"></span> Delete Slices</button>
+        </div>
+               {% endif %} 
+          </div>
+       </div>
+       <div class="tab-pane row" id="requests">
+       </div>
+</div>
+<script>
+$(document).ready(function() {
+    {% if person %}
+    {% if user_details.parent_authority %}
+
+        $.post("/rest/slice/",{'fields':['slice_hrn','users','url','slice_date_created'],'filters':{'parent_authority':'{{user_details.parent_authority}}'}}, function( data ) {
+            var list_slices = [];
+            var table_slices = [];
+            /* "slice_hrn", "slice_description", "slice_type", "parent_authority", "created", "nodes", "slice_url", "slice_last_updated", "users", "slice_urn", "slice_expires" */
+            $.each( data, function( key, val ) {
+                list_slices.push( "<li><a href=\"portal/slice/"+val.slice_hrn+"\">" + val.slice_hrn + "</a></li>" );
+                if(val.nodes=="undefined" || val.nodes==null){
+                    nodes_length=0;
+                }else{
+                    nodes_length=val.nodes.length;
+                }
+                console.log(val);
+                if(val.users=="undefined" || val.users==null){
+                    users_length=0;
+                }else{
+                    users_length=val.users.length;
+                }
+
+                if(val.url=="undefined" || val.url==null){
+                    slice_url="";
+                }else{
+                    slice_url="<a href='"+val.url+"' target='_blank'>"+val.url+"</a>";
+                }
+                
+                slice_row = "<tr id='"+val.slice_hrn+"'>";
+                slice_row += "<td><input type='checkbox' class='slice' id='"+val.slice_hrn+"'></td>";
+                slice_row += "<td><a href=\"/slice/"+val.slice_hrn+"\">" + val.slice_hrn + "</a></td>";
+                slice_row += "<td>"+users_length+"</td>";
+                slice_row += "<td>"+slice_url+"</td>";
+                //slice_row += "<td>"+nodes_length+"</td>";
+                slice_row += "<td>"+val.slice_date_created+"</td>";
+                slice_row += "</tr>";
+                table_slices.push(slice_row);
+                
+            });
+           
+            /* $("div#slice-list").html($( "<ul/>", { html: list_slices.join( "" ) })); */
+            $("table#slice-tab tr:last").after(table_slices.join( "" ));
+            $("div#slice-tab-loaded").css("display","block");
+            $("div#slice-tab-loading").css("display","none");
+        });
+               
+               
+        $.post("/rest/user/",{'fields':['user_hrn','user_email'],'filters':{'parent_authority':'{{user_details.parent_authority}}'}}, function( data ) {
+            var list_users = [];
+            var table_users = [];
+                   /* Available fields
+                   user_gid, user_enabled, slices, pi_authorities, keys, parent_authority, user_first_name,
+                   user_urn, user_last_name, user_phone, user_hrn, user_email, user_type
+                   */
+            $.each( data, function( key, val ) {
+                list_users.push( "<li><a href=\"portal/user/"+val.user_email+"\">" + val.user_email + "</a></li>" );
+                user_row = "<tr id='"+val.user_hrn+"'>";
+                user_row += "<td><input type='checkbox' class='user' id='"+val.user_hrn+"'></td>";
+                user_row += "<td>"+val.user_email+"</td>";
+                user_row += "<td>"+val.user_hrn+"</td>";
+                /*
+                user_row += "<td>"+val.user_first_name+"</td>";
+                user_row += "<td>"+val.user_last_name+"</td>";
+                           user_row += "<td>"+val.user_enabled+"</td>";
+                */
+                user_row += "</tr>";
+                table_users.push(user_row);
+            });
+            $("table#user-tab tr:last").after(table_users.join( "" ));
+            $("div#user-tab-loaded").css("display","block");
+            $("div#user-tab-loading").css("display","none");
+        });
+
+    {% endif %}
+    {% endif %}
+
+}); // End document.ready
+
+$(document).ready(function() {
+       $('.nav-tabs a').click(function (e) {
+               e.preventDefault();
+               $(this).tab('show');
+       var id = $(this).attr('href').substr(1);
+       if ((id == 'requests') || (id == 'about'))
+               $("#" + id).load('/management/' + id);
+       });
+       var hash = window.location.hash;
+       if (hash) {
+               $('.nav-tabs a[href='+hash+']').click();
+       } else {
+               $('.nav-tabs a[href=#about]').click();
+       }
+});
+</script>
+{% endblock %}
diff --git a/portal/templates/smartfire/smartfire_management-tab-requests.html b/portal/templates/smartfire/smartfire_management-tab-requests.html
new file mode 100644 (file)
index 0000000..e255779
--- /dev/null
@@ -0,0 +1,226 @@
+<script type="text/javascript">
+       $(document).ready(function() {
+               $("li#nav-request").addClass("active");
+       });
+       function on_click_event() {
+               var ids = []; 
+               $('.portal__validate__checkbox').each(function(i, el) {
+                       if ($(el).prop('checked')) {
+                               // portal__validate__checkbox__slice__2
+                               var id_array = $(el).attr('id').split('__');
+                               // push(slice__2)
+                               ids.push(id_array[3] + '__' + id_array[4]);
+                       }
+               });
+               if (ids.length > 0) {
+                       var id_str = ids.join('/');
+                       // XXX spinner
+                       $.getJSON('/portal/validate_action/' + id_str,
+                               function(status) {
+                                       $.each(status, function(request_type__id, request_status) {
+                                               // request_status: NAME -> dict (status, description)
+                                               var status_str = '';
+                                               $.each(request_status, function(name, result) {
+                                                       if (status_str != '')
+                                                               status_str += ' -- ';
+
+                                                       if (result.status) {
+                                                               status_str += '<font color="green">OK</font>';
+                                                               $('#portal__validate__checkbox__' + request_type__id).hide();
+                                                       } else {
+                                                               status_str += '<font color="red">ERROR: ' + result.description + '</font>';
+                                                       }
+                                               });
+                                               $('#portal__status__' + request_type__id).html(status_str);
+
+
+                                       });
+                               }
+                       );
+               }
+       }
+</script>
+
+<div class="col-md-12">
+       <h2>From your authorities</h2>
+</div>
+{% if my_authorities %}
+       
+       {% for authority, requests in my_authorities.items %}
+       
+       <div class="col-md-12">
+               <h2>{{authority}}</h2>
+       </div>
+       
+    <table class="table">
+      <th>
+        <td>Type</td>
+        <td>Id</td>
+        <td>Details</td>
+        <td>Timestamp</td>
+        <td>Status</td>
+      </th>
+    {% for request in requests %}
+
+         <tr>
+               <td>
+               {% if request.allowed == 'allowed' %}
+               <input class='portal__validate__checkbox' id='portal__validate__checkbox__{{request.type}}__{{request.id}}' type='checkbox'/>
+               {% else %}
+                       {% if request.allowed == 'expired' %}
+                               expired
+                       {% else %} {# denied #}
+                               denied
+                       {% endif %}
+               {% endif %}
+               </td>
+               <td>{{ request.type }}</td>
+               <td>{{ request.id }}</td>
+               <td>
+        {% if request.type == 'user' %}
+            <b>{{request.first_name}} {{request.last_name}}</b> <a href="mailto:{{request.email}}">{{request.email}}</a>
+        {% else %}
+            {% if request.type == 'slice' %}
+            <b>{{request.slice_name}}</b> -- Number of nodes: {{request.number_of_nodes}} -- Type of nodes: {{request.type_of_nodes}} -- Purpose: {{request.purpose}}
+            {% else %} {# authority #}
+            <b>{{request.site_name}}</b> ({{request.site_authority}}) -- {{request.address_city}}, {{request.address_country}}
+            {% endif %}
+        {% endif %}
+               </td>
+               <td>{{ request.timestamp }}</td>
+               
+               <td><span id='portal__status__{{request.type}}__{{request.id}}'></span></td>
+
+    <!--<div class='portal_validate_request {{request.type}} {% if forloop.counter|divisibleby:2 %}even{% else %}odd{% endif %}'> -->
+         </tr>
+
+    {% endfor %}
+       </table>
+       {% endfor %}
+
+{% else %}
+       <div class="col-md-12">
+               <i>There is no pending request waiting for validation.</i>
+       </div>
+{% endif %}
+<div>nnllknjkn<br /><br /></div>
+<div class="col-md-12">
+       <h2>From your sub-authorities</h2>
+</div>
+{% if sub_authorities %}
+       
+       {% for authority, requests in sub_authorities.items %}
+       <div class="col-md-12">
+               <h2>{{authority}}</h2>
+       </div>
+       
+       <table class="table">
+             <th>
+               <td>Type</td>
+               <td>Id</td>
+               <td>Details</td>
+               <td>Timestamp</td>
+               <td>Status</td>
+             </th>
+           {% for request in requests %}
+                 <tr>
+                       <td>
+                       {% if request.allowed == 'allowed' %}
+                       <input class='portal__validate__checkbox' id='portal__validate__checkbox__{{request.type}}__{{request.id}}' type='checkbox'/>
+                       {% else %}
+                               {% if request.allowed == 'expired' %}
+                                       expired
+                               {% else %} {# denied #}
+                                       denied
+                               {% endif %}
+                       {% endif %}
+                       </td>
+                       <td>{{ request.type }}</td>
+                       <td>{{ request.id }}</td>
+                       <td>
+               {% if request.type == 'user' %}
+               Login: {{request.login}} -- First name: {{request.first_name}} -- Last name: {{request.last_name}} -- Email: {{request.email}}
+               {% else %}
+                   {% if request.type == 'slice' %}
+               Slice name: {{request.slice_name}} -- Number of nodes: {{request.number_of_nodes}} -- Type of nodes: {{request.type_of_nodes}} -- Purpose: {{request.purpose}}
+                   {% else %} {# authority #}
+               Authority name: {{request.site_name}} -- authority_hrn: {{request.site_authority}} -- City: {{request.address_city}} -- Country: {{request.address_country}}
+                   {% endif %}
+               {% endif %}
+                       </td>
+                       <td>{{ request.timestamp }}</td>
+                       
+                       <td><span id='portal__status__{{request.type}}__{{request.id}}'></span></td>
+       
+           <!--<div class='portal_validate_request {{request.type}} {% if forloop.counter|divisibleby:2 %}even{% else %}odd{% endif %}'> -->
+                 </tr>
+           {% endfor %}
+       </table>
+       {% endfor %}
+{% else %}
+<div class="col-md-12">
+       <i>There is no pending request waiting for validation.</i>
+</div>
+{% endif %}
+
+<div class="col-md-12">
+       <h2>From your authorities with delegation</h2>
+</div>
+
+{% if delegation_authorities %}
+       
+       {% for authority, requests in delegation_authorities.items %}
+       <div class="col-md-12">
+               <h3>{{authority}}</h3>
+       </div>
+       <table class="table">
+                     <th>
+                       <td>Type</td>
+                       <td>Id</td>
+                       <td>Details</td>
+                       <td>Timestamp</td>
+                       <td>Status</td>
+                     </th>
+                   {% for request in requests %}
+                         <tr>
+                               <td>
+                               {% if request.allowed == 'allowed' %}
+                               <input class='portal__validate__checkbox' id='portal__validate__checkbox__{{request.type}}__{{request.id}}' type='checkbox'/>
+                               {% else %}
+                                       {% if request.allowed == 'expired' %}
+                                               expired
+                                       {% else %} {# denied #}
+                                               denied
+                                       {% endif %}
+                               {% endif %}
+                               </td>
+                               <td>{{ request.type }}</td>
+                               <td>{{ request.id }}</td>
+                               <td>
+                       {% if request.type == 'user' %}
+                       Login: {{request.login}} -- First name: {{request.first_name}} -- Last name: {{request.last_name}} -- Email: {{request.email}}
+                       {% else %}
+                           {% if request.type == 'slice' %}
+                       Slice name: {{request.slice_name}} -- Number of nodes: {{request.number_of_nodes}} -- Type of nodes: {{request.type_of_nodes}} -- Purpose: {{request.purpose}}
+                           {% else %} {# authority #}
+                       Authority name: {{request.site_name}} -- authority_hrn: {{request.site_authority}} -- City: {{request.address_city}} -- Country: {{request.address_country}}
+                           {% endif %}
+                      {% endif %}
+                               </td>
+                               <td>{{ request.timestamp }}</td>
+                               
+                               <td><span id='portal__status__{{request.type}}__{{request.id}}'></span></td>
+               
+                   <!--<div class='portal_validate_request {{request.type}} {% if forloop.counter|divisibleby:2 %}even{% else %}odd{% endif %}'> -->
+                         </tr>
+                   {% endfor %}
+       </table>
+               {% endfor %}
+{% else %}
+<div class="col-md-12">
+       <i>There is no pending request waiting for validation.</i>
+</div>
+{% endif %}
+<div class="col-md-12">
+       <button class="btn btn-onelab" type="button" id="portal__validate" onclick="on_click_event();"><span class="glyphicon glyphicon-ok"></span> Validate</button>
+</div>
diff --git a/portal/templates/smartfire/smartfire_slicerequest_view.html b/portal/templates/smartfire/smartfire_slicerequest_view.html
new file mode 100644 (file)
index 0000000..211f35d
--- /dev/null
@@ -0,0 +1,108 @@
+{% extends "layout.html" %}
+{% load i18n %}
+
+{% block content %}
+       <div class="row">
+               <div class="col-md-12">
+                        <div class="breadcrumbs">
+                                Experiment &nbsp;>&nbsp; Request a new Slice
+                        </div>
+               </div>
+       </div>
+
+       {% if errors %}
+       <div class="row">
+               <div class="col-md-12">
+               <ul class="error">
+                 {% for error in errors %}
+                 <li>{{ error }}</li>
+                 {% endfor %}
+               </ul>
+               </div>
+       </div>
+       {% endif %}
+       
+       <div class="row">
+               <div class="col-md-8 el">
+                       <form role="form" method="post">
+                       {% csrf_token %}
+                         <div class="form-group" style="display:none">
+                           <input type="email" class="form-control" id="email" style="width:300px" value="{{ email }}" readonly="readonly">
+                         </div>
+                         <div class="form-group">
+                           <input type="text" class="form-control" name="slice_name" id="slice_name" style="width:300px" placeholder="Slice name" value="{{slice_name}}" 
+                               title="Please enter a name for your slice"required="required">
+                         </div>
+                         <div class="form-group">
+                               {%if 'is_pi'  in pi %}
+                               <input type="text" class="form-control" id="authority_hrn" name="org_name" style="width:300px" placeholder="Organization" 
+                               title="An authority responsible for vetting your slice" required="required">
+                               {%else%}
+                           <input type="text" class="form-control" id="authority_hrn" name="org_name" placeholder="Organization" style="width:300px;" 
+                               title="An authority responsible for vetting your slice" required="required" readonly>
+                               {%endif%}
+                         </div>
+                         <div class="form-group">
+                           <input type="text" class="form-control" name="url" id="url" style="width:300px" placeholder="Experiment URL (if one exists)"
+                               title="Please provide the url of your experiment if you have one." value="{{url}}">
+                         </div>
+                         <div class="form-group">
+                               <textarea id="purpose" name="purpose" class="form-control" rows="6" placeholder="Experiment purpose" style="width:300px" 
+                               title="Purpose of your experiment (informative)" required="required">{{ purpose }}</textarea>
+                         </div>
+                         {%if 'is_pi'  in pi %}        
+                         <button type="submit" id=submit_pi class="btn btn-onelab"><span class="glyphicon glyphicon-plus"></span> Create slice</button>
+                         {%else%}
+                         <button type="submit" class="btn btn-onelab"><span class="glyphicon glyphicon-plus"></span> Request slice</button>
+                         {%endif%}     
+                       </form>
+       
+               </div>
+       </div>
+               
+<script>
+jQuery(document).ready(function(){
+       
+       /*$("#authority_hrn").load("/rest/user/", {"fields" : ["parent_authority"], "filters": {"user_hrn": "{{ user_hrn }}"}}, function(data) {
+               var jsonData = JSON.parse(data);
+        $(this).attr("value", jsonData[0]['parent_authority']);
+    });*/
+       $("#authority_hrn").val("{{authority_name}}");
+       var availableTags = [
+    {% if authorities %}
+        {% for authority in authorities %}
+            {% if authority.name %}
+                {value:"{{ authority.name }}",label:"{{authority.name}}"},
+                       // to show only full name
+           // {% else %}
+           //     {value:"{{ authority.authority_hrn }}",label:"{{authority.authority_hrn}}"},
+            {% endif %}
+        {% endfor %}    
+    {% else %}
+        {value:"",label:"No authority found !!!"}
+    {% endif %}
+    ];
+       // sorting the list
+       availableTags.sort(function(a,b){
+               var nameA=a.value.toLowerCase(), nameB=b.value.toLowerCase();
+               if (nameA < nameB) {
+               return -1;
+               }
+               if (nameA > nameB) {
+               return 1;
+               }
+       return 0;
+       }); 
+    $( "#authority_hrn" ).autocomplete({
+      source: availableTags,
+      minLength: 0,
+      select: function( event, ui ) {console.log(jQuery(this));}
+    });
+
+       $("#submit_pi").click(function() {
+               localStorage.clear();
+       });
+});
+</script>
+{% endblock %}
+
diff --git a/portal/templates/smartfire/smartfire_widget-login-user.html b/portal/templates/smartfire/smartfire_widget-login-user.html
new file mode 100644 (file)
index 0000000..7529c61
--- /dev/null
@@ -0,0 +1,26 @@
+<div class="login-form">
+       {% if state %}
+       <span class="help-block">{{ state }}</span>
+       {% endif %}
+       <form action="/login/" method="post" role="form">
+         {% csrf_token %}
+         {% if next %}
+         <input type="hidden" name="next" value="{{ next }}" />
+         {% endif %}
+       <div class="form-group">
+       <input type="email" name="username" placeholder="Enter Email / Username">
+       </div>
+       <div class="form-group">
+       <input type="password" name="password" placeholder="Password">
+       </div>
+       <div class="login-submit">
+               <input type="submit" class="btn btn-onelab" value="Sign In" />
+               <span class="lost-password">&nbsp;&nbsp;&nbsp;|&nbsp;&nbsp;&nbsp;<a href="/portal/pass_reset/">Can't access your account?</a></span>
+       </div>
+       <div class="login-signup">
+               <!-- You don't have yet an account? 
+               
+               <a href="/register">Sign Up!</a> -->
+       </div>
+       </form>
+</div>
diff --git a/portal/templates/smartfire/smartfire_widget-topmenu.html b/portal/templates/smartfire/smartfire_widget-topmenu.html
new file mode 100644 (file)
index 0000000..738075f
--- /dev/null
@@ -0,0 +1,71 @@
+{% load portal_filters %}
+<div class="header">
+<div class="container">
+       <div class="row">
+               <div class="col-sm-3 col-md-3 logo">
+                       <a href="/"><img height="60" src="{{ STATIC_URL }}img/SmartFIRE_logo.png" alt="SmartFIRE | sinis.ipv6.lip6.fr Portal - SmartFIRE" /></a>
+               </div>
+               {% if username %}
+               <div class="col-sm-4 col-md-4 navigation">
+                       <ul>
+                               <li>
+                                       <a class="dropdown-toggle" data-toggle="dropdown" href="#">
+                                       EXPERIMENT <span class="caret"></span>
+                               </a>
+                                       
+                                       <div class="dropdown-menu" style="z-index:99;">
+                                                       <ul id="dropdown-slice-list">
+                                                               <li class="title"><a href="/portal/slice_request/">Request Slice</a></li>
+                                                       </ul>
+                                       </div>
+                               </li>
+                               {%if 'is_pi'  in pi %}  
+                               <li id="nav-institution" class=""><a href="/institution">MANAGEMENT</a></li>
+                                {%endif%}
+                               <li><a href="/support/">SUPPORT</a></li>
+                       </ul>
+               </div>
+               {% else %}
+               <div class="col-sm-4 col-md-4 navigation">
+               </div>
+               {% endif %}
+               <div class="col-sm-5 col-md-5 secondary">
+                       <ul>
+                               
+                               <!--<li><a target="_blank" href="http://status.testbeds.eu">Services Status</a></li> -->
+                               <li><a target="_blank" href="http://eukorea-fire.eu">Web site</a></li>
+                       </ul>
+                       {% if username %}
+                       <div class="account">You are logged in as &nbsp;<a href="/account/">{{ username }}</a> &nbsp;&nbsp;|&nbsp;&nbsp; <a id="logout" style="cursor:pointer;" data-username="{{ username }}"><span class="glyphicon glyphicon-off"></span> Logout</a></div>
+                       {% endif %}
+               </div>
+       </div>
+</div>
+</div>
+
+<div class="row">
+{% widget '_widget-message.html' %}
+</div>
+<script>
+       $(document).ready(function() {
+               $('li.slices').mouseenter(function() {
+                       $('div#menu-slice-list').fadeIn(100);
+               });
+               $('div#menu-slice-list').mouseleave(function(e) {
+                       if (!$('li.slices').is(":hover")) {
+                               $(this).fadeOut(100);
+                       }
+               });
+               // var slices = localStorage.getItem('slices');
+               // if (slices.length == 0) {
+                       // $.post("/rest/user/",{'filters':{'user_hrn':'$user_hrn'}}, function( data ) {
+                       // var items = [];
+                               // localStorage.setItem('slices', data[0].slice);
+                       // });
+               // }
+               // $.each(slices, function( key, val ) {
+                       // items.push( "<li><a href=\"/slice/"+val.slice_hrn+"\">" + val.slice_hrn + "</a></li>" );
+               // });
+               // $("div#home-slice-list").html($( "<ul/>", { html: items.join( "" ) }));
+       });
+</script>