Merge branch 'onelab' of ssh://git.onelab.eu/git/myslice into fibre
authorLoic & Edelberto <loic.baron@lip6.fr>
Wed, 23 Apr 2014 14:03:49 +0000 (11:03 -0300)
committerLoic & Edelberto <loic.baron@lip6.fr>
Wed, 23 Apr 2014 14:03:49 +0000 (11:03 -0300)
Conflicts:
auth/manifoldbackend.py
myslice/settings.py
portal/templates/contact.html
portal/templates/documentationview.html
portal/templates/registration_view.html
setup.py

1  2 
auth/manifoldbackend.py
myslice/settings.py
myslice/urls.py
portal/actions.py
portal/homeview.py
portal/registrationview.py
portal/templates/fibre/fibre_contact.html
portal/templates/fibre/fibre_documentationview.html
portal/templates/fibre/fibre_registration_view.html
setup.py

diff --combined auth/manifoldbackend.py
@@@ -1,8 -1,5 +1,8 @@@
  import time
  
 +# import ldap for LDAP authentication - Edelberto
 +import ldap
 +
  from django.contrib.auth.models import User
  
  from manifoldapi.manifoldapi    import ManifoldAPI, ManifoldException, ManifoldResult
@@@ -11,188 -8,44 +11,188 @@@ from manifold.core.query        import 
  # Name my backend 'ManifoldBackend'
  class ManifoldBackend:
  
 +
      # Create an authentication method
      # This is called by the standard Django login procedure
      def authenticate(self, token=None):
 +    
 +        # LDAP local/global var
 +        checkldap = None
 +
          if not token:
              return None
  
          try:
 +            print "ManifoldBackend authenticate()"
 +            # Mandatory fields in token
              username = token['username']
 -            password = token['password']
              request = token['request']
  
 -            auth = {'AuthMethod': 'password', 'Username': username, 'AuthString': password}
 -            api = ManifoldAPI(auth)
 -            sessions_result = api.forward(Query.create('local:session').to_dict())
 -            print "result"
 -            sessions = sessions_result.ok_value()
 -            print "ok"
 -            if not sessions:
 -                print "GetSession failed", sessions_result.error()
 -                return
 -            print "first", sessions
 -            session = sessions[0]
 -
 -            # Change to session authentication
 -            api.auth = {'AuthMethod': 'session', 'session': session['session']}
 -            self.api = api
 -
 -            # Get account details
 -            # the new API would expect Get('local:user') instead
 -            persons_result = api.forward(Query.get('local:user').to_dict())
 -            persons = persons_result.ok_value()
 -            if not persons:
 -                print "GetPersons failed",persons_result.error()
 -                return
 -            person = persons[0]
 -            print "PERSON=", person
 -
 -            request.session['manifold'] = {'auth': api.auth, 'person': person, 'expires': session['expires']}
 +            # usernameldap is optional - from LDAP user form. 
 +            # If it is filled - See portal/homeview.py too
 +            if 'usernameldap' in token:
 +                usernameldap = token['usernameldap']
 +            else:
 +                usernameldap = None
 +            password = token['password']
 +            # if data are not from LDAP form then normal (local) login
 +            if not usernameldap:
 +                print "not userldap ManifoldBackend authenticate()"
 +                auth = {'AuthMethod': 'password', 'Username': username, 'AuthString': password}
 +                api = ManifoldAPI(auth)
 +                sessions_result = api.forward(Query.create('local:session').to_dict())
 +                print "result"
 +                sessions = sessions_result.ok_value()
 +                print "ok"
 +                if not sessions:
 +                    print "GetSession failed", sessions_result.error()
 +                    return
 +                print "first", sessions
 +                session = sessions[0]
 +
 +                # Change to session authentication
 +                api.auth = {'AuthMethod': 'session', 'session': session['session']}
 +                self.api = api
 +
 +                # Get account details
 +                # the new API would expect Get('local:user') instead
 +                persons_result = api.forward(Query.get('local:user').to_dict())
 +                persons = persons_result.ok_value()
 +                if not persons:
 +                    print "GetPersons failed",persons_result.error()
 +                    return
 +                person = persons[0]
 +                print "PERSON=", person
 +
 +                request.session['manifold'] = {'auth': api.auth, 'person': person, 'expires': session['expires']}
 +            ################################
 +            # Edelberto LDAP authentication
 +            # if data are from LDAP form, so
 +            else:
 +                print "userldap ManifoldBackend authenticate()"
 +            # XXX UGLY
 +            # Needing to create an specific entries at settings.py (or myslice.ini) for these vars
 +            ##################################################
 +            # Edelberto - UFF - esilva@ic.uff.br
 +            # v1 - ldap authentication module
 +            # Note: focus on LDAP FIBRE-BR for DN
 +            #       if uses other DN, configuration are needed
 +            ###################################################
 +            #Searching an LDAP Directory
 +
 +                try:
 +                    #uid = "debora@uff.br"
 +
 +                    # Receiving an email address, how can we split and mount it in DN format?
 +                    #mail = "debora@uff.br"
 +                    mail = usernameldap
 +                    login = mail.split('@')[0]
 +                    org = mail.split('@')[1]
 +                    o = org.split('.')[0]
 +                    dc = org.split('.')[1]
 +                    '''
 +                    print mail
 +                    print login
 +                    print org
 +                    print o
 +                    print dc
 +                    '''
 +
 +                    # DN format to authenticate - IMPORTANT!
 +                    #FIBRE-BR format
 +                    uid = "uid="+mail+",ou=people,o="+o+",dc="+dc
 +                    #uid = "uid=debora@uff.br,ou=people,o=uff,dc=br"
 +                    # User password from LDAP form
 +                    #userPassword = "fibre"
 +                    userPassword = password
 +
 +                    # testing with:
 +                    # wrong password for test
 +                    #    userPassword = "fibre2"
 +                    
 +                    # Parameters to connect on LDAP
 +                    ldap.set_option(ldap.OPT_REFERRALS, 0)
 +                    # LDAP Server Address
 +                    l = ldap.open("127.0.0.1")
 +                    # LDAP version
 +                    l.protocol_version = ldap.VERSION3
 +
 +                    #l.simple_bind(uid, userPassword)
 +                    # l.bind_s is necessary to do the authentication with a normal LDAP user
 +                    l.bind_s(uid, userPassword, ldap.AUTH_SIMPLE)
 +                    #print l.bind_s(uid, userPassword, ldap.AUTH_SIMPLE)
 +
 +                    # DN base - Our root dc (dc=br)
 +                    baseDN="dc="+dc
 +                    searchScope = ldap.SCOPE_SUBTREE
 +                    retrieveAttributes = None
 +                    # User only can see its credentials. He search only his attributes
 +                    searchFilter = "uid="+mail
 +
 +                    # Getting all attributes
 +                    try:
 +                        ldap_result_id = l.search(baseDN, searchScope, searchFilter, retrieveAttributes)
 +                        result_set = []
 +                        # while exist attributes, save them in a list!
 +                        while 1:
 +                        #   print l.result(ldap_result_id, 0)
 +                            result_type, result_data = l.result(ldap_result_id, 0)
 +                            if (result_data == []):
 +                            #print ("User %s don't allowed to bind in LDAP", uid)
 +                                break
 +                            else:
 +                                ## Appendng to a list
 +                                if result_type == ldap.RES_SEARCH_ENTRY:
 +                                    result_set.append(result_data)
 +                                    #    print result_set
 +                    except ldap.LDAPError, e:
 +                        print e
 +
 +                    # Matching if the user is really who his say
 +                    #checkldap = None
 +                    if l.compare_s(uid, 'uid', mail):
 +                        # DEBUG
 +                        checkldap = True
 +                        print "match"
 +
 +                # Now, based on default Manifold Auth
 +                        auth = {'AuthMethod': 'password', 'Username': usernameldap, 'AuthString': password}
 +                        api = ManifoldAPI(auth)
 +                        sessions_result = api.forward(Query.create('local:session').to_dict())
 +                        print "result"
 +                        sessions = sessions_result.ok_value()
 +                        print "ok"
 +                        if not sessions:
 +                            print "GetSession failed", sessions_result.error()
 +                            return
 +                        print "first", sessions
 +                        session = sessions[0]
 +
 +                        # Change to session authentication
 +                        api.auth = {'AuthMethod': 'session', 'session': session['session']}
 +                        self.api = api
 +
 +                        # Get account details
 +                        # the new API would expect Get('local:user') instead
 +                        persons_result = api.forward(Query.get('local:user').to_dict())
 +                        persons = persons_result.ok_value()
 +                        if not persons:
 +                            print "GetPersons failed",persons_result.error()
 +                            return
 +                        person = persons[0]
 +                        print "PERSON=", person
 +
 +                        request.session['manifold'] = {'auth': api.auth, 'person': person, 'expires': session['expires']}
 +
 +                    else:
 +                        print "no match. User doesnt allowed"
 +                        checkldap = False
 +
 +                except ldap.LDAPError, e:
 +                    print "E: LDAP Search user", e                      
 +        # end of LDAP
 +       
 +        # Follow the same of Manifold 
          except ManifoldException, e:
              print "ManifoldBackend.authenticate caught ManifoldException, returning corresponding ManifoldResult"
              return e.manifold_result
              import traceback
              traceback.print_exc()
              return None
 -
 -        try:
 -            # Check if the user exists in Django's local database
 -            user = User.objects.get(username=username)
 -        except User.DoesNotExist:
 -            # Create a user in Django's local database
 -            user = User.objects.create_user(username, username, 'passworddoesntmatter')
 -            user.email = person['email']
 +    
 +        if not usernameldap:
 +            try:
 +                # Check if the user exists in Django's local database
 +               user = User.objects.get(username=username)
 +            except User.DoesNotExist:
 +                # Create a user in Django's local database
 +                user = User.objects.create_user(username, usernamep, 'passworddoesntmatter')
