#! /usr/bin/env python

#############################################################
#                                                           #
#   Author: Bertrand Neron                                  #
#   Organization:'Biological Software and Databases' Group, #
#                Institut Pasteur, Paris.                   #
#   Distributed under GPLv2 Licence. Please refer to the    #
#   COPYING.LIB document.                                   #
#                                                           #
#############################################################

import sys
from hashlib import md5
import os , os.path

MOBYLEHOME = None
if os.environ.has_key('MOBYLEHOME'):
    MOBYLEHOME = os.environ['MOBYLEHOME']
if not MOBYLEHOME:
    sys.exit('MOBYLEHOME must be defined in your environment')

if ( os.path.join( MOBYLEHOME , 'Src' ) ) not in sys.path:    
    sys.path.append( os.path.join( MOBYLEHOME , 'Src' ) )


from Mobyle.ConfigManager import Config
from Mobyle.Session import Session , Transaction
from Mobyle.MobyleError import MobyleError , SessionError 
from Mobyle.Net import Email


class SessionPasswd( Session ):

    def __init__( self , email , cfg ):
        self.newPasswd = None
        self.cfg = cfg
        self.email = Email( email , cfg )
        email_checked = self.email.check()
        if not email_checked:
            msg = self.email.getMessage()
            raise MobyleError , msg        

        sessionDir , key = self._findSession()
        Session.__init__( self, sessionDir , key , self.cfg )
        if self.email.To != self.getEmail():
            raise MobyleError , "the email %s in xml does not match the session Key %s" %( self.getEmail() , key ) 
        
    def setPasswd( self, newPasswd ):
        newMd5 = md5()
        newMd5.update( newPasswd )
        newCryptPasswd = newMd5.hexdigest()
        transaction = self._getTransaction( Transaction.WRITE)
        try:
            transaction.setPasswd( newCryptPasswd )
            self.newPasswd = newPasswd
            transaction.commit()
        except:
            transaction.rollback()
            
    def sendNewPasswd(self):
        if not self.newPasswd:
            raise MobyleError , "password has not been set"
        subject = "nouveau mot de passe"
        portalUrl = "%s/%s/portal.py" %( self.cfg.root_url() ,
                                        self.cfg.cgi_url()
                                        )
        
        msg = """you ask to change your password for account at
%(server)s server
new password = %(passwd)s
you can change this password blablabla
        """ %{ 'server' : portalUrl ,
               'passwd' : self.newPasswd
               }
        
        self.email.sendMsg( subject , msg )

    def _findSession( self ):
        newMd5 = md5()
        newMd5.update( self.email.To )
        key = newMd5.hexdigest()
        sessionDir = os.path.join( cfg.user_sessions_path() , 'authentified' , key )
        if os.path.exists( sessionDir ):
            return sessionDir , key
        else:
            raise SessionError , "there no session corresonding to %s" % self.email.To
        
if __name__ == '__main__':
    
    def usage():
        return "mpasswd email passwd"
        
    try:
        email , passwd = sys.argv[1:3]
    except Exception:
        print >> sys.stderr , usage()
        sys.exit(1)
        
    cfg = Config()
    try:
        sPasswd = SessionPasswd( email , cfg )
        sPasswd.setPasswd( passwd )
        print >> sys.stderr , "the password for user %s has been updated successfully" % email
    except Exception ,err:
        print >> sys.stderr , "changing password for user %s aborted :\n %s" %( email , err )
        sys.exit(2)
    try:   
        sPasswd.sendNewPasswd()
        print >> sys.stderr , "the new password for user %s has been send successfully" % email
    except Exception , err :
        print >> sys.stderr , "the new password cannot be send to %s :\n %s" %( email , err )
        sys.exit(3)
        
    
