--- /dev/null
+sqlite> CREATE TEMPORARY TABLE portal_pendinguser_backup(id,first_name,last_name,email,password,keypair,authority_hrn);
+sqlite> INSERT INTO portal_pendinguser_backup SELECT id,first_name,last_name,email,password,keypair,authority_hrn FROM portal_pendinguser;
+sqlite> DROP TABLE portal_pendinguser;
+sqlite> CREATE TABLE portal_pendinguser(id,first_name,last_name,email,password,keypair,authority_hrn);
+sqlite> INSERT INTO portal_pendinguser SELECT id,first_name,last_name,email,password,keypair,authority_hrn FROM portal_pendinguser_backup;
+sqlite> DROP TABLE portal_pendinguser_backup;
+sqlite> COMMIT;
result = manifold_api.forward(query.to_dict())
if result['code'] == 2:
raise Exception, 'Error running query: %r' % result
+
+ if result['code'] == 1:
+ print "WARNING"
+ print result['description']
# XXX Handle errors
#Error running query: {'origin': [0, 'XMLRPCAPI'], 'code': 2, 'description': 'No such session: No row was found for one()', 'traceback': 'Traceback (most recent call last):\n File "/usr/local/lib/python2.7/dist-packages/manifold/core/xmlrpc_api.py", line 68, in xmlrpc_forward\n user = Auth(auth).check()\n File "/usr/local/lib/python2.7/dist-packages/manifold/auth/__init__.py", line 245, in check\n return self.auth_method.check()\n File "/usr/local/lib/python2.7/dist-packages/manifold/auth/__init__.py", line 95, in check\n raise AuthenticationFailure, "No such session: %s" % e\nAuthenticationFailure: No such session: No row was found for one()\n', 'type': 2, 'ts': None, 'value': None}
[manifold]
url = http://localhost:7080
admin_user = admin
-admin_password = demo
+admin_password = admin
from portal.models import PendingUser, PendingSlice
import json
+# XXX sfa dependency, should be moved to SFA gateway
+from sfa.util.xrn import Xrn
+
+
# Get the list of authorities
def authority_get_pis(request, authority_hrn):
#return result['pi_users']
return results
-def authority_get_pi_emails(request,authority_hrn):
+def authority_get_pi_emails(request, authority_hrn):
+ return ['jordan.auge@lip6.fr', 'loic.baron@lip6.fr']
+
pi_users = authority_get_pis(request,authority_hrn)
pi_user_hrns = [ hrn for x in pi_users for hrn in x['pi_users'] ]
query = Query.get('user').filter_by('user_hrn', 'included', pi_user_hrns).select('email')
- results = execute_query(request,query)
+ results = execute_query(request, query)
print "mails", [result['email'] for result in results]
return [result['email'] for result in results]
# SFA add record (user, slice)
-def sfa_add_user(user_params):
- # sfi.py add --xrn=fed4fire.upmc.timur_friedman --type=user --key=/root/.sfi/timur.pub --email=timur.friedman@lip6.fr --extra=first_name=Timur --extra=last_name=Friedman --extra=enabled=true
- # user_params: xrn type key email + first_name last_name enabled
+def sfa_add_user(request, user_params):
query = Query.create('user').set(user_params).select('user_hrn')
- results = execute_query(query)
+ results = execute_query(request, query)
if not results:
- raise Exception, "Failed creating SFA user: %s" % user_params['user_hrn']
- result, = results
- return result['user_hrn']
+ raise Exception, "Could not create %s. Already exists ?" % user_params['hrn']
+ return results
-def sfa_add_slice(slice_params):
- pass
+def sfa_add_slice(request, slice_params):
+ query = Query.create('slice').set(slice_params).select('slice_hrn')
+ results = execute_query(request, query)
+ if not results:
+ raise Exception, "Could not create %s. Already exists ?" % slice_params['hrn']
+ return results
# Propose hrn
def manifold_add_user(request, user_params):
# user_params: email, password e.g., user_params = {'email':'aa@aa.com','password':'demo'}
query = Query.create('local:user').set(user_params).select('email')
- results = execute_query(request,query)
+ results = execute_query(request, query)
if not results:
raise Exception, "Failed creating manifold user: %s" % user_params['email']
result, = results
def make_request_user(user):
request = {}
- request['type'] = 'user'
- request['id'] = user.id
- request['timestamp'] = 'TODO' # XXX in DB ?
+ request['type'] = 'user'
+ request['id'] = user.id
+ request['timestamp'] = user.created # XXX in DB ?
request['authority_hrn'] = user.authority_hrn
- request['first_name'] = user.first_name
- request['last_name'] = user.last_name
- request['email'] = user.email
+ request['first_name'] = user.first_name
+ request['last_name'] = user.last_name
+ request['email'] = user.email
+ request['login'] = user.login
+ request['keypair'] = user.keypair
return request
def make_request_slice(slice):
request = {}
request['type'] = 'slice'
request['id'] = slice.id
- request['timestamp'] = 'TODO' # XXX in DB ?
+ request['timestamp'] = slice.created
request['authority_hrn'] = slice.authority_hrn
+ request['slice_name'] = slice.slice_name
request['number_of_nodes'] = slice.number_of_nodes
request['type_of_nodes'] = slice.type_of_nodes
request['purpose'] = slice.purpose
return make_requests(pending_users, pending_slices)
-SFA_USER_KEYS = ['xrn', 'type', 'key', 'first_name', 'last_name', 'email']
-SFA_SLICE_KEYS = []
-MANIFOLD_USER_KEYS = ['email', 'password']
-MANIFOLD_ACCOUNT_KEYS = []
+# XXX Is it in sync with the form fields ?
-def portal_validate_request(request_ids):
+def portal_validate_request(wsgi_request, request_ids):
status = {}
if not isinstance(request_ids, list):
request_status = {}
+ print "REQUEST", request
if request['type'] == 'user':
+
try:
- sfa_user_params = { key: request[key] for key in SFA_USER_KEYS }
- sfa_user_params['enabled'] = True
- # XXX # sfa_add_user(sfa_user_params)
+ hrn = "%s.%s" % (request['authority_hrn'], request['login'])
+ urn = Xrn(hrn, request['type']).get_urn()
+
+ sfa_user_params = {
+ 'hrn' : hrn,
+ 'urn' : urn,
+ 'type' : request['type'],
+ 'keys' : [json.loads(request['keypair'])['user_public_key']],
+ 'first_name' : request['first_name'],
+ 'last_name' : request['last_name'],
+ 'email' : request['email'],
+ #'slices' : None,
+ #'researcher': None,
+ #'pi' : None,
+ 'enabled' : True
+ }
+ # ignored in request: id, timestamp, password
+
+ sfa_add_user(wsgi_request, sfa_user_params)
+
+ # XXX Remove from database
+
+
request_status['SFA user'] = {'status': True }
+
except Exception, e:
request_status['SFA user'] = {'status': False, 'description': str(e)}
- try:
- manifold_user_params = { key: request[key] for key in MANIFOLD_USER_KEYS }
- # XXX # manifold_add_user(manifold_user_params)
- request_status['MySlice user'] = {'status': True }
- except Exception, e:
- request_status['MySlice user'] = {'status': False, 'description': str(e)}
+ # MANIFOLD user should be added beforehand, during registration
+ #try:
+ # manifold_user_params = { key: request[key] for key in MANIFOLD_USER_KEYS }
+ # # XXX # manifold_add_user(manifold_user_params)
+ # request_status['MySlice user'] = {'status': True }
+ #except Exception, e:
+ # request_status['MySlice user'] = {'status': False, 'description': str(e)}
# XXX
#manifold_account_params = { key: request[key] for key in MANIFOLD_ACCOUNT_KEYS }
#manifold_add_account(manifold_account_params)
- request_status['MySlice testbed accounts'] = {'status': False }
+ #request_status['MySlice testbed accounts'] = {'status': False }
elif request['type'] == 'slice':
try:
- sfa_slice_params = { key: request[key] for key in SFA_SLICE_KEYS }
- # XXX # sfa_add_slice(sfa_slice_params)
+ hrn = "%s.%s" % (request['authority_hrn'], request['slice_name'])
+ urn = Xrn(hrn, request['type']).get_urn()
+
+ sfa_slice_params = {
+ 'hrn' : hrn,
+ 'urn' : urn,
+ 'type' : request['type'],
+ #'slices' : None,
+ #'researcher': None,
+ #'pi' : None,
+ 'enabled' : True
+ }
+ # ignored in request: id, timestamp, number_of_nodes, type_of_nodes, purpose
+
+ sfa_add_slice(wsgi_request, sfa_slice_params)
+
+ # XXX Remove from database
+
+
request_status['SFA slice'] = {'status': True }
+
except Exception, e:
request_status['SFA slice'] = {'status': False, 'description': str(e)}
status['%s__%s' % (request['type'], request['id'])] = request_status
- # XXX remove from database succeeded actions
-
return status
-def validate_action(*args, **kwargs):
+def validate_action(request, **kwargs):
ids = filter(None, kwargs['id'].split('/'))
- status = portal_validate_request(ids)
+ status = portal_validate_request(request, ids)
json_answer = json.dumps(status)
return HttpResponse (json_answer, mimetype="application/json")
(u'id', self.gf('django.db.models.fields.AutoField')(primary_key=True)),
('first_name', self.gf('django.db.models.fields.TextField')()),
('last_name', self.gf('django.db.models.fields.TextField')()),
- ('affiliation', self.gf('django.db.models.fields.TextField')()),
('email', self.gf('django.db.models.fields.EmailField')(max_length=75)),
('password', self.gf('django.db.models.fields.TextField')()),
('keypair', self.gf('django.db.models.fields.TextField')()),
},
u'portal.pendinguser': {
'Meta': {'object_name': 'PendingUser'},
- 'affiliation': ('django.db.models.fields.TextField', [], {}),
'authority_hrn': ('django.db.models.fields.TextField', [], {}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'first_name': ('django.db.models.fields.TextField', [], {}),
}
}
- complete_apps = ['portal']
\ No newline at end of file
+ complete_apps = ['portal']
},
u'portal.pendinguser': {
'Meta': {'object_name': 'PendingUser'},
- 'affiliation': ('django.db.models.fields.TextField', [], {}),
'authority_hrn': ('django.db.models.fields.TextField', [], {}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'first_name': ('django.db.models.fields.TextField', [], {}),
}
}
- complete_apps = ['portal']
\ No newline at end of file
+ complete_apps = ['portal']
},
u'portal.pendinguser': {
'Meta': {'object_name': 'PendingUser'},
- 'affiliation': ('django.db.models.fields.TextField', [], {}),
'authority_hrn': ('django.db.models.fields.TextField', [], {}),
'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
'first_name': ('django.db.models.fields.TextField', [], {}),
}
}
- complete_apps = ['portal']
\ No newline at end of file
+ complete_apps = ['portal']
--- /dev/null
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+ # Adding field 'PendingUser.login'
+ db.add_column(u'portal_pendinguser', 'login',
+ self.gf('django.db.models.fields.TextField')(default='dummy'),
+ keep_default=False)
+
+
+ def backwards(self, orm):
+ # Deleting field 'PendingUser.login'
+ db.delete_column(u'portal_pendinguser', 'login')
+
+
+ models = {
+ u'portal.institution': {
+ 'Meta': {'object_name': 'Institution'},
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.TextField', [], {})
+ },
+ u'portal.pendingslice': {
+ 'Meta': {'object_name': 'PendingSlice'},
+ 'authority_hrn': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'number_of_nodes': ('django.db.models.fields.TextField', [], {'default': '0'}),
+ 'purpose': ('django.db.models.fields.TextField', [], {'default': "'NA'"}),
+ 'slice_name': ('django.db.models.fields.TextField', [], {}),
+ 'type_of_nodes': ('django.db.models.fields.TextField', [], {'default': "'NA'"})
+ },
+ u'portal.pendinguser': {
+ 'Meta': {'object_name': 'PendingUser'},
+ 'authority_hrn': ('django.db.models.fields.TextField', [], {}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
+ 'first_name': ('django.db.models.fields.TextField', [], {}),
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'keypair': ('django.db.models.fields.TextField', [], {}),
+ 'last_name': ('django.db.models.fields.TextField', [], {}),
+ 'login': ('django.db.models.fields.TextField', [], {}),
+ 'password': ('django.db.models.fields.TextField', [], {})
+ }
+ }
+
+ complete_apps = ['portal']
\ No newline at end of file
--- /dev/null
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+ # Adding field 'PendingUser.created'
+ db.add_column(u'portal_pendinguser', 'created',
+ self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, default=datetime.datetime(2013, 10, 25, 0, 0), blank=True),
+ keep_default=False)
+
+
+ def backwards(self, orm):
+ # Deleting field 'PendingUser.created'
+ db.delete_column(u'portal_pendinguser', 'created')
+
+
+ models = {
+ u'portal.institution': {
+ 'Meta': {'object_name': 'Institution'},
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.TextField', [], {})
+ },
+ u'portal.pendingslice': {
+ 'Meta': {'object_name': 'PendingSlice'},
+ 'authority_hrn': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'number_of_nodes': ('django.db.models.fields.TextField', [], {'default': '0'}),
+ 'purpose': ('django.db.models.fields.TextField', [], {'default': "'NA'"}),
+ 'slice_name': ('django.db.models.fields.TextField', [], {}),
+ 'type_of_nodes': ('django.db.models.fields.TextField', [], {'default': "'NA'"})
+ },
+ u'portal.pendinguser': {
+ 'Meta': {'object_name': 'PendingUser'},
+ 'authority_hrn': ('django.db.models.fields.TextField', [], {}),
+ 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
+ 'first_name': ('django.db.models.fields.TextField', [], {}),
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'keypair': ('django.db.models.fields.TextField', [], {}),
+ 'last_name': ('django.db.models.fields.TextField', [], {}),
+ 'login': ('django.db.models.fields.TextField', [], {}),
+ 'password': ('django.db.models.fields.TextField', [], {})
+ }
+ }
+
+ complete_apps = ['portal']
\ No newline at end of file
--- /dev/null
+# -*- coding: utf-8 -*-
+import datetime
+from south.db import db
+from south.v2 import SchemaMigration
+from django.db import models
+
+
+class Migration(SchemaMigration):
+
+ def forwards(self, orm):
+ # Adding field 'PendingSlice.created'
+ db.add_column(u'portal_pendingslice', 'created',
+ self.gf('django.db.models.fields.DateTimeField')(auto_now_add=True, default=datetime.datetime(2013, 10, 25, 0, 0), blank=True),
+ keep_default=False)
+
+
+ def backwards(self, orm):
+ # Deleting field 'PendingSlice.created'
+ db.delete_column(u'portal_pendingslice', 'created')
+
+
+ models = {
+ u'portal.institution': {
+ 'Meta': {'object_name': 'Institution'},
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'name': ('django.db.models.fields.TextField', [], {})
+ },
+ u'portal.pendingslice': {
+ 'Meta': {'object_name': 'PendingSlice'},
+ 'authority_hrn': ('django.db.models.fields.TextField', [], {'null': 'True'}),
+ 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'number_of_nodes': ('django.db.models.fields.TextField', [], {'default': '0'}),
+ 'purpose': ('django.db.models.fields.TextField', [], {'default': "'NA'"}),
+ 'slice_name': ('django.db.models.fields.TextField', [], {}),
+ 'type_of_nodes': ('django.db.models.fields.TextField', [], {'default': "'NA'"})
+ },
+ u'portal.pendinguser': {
+ 'Meta': {'object_name': 'PendingUser'},
+ 'authority_hrn': ('django.db.models.fields.TextField', [], {}),
+ 'created': ('django.db.models.fields.DateTimeField', [], {'auto_now_add': 'True', 'blank': 'True'}),
+ 'email': ('django.db.models.fields.EmailField', [], {'max_length': '75'}),
+ 'first_name': ('django.db.models.fields.TextField', [], {}),
+ u'id': ('django.db.models.fields.AutoField', [], {'primary_key': 'True'}),
+ 'keypair': ('django.db.models.fields.TextField', [], {}),
+ 'last_name': ('django.db.models.fields.TextField', [], {}),
+ 'login': ('django.db.models.fields.TextField', [], {}),
+ 'password': ('django.db.models.fields.TextField', [], {})
+ }
+ }
+
+ complete_apps = ['portal']
\ No newline at end of file
class PendingUser(models.Model):
# NOTE We might consider migrating the fields to CharField, which would
# simplify form creation in forms.py
- first_name = models.TextField()
- last_name = models.TextField()
-# affiliation = models.TextField()
- email = models.EmailField() #validators=[validate_email])
- password = models.TextField()
- keypair = models.TextField()
- # institution
+ first_name = models.TextField()
+ last_name = models.TextField()
+ email = models.EmailField() #validators=[validate_email])
+ password = models.TextField()
+ keypair = models.TextField()
authority_hrn = models.TextField()
+ login = models.TextField()
+ created = models.DateTimeField(auto_now_add = True)
# models.ForeignKey(Institution)
class PendingSlice(models.Model):
number_of_nodes = models.TextField(default=0)
type_of_nodes = models.TextField(default='NA')
purpose = models.TextField(default='NA')
+ created = models.DateTimeField(auto_now_add = True)
class RegistrationView (View):
def dispatch (self, request):
-
errors = []
authorities_query = Query.get('authority').\
select('name', 'authority_hrn')
- onelab_enabled_query = Query.get('local:platform').filter_by('platform', '==', 'ple-onelab').filter_by('disabled', '==', 'False')
- #onelab_enabled = not not execute_admin_query(request, onelab_enabled_query)
- onelab_enabled = True
+ onelab_enabled_query = Query.get('local:platform').filter_by('platform', '==', 'ple').filter_by('disabled', '==', 'False')
+ onelab_enabled = not not execute_admin_query(request, onelab_enabled_query)
if onelab_enabled:
print "ONELAB ENABLED"
authorities_query = authorities_query.filter_by('authority_hrn', 'included', ['ple.inria', 'ple.upmc', 'ple.ibbtple'])
# We shall use a form here
#get_email = PendingUser.objects.get(email)
- reg_fname = request.POST.get('firstname', '')
- reg_lname = request.POST.get('lastname', '')
- #reg_aff = request.POST.get('affiliation','')
- reg_auth = request.POST.get('authority_hrn', '')
- reg_email = request.POST.get('email','').lower()
+ reg_fname = request.POST.get('firstname', '')
+ reg_lname = request.POST.get('lastname', '')
+ #reg_aff = request.POST.get('affiliation','')
+ reg_auth = request.POST.get('authority_hrn', '')
+ reg_login = request.POST.get('login', '')
+ reg_email = request.POST.get('email','').lower()
#POST value validation
if (re.search(r'^[\w+\s.@+-]+$', reg_fname)==None):
#b.save()
if not errors:
b = PendingUser(
- first_name=reg_fname,
- last_name=reg_lname,
- #affiliation=reg_aff,
- authority_hrn=reg_auth,
- email=reg_email,
- password=request.POST['password'],
- keypair=keypair
- )
+ first_name = reg_fname,
+ last_name = reg_lname,
+ #affiliation = reg_aff,
+ authority_hrn = reg_auth,
+ login = reg_login,
+ email = reg_email,
+ password = request.POST['password'],
+ keypair = keypair,
+ )
b.save()
# Send email
'keypair' : 'Public Key :' + public_key,
'cc_myself' : True # form.cleaned_data['cc_myself']
}
- #not working
- #recipients = authority_get_pi_emails(request,reg_auth)
- recipients = ['devel@myslice.info']
+
+ recipients = authority_get_pi_emails(request,reg_auth)
+
if ctx['cc_myself']:
recipients.append(ctx['email'])
msg = render_to_string('user_request_email.txt', ctx)
- print "tesing msg"
- print msg
send_mail("Onelab New User request for %s submitted"%reg_email, msg, reg_email, recipients)
return render(request, 'user_register_complete.html')
select('name', 'authority_hrn')
onelab_enabled_query = Query.get('local:platform').filter_by('platform', '==', 'ple-onelab').filter_by('disabled', '==', 'False')
- #onelab_enabled = not not execute_admin_query(request, onelab_enabled_query)
- onelab_enabled = True
+ onelab_enabled = not not execute_admin_query(request, onelab_enabled_query)
if onelab_enabled:
authorities_query = authorities_query.filter_by('authority_hrn', 'included', ['ple.inria', 'ple.upmc', 'ple.ibbtple'])
cc_myself = form.cleaned_data['cc_myself']
# The recipients are the PI of the authority
- recipients = authority_get_pi_emails(request,authority_hrn)
- #recipients = ['yasin.upmc@gmail.com','jordan.auge@lip6.fr']
+ recipients = authority_get_pi_emails(request, authority_hrn)
+
if cc_myself:
recipients.append(email)
msg = render_to_string('slice-request-email.txt', form.cleaned_data)
</div>
<div class="col-xs-4"><p class="form-hint">Please select an authority responsible for vetting your account</p></div>
</div>
+
+ <!-- LOGIN
+ TODO: Login should be suggested from user email or first/last name, and
+ checked for existence. In addition, the full HRN should be shown to the
+ user.
+ -->
+ <div class="form-group">
+ <label for="login" class="col-xs-4 control-label">Login</label>
+ <div class="col-xs-4">
+ <input type="text" name="login" size="25" class="form-control" minlength="2" value="{{ login }}" placeholder="Login" required />
+ </div>
+ <div class="col-xs-4"><p class="form-hint">Enter your login</p></div>
+ </div>
<div class="form-group">
<label for="email" class="col-xs-4 control-label">Email</label>
function on_click_event() {
var ids = [];
$('.portal__validate__checkbox').each(function(i, el) {
- if ($(el).attr('checked')) {
+ if ($(el).prop('checked')) {
// portal__validate__checkbox__slice__2
var id_array = $(el).attr('id').split('__');
// push(slice__2)
status_str += ' -- ';
if (result.status) {
- status_str += '<font color="green">' + name + '</font>';
+ status_str += '<font color="green">OK</font>';
$('#portal__validate__checkbox__' + request_type__id).hide();
} else {
- status_str += '<font color="red">' + name + ' (' + result.description + ')</font>';
+ status_str += '<font color="red">ERROR: ' + result.description + '</font>';
}
});
$('#portal__status__' + request_type__id).html(status_str)
url(r'^validate/?$', ValidatePendingView.as_view()),
# http://stackoverflow.com/questions/2360179/django-urls-how-to-pass-a-list-of-items-via-clean-urls
# (r'^validate_action/(?P<constraints>[^/]+)/(?P<id>\w+)/?$', 'portal.views.pres_view_static'),
- (r'^validate_action(?P<id>(?:/\w+)+)/?$', 'portal.actions.validate_action'),
+ url(r'^validate_action(?P<id>(?:/\w+)+)/?$', 'portal.actions.validate_action'),
url(r'^pres_view/?$', PresViewView.as_view(), name='pres_view'),
(r'^methods/(?P<type>\w+)/?$', 'portal.views.pres_view_methods'),
@login_required
def tab_view (request):
+ print "request", request.__class__
+ print request
prelude=Prelude( js_files='js/bootstrap.js', css_files='css/bootstrap.css')
prelude_env = prelude.prelude_env()