-                 user.first_name = "DUMMY_FIRST_NAME" #person['first_name']
-                 user.last_name = "DUMMY LAST NAME" # person['last_name']
 +                user.email = person['email']
-             return user
 +        else:
 +            if checkldap:
 +                try:
 +                    # Check if the user exists in Django's local database
 +                    user = User.objects.get(username=usernameldap)
 +                except User.DoesNotExist:
 +                    # Create a user in Django's local database
 +                    user = User.objects.create_user(username, usernameldap, 'passworddoesntmatter')
-                     user.first_name = "DUMMY_FIRST_NAME" #person['first_name']
-                     user.last_name = "DUMMY LAST NAME" # person['last_name']
 +                    user.email = person['email']
-                 return user
  
 -
+         if 'firstname' in person:
+             user.first_name = person['firstname']
+         if 'lastname' in person:
+             user.last_name = person['lastname']
+         return user
      # Required for your backend to work properly - unchanged in most scenarios
      def get_user(self, user_id):
          try:
diff --combined myslice/settings.py
index cf9cbb6,620ab5b..d4240f4
mode 100644,100755..100755
@@@ -2,6 -2,13 +2,13 @@@
  
  import os.path
  
+ ### detect if we're in a build environment
+ try:
+     import manifold
+     building=False
+ except:
+     building=True
  DEBUG = True
  TEMPLATE_DEBUG = DEBUG
  
