Revision 85f1cd1e
b/snf-cyclades-app/synnefo/app_settings/default/ui.py | ||
---|---|---|
45 | 45 |
# Email from which the feedback emails will be sent from |
46 | 46 |
FEEDBACK_EMAIL_FROM = DEFAULT_FROM_EMAIL |
47 | 47 |
|
48 |
# URL to redirect user to when he logs out from the ui (if not set |
|
49 |
# settings.LOGIN_URL will be used) |
|
50 |
#LOGOUT_URL = "" |
|
48 |
# URL to redirect not authenticated users |
|
49 |
UI_LOGIN_URL = "/im/login" |
|
50 |
|
|
51 |
# URL to redirect user to when he logs out from the ui |
|
52 |
UI_LOGOUT_URL = "/im/logout" |
|
51 | 53 |
|
52 | 54 |
# Flavor options that we provide to the user as predefined |
53 | 55 |
# cpu/ram/disk combinations on vm create wizard |
b/snf-cyclades-app/synnefo/app_settings/urls.py | ||
---|---|---|
37 | 37 |
(r'^ui/', include('synnefo.ui.urls')), |
38 | 38 |
url(r'^machines/console$', 'synnefo.ui.views.machines_console', name='machines-console'), |
39 | 39 |
url(r'^machines/connect$', 'synnefo.ui.views.machines_connect', name='machines-connect'), |
40 |
(r'^admin/', include('synnefo.admin.urls')), |
|
41 | 40 |
(r'^api/', include('synnefo.api.urls')), |
42 | 41 |
(r'^plankton/', include('synnefo.plankton.urls')), |
43 | 42 |
) |
b/snf-cyclades-app/synnefo/ui/static/snf/js/auth.js | ||
---|---|---|
1 |
// Copyright 2012 GRNET S.A. All rights reserved. |
|
2 |
// |
|
3 |
// Redistribution and use in source and binary forms, with or |
|
4 |
// without modification, are permitted provided that the following |
|
5 |
// conditions are met: |
|
6 |
// |
|
7 |
// 1. Redistributions of source code must retain the above |
|
8 |
// copyright notice, this list of conditions and the following |
|
9 |
// disclaimer. |
|
10 |
// |
|
11 |
// 2. Redistributions in binary form must reproduce the above |
|
12 |
// copyright notice, this list of conditions and the following |
|
13 |
// disclaimer in the documentation and/or other materials |
|
14 |
// provided with the distribution. |
|
15 |
// |
|
16 |
// THIS SOFTWARE IS PROVIDED BY GRNET S.A. ``AS IS'' AND ANY EXPRESS |
|
17 |
// OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED |
|
18 |
// WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR |
|
19 |
// PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GRNET S.A OR |
|
20 |
// CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, |
|
21 |
// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT |
|
22 |
// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF |
|
23 |
// USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED |
|
24 |
// AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT |
|
25 |
// LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN |
|
26 |
// ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE |
|
27 |
// POSSIBILITY OF SUCH DAMAGE. |
|
28 |
// |
|
29 |
// The views and conclusions contained in the software and |
|
30 |
// documentation are those of the authors and should not be |
|
31 |
// interpreted as representing official policies, either expressed |
|
32 |
// or implied, of GRNET S.A. |
|
33 |
// |
|
34 |
|
|
35 |
;(function(root){ |
|
36 |
|
|
37 |
// Astakos client javascript lib |
|
38 |
// Requires jquery and jquery.cookie javascript libs |
|
39 |
// |
|
40 |
// Usage |
|
41 |
// ----- |
|
42 |
// <script src="jquery.js"></script> |
|
43 |
// <script src="jquery.cookie.js"></script> |
|
44 |
// <script src="snf/auth.js"></script> |
|
45 |
// |
|
46 |
// var astakos_config = { |
|
47 |
// 'login_url': '/im/login', |
|
48 |
// 'auth_url': '/im/authenticate', |
|
49 |
// 'cookie_name': '_pithos2_a', |
|
50 |
// 'logout_callback': function(client) { |
|
51 |
// console.log("logging out"); |
|
52 |
// client.redirect_to_logout(); |
|
53 |
// } |
|
54 |
// |
|
55 |
// var astakos_client = new snf.auth.AstakosClient(astakos_config); |
|
56 |
// var user = astakos_client.get_user(); |
|
57 |
// if (!user) { astakos_client.redirect_to_login() }; |
|
58 |
// console.log(user.username, user.token); |
|
59 |
// |
|
60 |
|
|
61 |
var root = root; |
|
62 |
var snf = root.synnefo = root.synnefo || {}; |
|
63 |
|
|
64 |
// init auth namespace |
|
65 |
snf.auth = {}; |
|
66 |
|
|
67 |
snf.auth.AstakosClient = function(config) { |
|
68 |
this.config = $.extend(this.default_config, config); |
|
69 |
} |
|
70 |
|
|
71 |
snf.auth.AstakosClient.prototype.default_config = { |
|
72 |
'logout_url': '/im/logout', |
|
73 |
'login_url': '/im/login', |
|
74 |
'cookie_name': '_pithos2_a', |
|
75 |
'logout_callback': function(client) { |
|
76 |
client.redirect_to_logout(); |
|
77 |
} |
|
78 |
} |
|
79 |
|
|
80 |
snf.auth.AstakosClient.prototype.delete_cookie = function() { |
|
81 |
$.cookie(this.config.cookie_name, null); |
|
82 |
} |
|
83 |
|
|
84 |
snf.auth.AstakosClient.prototype.redirect_to_logout = function() { |
|
85 |
window.location = this.config.logout_url; |
|
86 |
} |
|
87 |
|
|
88 |
snf.auth.AstakosClient.prototype.redirect_to_login = function() { |
|
89 |
window.location = this.config.login_url + "?next=" + window.location.toString(); |
|
90 |
} |
|
91 |
|
|
92 |
// delete cookie and redirect to logout |
|
93 |
// cookie removal can be forced by passing true as delete_cookie parameter |
|
94 |
snf.auth.AstakosClient.prototype.logout = function(delete_cookie) { |
|
95 |
var delete_cookie = delete_cookie == undefined ? false : delete_cookie; |
|
96 |
if (delete_cookie) { |
|
97 |
this.delete_cookie(); |
|
98 |
} |
|
99 |
this.config.logout_callback(this); |
|
100 |
} |
|
101 |
|
|
102 |
snf.auth.AstakosClient.prototype.get_cookie_data = function() { |
|
103 |
var data = $.cookie(this.config.cookie_name); |
|
104 |
|
|
105 |
// remove " characters |
|
106 |
if (data) { return data.replace(/\"/g, "") } |
|
107 |
return data; |
|
108 |
} |
|
109 |
|
|
110 |
|
|
111 |
snf.auth.AstakosClient.prototype.logged_in = function() { |
|
112 |
return this.get_cookie_data() == null |
|
113 |
} |
|
114 |
|
|
115 |
// parse cookie data |
|
116 |
// astakos sets cookie data using the following pattern: <username>|<token> |
|
117 |
snf.auth.AstakosClient.prototype.parse_cookie_data = function(data) { |
|
118 |
return { |
|
119 |
'username': data.split("|")[0], |
|
120 |
'token': data.split("|")[1] |
|
121 |
} |
|
122 |
} |
|
123 |
|
|
124 |
// set username and token |
|
125 |
snf.auth.AstakosClient.prototype.get_user = function() { |
|
126 |
var data = this.get_cookie_data(); |
|
127 |
if (!data) { |
|
128 |
return false; |
|
129 |
} |
|
130 |
var parsed_data = this.parse_cookie_data(data); |
|
131 |
return parsed_data; |
|
132 |
} |
|
133 |
|
|
134 |
})(this); |
b/snf-cyclades-app/synnefo/ui/static/snf/js/sync.js | ||
---|---|---|
180 | 180 |
this.date_send = new Date; |
181 | 181 |
} |
182 | 182 |
|
183 |
if (handler_type == "beforeSend") { |
|
184 |
arguments[0].setRequestHeader('X-Auth-Token', synnefo.user.token); |
|
185 |
} |
|
186 |
|
|
183 | 187 |
// error with status code 0 in opera |
184 | 188 |
// act as 304 response |
185 | 189 |
if (handler_type == "error" && $.browser.opera) { |
b/snf-cyclades-app/synnefo/ui/static/snf/js/ui/web/ui_main_view.js | ||
---|---|---|
61 | 61 |
|
62 | 62 |
beforeOpen: function() { |
63 | 63 |
var cont = this.$(".copy-content p"); |
64 |
var token = $.cookie("X-Auth-Token");
|
|
64 |
var token = snf.user.token;
|
|
65 | 65 |
|
66 | 66 |
cont.html(""); |
67 | 67 |
cont.text(token); |
... | ... | |
78 | 78 |
|
79 | 79 |
onClose: function() { |
80 | 80 |
var cont = this.$(".copy-content p"); |
81 |
var token = $.cookie("X-Auth-Token");
|
|
81 |
var token = snf.user.token;
|
|
82 | 82 |
cont.html(""); |
83 | 83 |
} |
84 | 84 |
}); |
... | ... | |
496 | 496 |
var args = util.parse_api_error.apply(util, arguments); |
497 | 497 |
|
498 | 498 |
// force logout if UNAUTHORIZED request arrives |
499 |
if (args.code == 401) { snf.ui.logout(); return };
|
|
499 |
if (args.code == 401) { snf.auth_client.logout(); return };
|
|
500 | 500 |
|
501 | 501 |
var error_entry = [args.ns, args.code, args.message, args.type, args.details, args]; |
502 | 502 |
this.error_view.show_error.apply(this.error_view, error_entry); |
... | ... | |
640 | 640 |
synnefo.ui.bind("error", _.bind(this.handle_ui_error, this)); |
641 | 641 |
|
642 | 642 |
this.feedback_view = new views.FeedbackView(); |
643 |
this.invitations_view = new views.InvitationsView(); |
|
644 | 643 |
this.public_keys_view = new views.PublicKeysOverlay(); |
645 | 644 |
|
646 | 645 |
if (synnefo.config.use_glance) { |
... | ... | |
685 | 684 |
}, |
686 | 685 |
|
687 | 686 |
init_menu: function() { |
688 |
$(".usermenu .invitations").click(_.bind(function(e){ |
|
689 |
e.preventDefault(); |
|
690 |
this.invitations_view.show(); |
|
691 |
}, this)); |
|
692 | 687 |
$(".usermenu .feedback").click(_.bind(function(e){ |
693 | 688 |
e.preventDefault(); |
694 | 689 |
this.feedback_view.show(); |
... | ... | |
715 | 710 |
|
716 | 711 |
bb.history.start(); |
717 | 712 |
|
718 |
this.trigger("initial");
|
|
713 |
this.trigger("ready");
|
|
719 | 714 |
}, |
720 | 715 |
|
721 | 716 |
show_vm_details: function(vm) { |
... | ... | |
957 | 952 |
|
958 | 953 |
snf.ui.main = new views.MainView(); |
959 | 954 |
|
960 |
snf.ui.logout = function() { |
|
961 |
$.cookie("X-Auth-Token", null); |
|
962 |
if (snf.config.logout_url !== undefined) |
|
963 |
{ |
|
964 |
window.location = snf.config.logout_url; |
|
965 |
} else { |
|
966 |
window.location.reload(); |
|
967 |
} |
|
968 |
} |
|
969 |
|
|
970 | 955 |
snf.ui.init = function() { |
971 | 956 |
if (snf.config.handle_window_exceptions) { |
972 | 957 |
window.onerror = function(msg, file, line) { |
b/snf-cyclades-app/synnefo/ui/templates/home.html | ||
---|---|---|
51 | 51 |
<![endif]--> |
52 | 52 |
|
53 | 53 |
<script src="{{ SYNNEFO_JS_URL }}utils.js"></script> |
54 |
<script src="{{ SYNNEFO_JS_URL }}auth.js"></script> |
|
54 | 55 |
<script src="{{ SYNNEFO_JS_URL }}sync.js"></script> |
55 | 56 |
<script src="{{ SYNNEFO_JS_URL }}models.js"></script> |
56 | 57 |
<script src="{{ SYNNEFO_JS_URL }}glance_models.js"></script> |
... | ... | |
65 | 66 |
<script src="{{ SYNNEFO_JS_WEB_URL }}ui_networks_view.js"></script> |
66 | 67 |
<script src="{{ SYNNEFO_JS_WEB_URL }}ui_metadata_view.js"></script> |
67 | 68 |
<script src="{{ SYNNEFO_JS_WEB_URL }}ui_feedback_view.js"></script> |
68 |
<script src="{{ SYNNEFO_JS_WEB_URL }}ui_invitations_view.js"></script> |
|
69 | 69 |
<script src="{{ SYNNEFO_JS_WEB_URL }}ui_create_view.js"></script> |
70 | 70 |
<script src="{{ SYNNEFO_JS_WEB_URL }}ui_connect_view.js"></script> |
71 | 71 |
<script src="{{ SYNNEFO_JS_WEB_URL }}ui_public_keys_view.js"></script> |
... | ... | |
75 | 75 |
<script src="{{ SYNNEFO_JS_WEB_URL }}ui_main_view.js"></script> |
76 | 76 |
|
77 | 77 |
<!-- the following views require refactor --> |
78 |
<script src="{{ SYNNEFO_JS_URL }}invitations.js"></script> |
|
79 | 78 |
<script src="{{ SYNNEFO_JS_URL }}synnefo.js"></script> |
80 | 79 |
|
81 | 80 |
<script> |
... | ... | |
91 | 90 |
var TIMEOUTS_OCCURED = 0; |
92 | 91 |
var SKIP_TIMEOUTS = 1; |
93 | 92 |
var UPDATE_INTERVAL = {{ update_interval }}; |
94 |
var LOGOUT_REDIRECT = '{{ logout_redirect }}'; |
|
95 |
var INVITATIONS_URL = "{% url invitations %}"; |
|
96 |
var INVITATIONS_TITLE = "{% trans "Invite people" %}"; |
|
97 | 93 |
var APP_DEBUG = {% if DEBUG %}true{% else %}false{% endif %}; |
98 | 94 |
var FEEDBACK_URL = "{% url feedback %}"; |
99 | 95 |
var FEEDBACK_TITLE = "{% trans "Send feedback" %}"; |
... | ... | |
190 | 186 |
<div id="header"> |
191 | 187 |
<div id="user"> |
192 | 188 |
<div class="usermenu"> |
193 |
<div class="username">{{ request.user.uniq }}</div>
|
|
189 |
<div class="username"></div> |
|
194 | 190 |
<ul class="useractions"> |
195 |
<li class="invitations"><a class="action" href="#">{% trans "invite friends..." %}</a></li> |
|
196 | 191 |
<li class="feedback"><a class="action" href="#">{% trans "send feedback..." %}</a></li> |
197 | 192 |
<li class="api"><a class="action" href="#">{% trans "API access..." %}</a></li> |
198 | 193 |
<li class="public_keys"><a class="action" href="#">{% trans "ssh public keys..." %}</a></li> |
... | ... | |
312 | 307 |
|
313 | 308 |
// bind menu actions |
314 | 309 |
$(".usermenu .logout").click(function() { |
315 |
synnefo.ui.logout();
|
|
310 |
synnefo.auth_client.logout();
|
|
316 | 311 |
}); |
317 | 312 |
|
318 | 313 |
$(".usermenu .api").click(function(){ |
... | ... | |
422 | 417 |
<span class="reload-app">{% trans "Reload" %}</span> |
423 | 418 |
</div> |
424 | 419 |
</div> |
425 |
{% include "partials/invitations.html" %} |
|
426 | 420 |
<div id="feedback-overlay-content" class="hidden overlay-content feedback-form"> |
427 | 421 |
<div class="description"> |
428 | 422 |
<p> |
... | ... | |
559 | 553 |
synnefo.config.handle_window_exceptions = {{ handle_window_exceptions }}; |
560 | 554 |
synnefo.config.ajax_timeout = {{ timeout }}; |
561 | 555 |
synnefo.config.skip_timeouts = {{ skip_timeouts }}; |
562 |
synnefo.config.invitations_url = "{% url invitations %}"; |
|
563 | 556 |
synnefo.config.machines_icons_url = '{{ SYNNEFO_IMAGES_URL }}icons/machines/'; |
564 | 557 |
synnefo.config.vm_name_template = {{ vm_name_template|safe }}; |
565 | 558 |
synnefo.config.flavors_disk_templates_info = {{ flavors_disk_templates_info|safe }}; |
... | ... | |
568 | 561 |
'compute': {{ compute_api_url|safe }}, |
569 | 562 |
'glance': {{ glance_api_url|safe }} |
570 | 563 |
}; |
564 |
|
|
571 | 565 |
// TODO: configurable userdata urls in models.js |
572 | 566 |
synnefo.config.userdata_url = '/ui/userdata'; |
573 |
synnefo.config.logout_url = '{{ logout_redirect }}'; |
|
574 | 567 |
synnefo.config.userdata_keys_url = '{% url keys_collection %}'; |
575 | 568 |
synnefo.config.userdata_keys_limit = {{ userdata_keys_limit }}; |
569 |
|
|
576 | 570 |
// media config |
577 | 571 |
synnefo.config.media_url = '{{ UI_MEDIA_URL }}'; |
578 | 572 |
synnefo.config.js_url = '{{ SYNNEFO_JS_URL }}'; |
... | ... | |
582 | 576 |
synnefo.config.machines_icons_url = '{{ SYNNEFO_IMAGES_URL }}icons/machines/'; |
583 | 577 |
synnefo.config.support_ssh_os_list = {{ support_ssh_os_list|safe }}; |
584 | 578 |
synnefo.config.os_created_users = {{ os_created_users|safe }}; |
579 |
|
|
580 |
synnefo.config.logout_redirect = '{{ logout_redirect }}'; |
|
581 |
synnefo.config.login_redirect = '{{ login_redirect }}'; |
|
582 |
synnefo.config.auth_cookie_name = '{{ auth_cookie_name }}'; |
|
583 |
|
|
584 |
synnefo.auth_client = new synnefo.auth.AstakosClient({ |
|
585 |
login_url: synnefo.config.login_redirect, |
|
586 |
logout_url: synnefo.config.logout_redirect, |
|
587 |
cookie_name: synnefo.config.auth_cookie_name |
|
588 |
}); |
|
589 |
|
|
585 | 590 |
// user config |
586 |
synnefo.user = {}; |
|
587 |
synnefo.user.username = '{{ request.user.uniq }}'; |
|
588 |
synnefo.user.token = $.cookie("X-Auth-Token"); |
|
591 |
synnefo.user = synnefo.auth_client.get_user(); |
|
592 |
if (!synnefo.user) { synnefo.auth_client.redirect_to_login(); } |
|
593 |
|
|
594 |
$(".usermenu .username").text(synnefo.user.username); |
|
595 |
|
|
589 | 596 |
// images config |
590 | 597 |
synnefo.config.system_images_owners = {{ system_images_owners|safe }}; |
591 | 598 |
synnefo.ui.init(); |
592 |
synnefo.ui.main.bind("initial", function(){
|
|
599 |
synnefo.ui.main.bind("ready", function(){
|
|
593 | 600 |
}); |
594 | 601 |
|
595 | 602 |
}) |
b/snf-cyclades-app/synnefo/ui/userdata/migrations/0003_auto__chg_field_publickeypair_fingerprint__chg_field_publickeypair_use.py | ||
---|---|---|
1 |
# encoding: utf-8 |
|
2 |
import datetime |
|
3 |
from south.db import db |
|
4 |
from south.v2 import SchemaMigration |
|
5 |
from django.db import models |
|
6 |
|
|
7 |
class Migration(SchemaMigration): |
|
8 |
|
|
9 |
def forwards(self, orm): |
|
10 |
|
|
11 |
# Changing field 'PublicKeyPair.fingerprint' |
|
12 |
db.alter_column('userdata_publickeypair', 'fingerprint', self.gf('django.db.models.fields.CharField')(max_length=100, blank=True)) |
|
13 |
|
|
14 |
# Renaming column for 'PublicKeyPair.user' to match new field type. |
|
15 |
db.rename_column('userdata_publickeypair', 'user_id', 'user') |
|
16 |
# Changing field 'PublicKeyPair.user' |
|
17 |
db.alter_column('userdata_publickeypair', 'user', self.gf('django.db.models.fields.CharField')(max_length=100)) |
|
18 |
|
|
19 |
# Removing index on 'PublicKeyPair', fields ['user'] |
|
20 |
db.delete_index('userdata_publickeypair', ['user_id']) |
|
21 |
|
|
22 |
|
|
23 |
def backwards(self, orm): |
|
24 |
|
|
25 |
# Changing field 'PublicKeyPair.fingerprint' |
|
26 |
db.alter_column('userdata_publickeypair', 'fingerprint', self.gf('django.db.models.fields.CharField')(max_length=100)) |
|
27 |
|
|
28 |
# Renaming column for 'PublicKeyPair.user' to match new field type. |
|
29 |
db.rename_column('userdata_publickeypair', 'user', 'user_id') |
|
30 |
# Changing field 'PublicKeyPair.user' |
|
31 |
db.alter_column('userdata_publickeypair', 'user_id', self.gf('django.db.models.fields.related.ForeignKey')(to=orm['db.SynnefoUser'])) |
|
32 |
|
|
33 |
# Adding index on 'PublicKeyPair', fields ['user'] |
|
34 |
db.create_index('userdata_publickeypair', ['user_id']) |
|
35 |
|
|
36 |
|
|
37 |
models = { |
|
38 |
'userdata.publickeypair': { |
|
39 |
'Meta': {'object_name': 'PublicKeyPair'}, |
|
40 |
'content': ('django.db.models.fields.TextField', [], {}), |
|
41 |
'fingerprint': ('django.db.models.fields.CharField', [], {'max_length': '100', 'blank': 'True'}), |
|
42 |
'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}), |
|
43 |
'name': ('django.db.models.fields.CharField', [], {'max_length': '255'}), |
|
44 |
'user': ('django.db.models.fields.CharField', [], {'max_length': '100'}) |
|
45 |
} |
|
46 |
} |
|
47 |
|
|
48 |
complete_apps = ['userdata'] |
b/snf-cyclades-app/synnefo/ui/userdata/models.py | ||
---|---|---|
43 | 43 |
from django.core.exceptions import ValidationError, NON_FIELD_ERRORS |
44 | 44 |
from django.db.models.signals import pre_save |
45 | 45 |
|
46 |
from synnefo.db import models as synnefo_models |
|
47 |
|
|
48 | 46 |
try: |
49 | 47 |
from paramiko import rsakey, dsskey, SSHException |
50 | 48 |
except: |
b/snf-cyclades-app/synnefo/ui/views.py | ||
---|---|---|
76 | 76 |
|
77 | 77 |
SUPPORT_SSH_OS_LIST = getattr(settings, "UI_SUPPORT_SSH_OS_LIST",) |
78 | 78 |
OS_CREATED_USERS = getattr(settings, "UI_OS_DEFAULT_USER_MAP") |
79 |
LOGOUT_URL = getattr(settings, "LOGOUT_URL", settings.LOGIN_URL) |
|
79 |
LOGOUT_URL = getattr(settings, "UI_LOGOUT_URL", '/im/authenticate') |
|
80 |
LOGIN_URL = getattr(settings, "UI_LOGIN_URL", '/im/login') |
|
81 |
AUTH_COOKIE_NAME = getattr(settings, "UI_AUTH_COOKIE_NAME", 'synnefo_user') |
|
80 | 82 |
|
81 | 83 |
# UI behaviour settings |
82 | 84 |
DELAY_ON_BLUR = getattr(settings, "UI_DELAY_ON_BLUR", True) |
... | ... | |
108 | 110 |
# extensions |
109 | 111 |
ENABLE_GLANCE = getattr(settings, 'UI_ENABLE_GLANCE', True) |
110 | 112 |
GLANCE_API_URL = getattr(settings, 'UI_GLANCE_API_URL', '/glance') |
111 |
INVITATIONS_PER_PAGE = getattr(settings, "INVITATIONS_PER_PAGE", 10) |
|
112 | 113 |
FEEDBACK_CONTACTS = getattr(settings, "FEEDBACK_CONTACTS", []) |
113 | 114 |
FEEDBACK_EMAIL_FROM = settings.FEEDBACK_EMAIL_FROM |
114 | 115 |
|
... | ... | |
144 | 145 |
# additional settings |
145 | 146 |
'image_icons': IMAGE_ICONS, |
146 | 147 |
'logout_redirect': LOGOUT_URL, |
148 |
'login_redirect': LOGIN_URL, |
|
149 |
'auth_cookie_name': AUTH_COOKIE_NAME, |
|
147 | 150 |
'suggested_flavors': json.dumps(SUGGESTED_FLAVORS), |
148 | 151 |
'suggested_roles': json.dumps(SUGGESTED_ROLES), |
149 | 152 |
'vm_image_common_metadata': json.dumps(VM_IMAGE_COMMON_METADATA), |
150 | 153 |
'synnefo_version': SYNNEFO_JS_LIB_VERSION, |
151 |
'invitations_per_page': INVITATIONS_PER_PAGE, |
|
152 | 154 |
'delay_on_blur': json.dumps(DELAY_ON_BLUR), |
153 | 155 |
'update_hidden_views': json.dumps(UPDATE_HIDDEN_VIEWS), |
154 | 156 |
'handle_window_exceptions': json.dumps(HANDLE_WINDOW_EXCEPTIONS), |
Also available in: Unified diff