@@@ -19,17 -26,28 +26,28 @@@ except
      import traceback
      traceback.print_exc()
  
+ #### this is where the problem lies I believe
+ # first try to run manage.py collectstatic without this
+ # themes
+ theme=None
+ try:
+     from myslice.configengine import ConfigEngine
+     configEngine = ConfigEngine()
+     if configEngine.myslice.theme :
+         theme = configEngine.myslice.theme
+ except:
+     pass
+     
  # find out HTTPROOT, which is different from ROOT 
  # when deployed from a package
  # this code is run by collectstatic too, so we cannot
  # assume we have ./static present already
 -HTTPROOT="/usr/share/unfold"
 +HTTPROOT="/var/www/myslice"
  # the place to store local data, like e.g. the sqlite db
 -DATAROOT="/var/unfold"
 +DATAROOT="/var/www/myslice"
  # if not there, then we assume it's from a devel tree
  if not os.path.isdir (os.path.join(HTTPROOT,"static")):
      HTTPROOT=ROOT
-     DATAROOT=ROOT
  
  if not os.path.isdir(ROOT): raise Exception,"Cannot find ROOT %s for unfold"%ROOT
  if not os.path.isdir(HTTPROOT): raise Exception,"Cannot find HTTPROOT %s for unfold"%HTTPROOT
@@@ -181,17 -199,17 +199,18 @@@ ROOT_URLCONF = 'myslice.urls
  
  # Python dotted path to the WSGI application used by Django's runserver.
  WSGI_APPLICATION = 'unfold.wsgi.application'
 +#WSGI_APPLICATION = 'myslice.wsgi.application'
  
- TEMPLATE_DIRS = (
-     # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
-     # Always use forward slashes, even on Windows.
-     # Don't forget to use absolute paths, not relative paths.
-     #os.path.join(HTTPROOT,"templates"),
-     os.path.join(HTTPROOT,"templates"),
- )
+ TEMPLATE_DIRS = [ ]
+ # Put strings here, like "/home/html/django_templates" or "C:/www/django/templates".
+ # Always use forward slashes, even on Windows.
+ # Don't forget to use absolute paths, not relative paths.
+ if theme is not None:
+     TEMPLATE_DIRS.append ( os.path.join(HTTPROOT,"portal/templates", theme))
+ TEMPLATE_DIRS.append     ( os.path.join(HTTPROOT,"portal/templates"))
+ TEMPLATE_DIRS.append     (  os.path.join(HTTPROOT,"templates"))
  
- INSTALLED_APPS = [
+ INSTALLED_APPS = [ 
      'django.contrib.auth',
      'django.contrib.contenttypes',
      'django.contrib.sessions',
      # our django project
      'myslice',
      # the core of the UI
-     'auth', 'manifoldapi', 'unfold',
+     'auth', 
+     'manifoldapi',
+     'unfold',
      # plugins
      'plugins',
      # views - more or less stable 
      # Uncomment the next line to enable admin documentation:
      # 'django.contrib.admindocs',
      'portal',
-     'rest',
  ]
+ # this app won't load in a build environment
+ if not building: INSTALLED_APPS.append ('rest')
  for aux in auxiliaries:
      if os.path.isdir(os.path.join(ROOT,aux)): 
          print "Using devel auxiliary",aux
@@@ -265,6 -287,3 +288,6 @@@ CSRF_FAILURE_VIEW = 'manifoldapi.manifo
  #IA_JS_FORMAT = "<script type='text/javascript' src='{URL}' />"
  # put stuff under static/
  # IA_MEDIA_PREFIX = '/code/'
 +
 +SESSION_ENGINE = 'django.contrib.sessions.backends.file'
 +
diff --combined myslice/urls.py
@@@ -15,22 -15,20 +15,22 @@@ from settings import auxiliaries, INSTA
  import portal.platformsview
  import portal.dashboardview
  import portal.homeview
+ import portal.newsview
  
 +import plugins.cafe.edelberto
 +
  home_view=portal.homeview.HomeView.as_view()
  dashboard_view=portal.dashboardview.DashboardView.as_view()
  platforms_view=portal.platformsview.PlatformsView.as_view()
  
- import portal.testbedlist
#import portal.testbedlist
  import portal.sliceview
  import portal.sliceresourceview
  
  import portal.slicetabexperiment
  import portal.slicetabinfo
  import portal.slicetabtestbeds
- from portal.sliceuserview import SliceUserView 
+ import portal.slicetabusers 
  
  #### high level choices
  # main entry point (set to the / URL)
@@@ -82,14 -80,13 +82,13 @@@ urls = 
      #
      #
      # Portal
-     
+     (r'^news/?$', portal.newsview.NewsView.as_view()),
      (r'^resources/(?P<slicename>[^/]+)/?$', portal.sliceresourceview.SliceResourceView.as_view()),
+     (r'^users/(?P<slicename>[^/]+)/?$', portal.slicetabusers.SliceUserView.as_view()),
      
      (r'^slice/(?P<slicename>[^/]+)/?$', portal.sliceview.SliceView.as_view()),
-     
      (r'^info/(?P<slicename>[^/]+)/?$', portal.slicetabinfo.SliceInfoView.as_view()),
      (r'^testbeds/(?P<slicename>[^/]+)/?$', portal.slicetabtestbeds.SliceTabTestbeds.as_view()),
-     (r'^users/(?P<slicename>[^/]+)/?$', SliceUserView.as_view()),
      (r'^experiment/(?P<slicename>[^/]+)/?$', portal.slicetabexperiment.ExperimentView.as_view()),
      url(r'^portal/', include('portal.urls')),
  ]
@@@ -102,10 -99,3 +101,10 @@@ for aux in auxiliaries
          urls.append ( url ( r'^%s/'%aux, include ('%s.urls'%aux )))
  
  urlpatterns = patterns(*urls)
 +
 +# Shibboleth - Edelberto
 +urlpatterns += patterns('',
 +   url(r'^cafe/', plugins.cafe.edelberto.EdelbertoView.as_view()),
 +   #url(r'^cafe/', 'plugins.cafe.edelberto.index'),
 +)
 +
diff --combined portal/actions.py
@@@ -8,7 -8,7 +8,7 @@@ from django.contrib.auth.models import 
  from django.template.loader     import render_to_string
  from django.core.mail           import EmailMultiAlternatives
  
- from theme                      import ThemeView
+ from myslice.theme                      import ThemeView
  
  theme = ThemeView()
  
@@@ -23,6 -23,7 +23,7 @@@
  def authority_get_pis(request, authority_hrn):
      query = Query.get('authority').filter_by('authority_hrn', '==', authority_hrn).select('pi_users')
      results = execute_admin_query(request, query)
+     print "authority_get_pis = %s" % results
      # NOTE: temporarily commented. Because results is giving empty list. 
      # Needs more debugging
      #if not results:
@@@ -33,6 -34,8 +34,8 @@@
  
  def authority_get_pi_emails(request, authority_hrn):
      pi_users = authority_get_pis(request,authority_hrn)
+     print "pi_users = %s" % pi_users
      if any(d['pi_users'] == None for d in pi_users):
          theme.template_name = 'email_default_recipients.txt' 
          default_email = render_to_string(theme.template, request)
@@@ -279,7 -282,7 +282,7 @@@ def portal_validate_request(wsgi_reques
              try:
                  create_user(wsgi_request, request)
                  request_status['SFA user'] = {'status': True }
+                 PendingUser.objects.get(id=request['id']).delete()
              except Exception, e:
                   request_status['SFA user'] = {'status': False, 'description': str(e)}
                         
              try:
                  create_slice(wsgi_request, request)
                  request_status['SFA slice'] = {'status': True }
+                 PendingSlice.objects.get(id=request['id']).delete()
  
              except Exception, e:
                  request_status['SFA slice'] = {'status': False, 'description': str(e)}
                  print "ADD Authority"
                  sfa_add_authority(wsgi_request, sfa_authority_params)
                  request_status['SFA authority'] = {'status': True }
+                 PendingAuthority.objects.get(id=request['id']).delete()
  
              except Exception, e:
                  request_status['SFA authority'] = {'status': False, 'description': str(e)}
@@@ -402,7 -407,7 +407,7 @@@ def create_pending_slice(wsgi_request, 
      try:
          # Send an email: the recipients are the PI of the authority
          recipients = authority_get_pi_emails(wsgi_request, request['authority_hrn'])
-     
          theme.template_name = 'slice_request_email.txt' 
          text_content = render_to_string(theme.template, request)
      
          subject = subject.replace('\n', '')
      
          sender = email
-         msg = EmailMultiAlternatives(subject, text_content, sender, [recipients])
-         print msg
+         msg = EmailMultiAlternatives(subject, text_content, sender, recipients)
          msg.attach_alternative(html_content, "text/html")
          msg.send()
      except Exception, e:
@@@ -500,138 -504,6 +504,138 @@@ def sfa_create_user(wsgi_request, reque
          raise Exception, "Could not create %s. Already exists ?" % sfa_user_params['user_hrn']
      return results
  
 +def ldap_create_user(wsgi_request, request, user_detail):
 +    """
 +    Populating LDAP withuser data - Edelberto 10/03/2014
 +    """
 +    # import needed modules
 +    import ldap
 +    import ldap.modlist as modlist
 +
 +    # Open a connection
 +    # XXX We need to create this in settings
 +    # ldap.open is deprecated!
 +    #l = ldap.open("127.0.0.1")
 +    l = ldap.initialize('ldap://127.0.0.1:389')
 +
 +    # you should  set this to ldap.VERSION2 if you're using a v2 directory
 +    l.protocol_version = ldap.VERSION3
 +
 +    # Bind/authenticate with a user with apropriate rights to add objects
 +    # XXX Now we set the force rootd but after we need to set this in settings file for could change the dn and password of root
 +    l.simple_bind_s("cn=Manager,dc=br","fibre")
 +
 +    # The dn of our new entry/object
 +    #dn="uid=addtest@uff.br,ou=people,o=uff,dc=br"
 +
 +    # we need to create the dn entry
 +    # Receiving an email address, how can we split and mount it in DN format?
 +    #mail = "debora@uff.br"
 +    mail = request['email']
 +    login = mail.split('@')[0]
 +    org = mail.split('@')[1]
 +    o = org.split('.')[-2]
 +    dc = org.split('.')[-1]
 +
 +    # DN format to authenticate - IMPORTANT!
 +    #FIBRE-BR format
 +    dn = "uid="+mail+",ou=people,o="+o+",dc="+dc
 +
 +    # DEBUG
 +    print "dn:"+dn
 +    print request['password']
 +
 +    # Creating a unique uidNumber - Necessary for experiments
 +    # Was defined to began in 100000
 +    unique = int(user_detail['user_id']) + 100000
 +    #unique = int(unique)
 +    print unique
 +
 +    # A dict to help build the "body" of the object
 +    attrs = {}
 +    attrs['objectclass'] = ['person','inetOrgPerson','posixAccount','eduPerson','brPerson','schacPersonalCharacteristics','fibre', 'ldapPublicKey']
 +    # XXX Converting all unicodes to string
 +    attrs['uid'] = mail.encode('utf-8')
 +    attrs['cn'] = request['first_name'].encode('latin1')
 +    attrs['sn'] = request['last_name'].encode('latin1')
 +    # XXX we need to set a unique uidNumber. How?
 +    attrs['uidNumber'] = str(unique)
 +    attrs['gidNumber'] = '500'
 +    attrs['homeDirectory'] = "/home/"+org+"/"+mail
 +    attrs['homeDirectory'] = attrs['homeDirectory'].encode('utf-8')
 +    attrs['mail'] = mail.encode('utf-8')
 +    attrs['eppn'] = mail.encode('utf8')
 +    attrs['userPassword'] = request['password'].encode('utf-8')
 +    attrs['sshPublicKey'] = request['public_key'].encode('utf-8')
 +    # XXX We really set TRUE for those attributes? 
 +    #attrs['userEnable'] = 'TRUE'
 +    # set FALSE and change after when the user is validated
 +    attrs['userEnable'] = 'FALSE'
 +    attrs['omfAdmin'] = 'TRUE'
 +
 +    # Convert our dict to nice syntax for the add-function using modlist-module
 +    ldif = modlist.addModlist(attrs)
 +
 +    # DEBUG
 +    print attrs['userPassword']
 +    print attrs['cn']
 +    print attrs['sn']
 +    print attrs['homeDirectory']
 +    #print ldif
 +
 +    # Do the actual synchronous add-operation to the ldapserver
 +    l.add_s(dn,ldif)
 +
 +    # Its nice to the server to disconnect and free resources when done
 +    l.unbind_s()
 +
 +    return ldif
 +
 +def ldap_modify_user(wsgi_request, request):
 +    #Modify entries in an LDAP Directory
 +
 +    #Synchrounous modify
 +    # import needed modules
 +    import ldap
 +    import ldap.modlist as modlist
 +
 +    # Open a connection
 +    l = ldap.initialize("ldap://localhost:389/")
 +
 +    # Bind/authenticate with a user with apropriate rights to add objects
 +    l.simple_bind_s("cn=Manager,dc=br","fibre")
 +
 +    # we need to create the dn entry
 +    # Receiving an email address, how can we split and mount it in DN format?
 +    #mail = "debora@uff.br"
 +    mail = request['email']
 +    login = mail.split('@')[0]
 +    org = mail.split('@')[1]
 +    o = org.split('.')[-2]
 +    dc = org.split('.')[-1]
 +
 +    # DN format to authenticate - IMPORTANT!
 +    #FIBRE-BR format
 +    dn = "uid="+mail+",ou=people,o="+o+",dc="+dc
 +
 +    # The dn of our existing entry/object
 +    #dn="uid=mario@uff.br,ou=people,o=uff,dc=br"
 +
 +    # Some place-holders for old and new values
 +    old = {'userEnable':'FALSE'}
 +    new = {'userEnable':'TRUE'}
 +
 +    # Convert place-holders for modify-operation using modlist-module
 +    ldif = modlist.modifyModlist(old,new)
 +
 +    # Do the actual modification
 +    l.modify_s(dn,ldif)
 +
 +    # Its nice to the server to disconnect and free resources when done
 +    l.unbind_s()
 +
 +    return ldif
 +
  def create_user(wsgi_request, request):
      
      # XXX This has to be stored centrally
  
      # NOTE : if we were to create a user directly (just like we create slices,
      # we would have to perform the steps in create_pending_user too
 -
 +    
 +    # Edelberto - I put this more below
      # Add the user to the SFA registry
 -    sfa_create_user(wsgi_request, request)
 +    #sfa_create_user(wsgi_request, request)
  
      # Update Manifold user status
      manifold_update_user(wsgi_request, request['email'], {'status': USER_STATUS_ENABLED})
  
      # Add reference accounts for platforms
      manifold_add_reference_user_accounts(wsgi_request, request)
 +    
 +# Add the user to the SFA registry
 +    sfa_create_user(wsgi_request, request)
 +
 +    # LDAP update user userEnabled = True
 +    try:
 +        mail = request['email']
 +        login = mail.split('@')[0]
 +        org = mail.split('@')[1]
 +        o = org.split('.')[-2]
 +        dc = org.split('.')[-1]
 +        # To know if user is a LDAP user - Need to has a 'dc' identifier
 +        if dc == 'br' or 'eu':
 +            ldap_modify_user(wsgi_request, request)
 +    except Exception, e:
 +        "LDAP create user failed"
  
  def create_pending_user(wsgi_request, request, user_detail):
      """
              .filter_by('platform', '==', 'myslice')           \
              .select('platform_id')
          reg_platform = execute_admin_query(wsgi_request, reg_platform_query)
 -
          reg_platform_id = reg_platform[0]['platform_id']
          account_params = {
              'platform_id'   : reg_platform_id, # XXX ALERT !!
          }
          manifold_add_account(wsgi_request, account_params)
      except Exception, e:
 -        print "Failed creating manifold account on platform %s for user: %s" % ('myslice', request['email'])
 +       print "Failed creating manifold account on platform %s for user: %s" % ('myslice', request['email'])
 +
 +    # Add user to LDAP userEnabled = False
 +    # Not more here. Create before directly to the registrationview.py
 +    # After we change userEnable = TRUE when validate the user
  
      try:
          # Send an email: the recipients are the PI of the authority
          sender =  render_to_string(theme.template, request)
          sender = sender.replace('\n', '')
      
-         msg = EmailMultiAlternatives(subject, text_content, sender, [recipients])
+         msg = EmailMultiAlternatives(subject, text_content, sender, recipients)
          msg.attach_alternative(html_content, "text/html")
          msg.send()
      except Exception, e:
          print "Failed to send email, please check the mail templates and the SMTP configuration of your server"
+         import traceback
+         traceback.print_exc()
diff --combined portal/homeview.py
@@@ -12,7 -12,7 +12,7 @@@ from manifoldapi.manifoldresult import 
  from ui.topmenu import topmenu_items, the_user
  from myslice.configengine import ConfigEngine
  
- from theme import ThemeView
+ from myslice.theme import ThemeView
  
  class HomeView (FreeAccessView, ThemeView):
      template_name = 'home-view.html'
      def post (self,request):
          env = self.default_env()
          env['theme'] = self.theme
+         env['section'] = "Dashboard"
+         
          username = request.POST.get('username')
          password = request.POST.get('password')
 +       
 +        # LDAP form - If FIBRE, then get the possibilite to authenticate using usernameldap
 +        #if self.theme == 'fibre':
 +        usernameldap = request.POST.get('usernameldap')
 +        token = {'usernameldap': usernameldap, 'username': username ,'password': password, 'request': request}    
 +        #else:
          
 -        # pass request within the token, so manifold session key can be attached to the request session.
 -        token = {'username': username, 'password': password, 'request': request}    
 +        # Follow original code
 +        ## pass request within the token, so manifold session key can be attached to the request session.
 +        #token = {'username': username, 'password': password, 'request': request}    
  
          # our authenticate function returns either
          # . a ManifoldResult - when something has gone wrong, like e.g. backend is unreachable
@@@ -85,7 -80,7 +87,7 @@@
              env['person'] = None
      
          env['theme'] = self.theme
-     
+         env['section'] = "Dashboard"
  
          env['username']=the_user(request)
          env['topmenu_items'] = topmenu_items(None, request)
@@@ -6,6 -6,7 +6,7 @@@ from django.views.generic       import 
  from django.template.loader     import render_to_string
  from django.shortcuts           import render
  from django.contrib.auth        import get_user_model
+ from django.contrib.sites.models import Site
  
  from unfold.page                import Page
  from unfold.loginrequired       import FreeAccessView
@@@ -15,11 -16,9 +16,11 @@@ from manifoldapi.manifoldapi    import 
  from manifold.core.query        import Query
  
  from portal.models              import PendingUser
 -from portal.actions             import create_pending_user
 +#from portal.actions             import create_pending_user
 +# Edelberto - LDAP
 +from portal.actions             import create_pending_user, ldap_create_user
  
- from theme import ThemeView
+ from myslice.theme import ThemeView
  
  # since we inherit from FreeAccessView we cannot redefine 'dispatch'
  # so let's override 'get' and 'post' instead
@@@ -51,6 -50,10 +52,10 @@@ class RegistrationView (FreeAccessView
  
          if method == 'POST':
              # The form has been submitted
+             
+             # get the domain url
+             current_site = Site.objects.get_current()
+             current_site = current_site.domain
  
              user_request = {
                  'first_name'    : wsgi_request.POST.get('firstname',     ''),
@@@ -58,6 -61,7 +63,7 @@@
                  'authority_hrn' : wsgi_request.POST.get('authority_hrn', ''),
                  'email'         : wsgi_request.POST.get('email',         '').lower(),
                  'password'      : wsgi_request.POST.get('password',      ''),
+                 'current_site'  : current_site
              }
  
              # Construct user_hrn from email (XXX Should use common code)
                  if user_detail['email'] == user_request['email']:
                      errors.append('Email already registered in Manifold. Please provide a new email address.')
              # Does the user exist in sfa? [query is very slow!!]
-             user_query  = Query().get('user').select('user_hrn','user_email')
+             #user_query  = Query().get('user').select('user_hrn','user_email')
+             # XXX Test based on the user_hrn is quick
+             user_query  = Query().get('user').select('user_hrn','user_email').filter_by('user_hrn','==',user_request['user_hrn'])
              user_details_sfa = execute_admin_query(wsgi_request, user_query)
              for user in user_details_sfa:
                  if user['user_email'] == user_request['email']:
                      errors.append('Email already registered in SFA registry. Please use another email.')
                  user_request['public_key']  = file_content
                  
              if not errors:
 +                try:
 +                    # verify if is a  LDAP 
 +                    mail = user_detail['email']
 +                    login = mail.split('@')[0]
 +                    org = mail.split('@')[1]
 +                    o = org.split('.')[-2]
 +                    dc = org.split('.')[-1]
 +                    # To know if user is a LDAP user - Need to has a 'dc' identifier
 +                    if dc == 'br' or 'eu':
 +                        # LDAP insert directly - but with userEnable = FALSE
 +                        ldap_create_user(wsgi_request, user_request, user_detail)
 +                except Exception, e:
 +                    print "LDAP: problem em access the LDAP with this credentail" 
                  create_pending_user(wsgi_request, user_request, user_detail)
                  self.template_name = 'user_register_complete.html'
 +            
                  return render(wsgi_request, self.template, {'theme': self.theme}) 
  
          else:
index 0000000,0000000..a610c87
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,42 @@@
++{% extends "layout.html" %}
++
++{% block head %}
++{{ wizard.form.media }}
++{% endblock %}
++
++{% block content %}
++<div class="row">
++      <div class="col-md-12">
++      <h1><img src="{{ STATIC_URL }}img/icon_support_small.png" alt="Open a Ticket" /> FIBRE Support</h1>
++      </div>
++</div>
++<div class="row">
++      <div class="col-md-12">&nbsp;</div>
++</div>
++<div class="row">
++      <div class="col-md-12">
++      <p>Please check our <a href="/portal/support/">FAQ</a> section. Most of the basic problems are explained there.</p>
++      <p>
++      If you haven't find your answes in the FAQ, please contact us by filling the form below.<br />
++      You can also <a href="mailto:support@myslice.info">e-mail</a> us directly.
++      </p>
++      </div>
++</div>
++
++<div class="row">
++      <div class="col-md-2"></div>
++      <div class="col-md-8">
++              <form role="form" method="post">
++              {% csrf_token %}
++              {% for field in form %}
++          <div class="form-group">
++              <label for="{{ field.html_name }}" class="control-label">{{ field.label }}</label>
++              {{ field.errors }} {{ field }}
++          </div>
++          {% endfor %}
++              <button type="submit" class="btn btn-default">Create Ticket</button>
++              </form>
++      </div>
++</div>
++{% endblock %}
++
index 0000000,0000000..3a22020
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,15 @@@
++{% extends "layout.html" %}
++
++{% block content %}
++<div class="row">
++      <div class="col-md-12">
++      <h1><img src="{{ STATIC_URL }}img/icon_support_small.png" alt="Open a Ticket" /> FIBRE Portal Documentation</h1>
++      </div>
++</div>
++<div class="row">
++      <div class="col-md-12">
++
++</div>
++</div>
++{% endblock %}
++
index 0000000,0000000..eb59dfe
new file mode 100644 (file)
--- /dev/null
--- /dev/null
@@@ -1,0 -1,0 +1,120 @@@
++{% extends "layout.html" %}
++
++{% block content %}        
++
++<div class="row">
++      <div class="col-md-12">
++      <h1><img src="{{ STATIC_URL }}img/icon_user_small.png" alt="User Registration" /> FIBRE Experimenter Registration</h1>
++      </div>
++</div>
++<div class="row">
++      <div class="col-md-12">
++              <h3>For First Line Support please <a href="/portal/contact" >Contact Support</a></h3>
++      </div>
++</div>
++{% if errors %}
++<ul>
++  {% for error in errors %}
++  <li>{{ error }}</li>
++  {% endfor %}
++</ul>
++{% endif %}
++   
++<div class="row">
++      <div class="col-md-2"></div>
++      <div class="col-md-8">
++      <form class="cmxform form-horizontal" id="registrationForm" method="post" enctype="multipart/form-data" role="form">
++    {% csrf_token %}
++    <div class="form-group">
++      <label for="firstname" class="control-label">First Name</label>
++              <input type="text" name="firstname" class="form-control" minlength="2" value="{{ firstname }}" placeholder="First Name" required />
++    </div>
++    <div class="form-group">
++      <label for="lastname" class="control-label">Last Name</label>
++              <input type="text" name="lastname" size="25" class="form-control" minlength="2" value="{{ lastname }}" placeholder="Last Name" required />
++    </div>
++    <div class="form-group">
++      <label for="authority_hrn" class="control-label">Authority</label>
++      <input id="authority_hrn" name="authority_hrn" class="form-control" value="{{ authority_hrn }}" required>
++      <p class="help-block">An authority responsible for vetting your account</p>
++    </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-2 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-6"><p class="form-hint">Enter your login</p></div>
++    </div>
++      -->
++
++    <div class="form-group">
++      <label for="email" class="control-label">Email</label>
++      <input type="email" name="email" size="25"  class="form-control" value="{{ email }}" required/>
++    </div>
++    <div class="form-group">
++      <label for="password" class="control-label">Password</label>
++      <input type="password"  id="password" name="password"   class="form-control" minlength="4" value="{{ password }}" required/>
++    </div>
++    <div class="form-group">
++      <label for="password" class="control-label">Confirm Password</label>
++              <input type="password"  id="confirmpassword" name="confirmpassword"   minlength="4" class="form-control" value="" placeholder="Confirm Password" required/>
++    </div>
++    <div class="form-group">
++      <label for="question" class="control-label">My Keys</label>
++              <select name="question" class="form-control" id="key-policy" required>        
++                      <option value="generate">Generate key pairs for me </option>
++                      <option value="upload">Upload my public key </option>
++              </select>
++              <p class="help-block">Genkey: Account Delegation Automatic (Recommended)</p>
++    </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" id="user_public_key" required>
++              <br />
++              <div class="alert alert-danger" id="pkey_del_msg">
++                      Once your account is validated, you will have to delegate your credentials manually using SFA [Advanced users only]
++              </div>
++              <p class="help-block">Account Delegation: Manual (Advanced Users)</p>
++    </div>
++    <div class="form-group" id="register">
++      <button class="submit btn btn-default" type="submit">Register</button>
++    </div>
++  </form>  
++</div>
++<script>
++jQuery(document).ready(function(){
++    var availableTags = [
++    {% if authorities %}
++        {% for authority in authorities %}
++            {% if authority.name %}
++                {value:"{{ authority.authority_hrn }}",label:"{{authority.name}}"},
++            {% else %}
++                {value:"{{ authority.authority_hrn }}",label:"{{authority.authority_hrn}}"},
++            {% endif %}
++        {% endfor %}    
++    {% else %}
++        {value:"",label:"No authority found !!!"}
++    {% endif %}
++    ];
++    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))}
++    });
++});
++</script>
++{% endblock %}
++
diff --combined setup.py
+++ b/setup.py
@@@ -17,13 -17,24 +17,23 @@@ print package
  # Avoid troubles : clean /usr/share/unfold/
  #shutil.rmtree('/usr/share/unfold/')
  
 -
+ def images (dir):
+     return glob( dir+"/*.png") + glob ( dir+"/*.gif")
+ def javascript (dir):
+     return glob( dir+"/*.js")
+ def stylesheets (dir):
+     return glob( dir+"/*.css")
  setup(packages = packages,
        # xxx somehow this does not seem to show up in debian packaging
        scripts = [ 'apache/unfold-init-ssl.sh' ],
        data_files = [ 
-           ( '/usr/share/unfold/static/js', glob ('static/js/*')),
-           ( '/usr/share/unfold/static/css', glob ('static/css/*')),
-           ( '/usr/share/unfold/static/img', glob ('static/img/*')),
+           ( '/usr/share/unfold/static/js', javascript('static/js')),
+           ( '/usr/share/unfold/static/css', stylesheets ('static/css')),
+           ( '/usr/share/unfold/static/img', images ('static/img')),
+ # for portal/          
+           ( '/usr/share/unfold/static/img/institutions', images ('static/img/institutions')),
+           ( '/usr/share/unfold/static/img/testbeds', images ('static/img/testbeds')),
            ( '/usr/share/unfold/static/fonts', glob ('static/fonts/*')),
            ( '/usr/share/unfold/templates', glob ('templates/*')),
            ( 'apache', [ 'apache/unfold.conf', 'apache/unfold-ssl.conf', 'apache/unfold.wsgi' ]),