We launched new forums in March 2019—join us there. In a hurry for help with your website? Get Help Now!
    • 26503
    • 620 Posts
    Sean Kimball Reply #1, 14 years ago
    I have a plugin I'm writing to allow SSO between modx & moodle, it's 99% there, but I just started getting this error;


     [2012-09-22 23:19:08] (ERROR @ /index.php) User l8FOGwLfkdBzlUNSFXZ1kbMgWhQGyCcMylx8lkraj9o= authenticated, attempting moodle login.
    [2012-09-22 23:19:08] (ERROR @ /index.php) User name is really = user001
    [2012-09-22 23:19:08] (ERROR @ /index.php) Modx user user001 successfully authenticated but was NOT found in moodle - creating moodle user!
    [2012-09-22 23:19:08] (ERROR @ /index.php) There was an error creating a new user in moodle, user = user001 exception = SoapFault exception: [Receiver] Unknown error | ERRORCODE: dmlwriteexception in /var/www/vhosts/doman.com/subdomains/sso/httpdocs/core/cache/includes/elements/modplugin/15.include.cache.php:234
    Stack trace:
    #0 /var/www/vhosts/doman.com/subdomains/sso/httpdocs/core/cache/includes/elements/modplugin/15.include.cache.php(234): SoapClient->__soapCall('core_user_creat...', Array)
    #1 /var/www/vhosts/doman.com/subdomains/sso/httpdocs/core/cache/includes/elements/modplugin/15.include.cache.php(292): createMoodleUser('user001', 'password', '918a0d5eb250235...', 'http://cme.onco...')
    #2 /var/www/vhosts/doman.com/subdomains/sso/httpdocs/core/model/modx/modscript.class.php(66): elements_modplugin_15(Array)
    #3 /var/www/vhosts/doman.com/subdomains/sso/httpdocs/core/model/modx/modx.class.php(1495): modScript->process(Array)
    #4 /var/www/vhosts/doman.com/subdomains/sso/httpdocs/core/model/modx/processors/security/login.php(188): modX->invokeEvent('OnWebLogin', Array)
    #5 /var/www/vhosts/doman.com/subdomains/sso/httpdocs/core/model/modx/modprocessor.class.php(343): include('/var/www/vhosts...')
    #6 /var/www/vhosts/doman.com/subdomains/sso/httpdocs/core/model/modx/modprocessor.class.php(173): modDeprecatedProcessor->process()
    #7 /var/www/vhosts/doman.com/subdomains/sso/httpdocs/core/model/modx/modx.class.php(1586): modProcessor->run()
    #8 /var/www/vhosts/doman.com/subdomains/sso/httpdocs/core/cache/includes/elements/modsnippet/8.include.cache.php(115): modX->runProcessor('security/login', Array)
    #9 /var/www/vhosts/doman.com/subdomains/sso/httpdocs/core/model/modx/modscript.class.php(66): elements_modsnippet_8(Array)
    #10 /var/www/vhosts/doman.com/subdomains/sso/httpdocs/core/model/modx/modparser.class.php(484): modScript->process('&preHooks=`mood...')
    #11 /var/www/vhosts/doman.com/subdomains/sso/httpdocs/core/model/modx/modparser.class.php(221): modParser->processTag(Array, true)
    #12 /var/www/vhosts/doman.com/subdomains/sso/httpdocs/core/model/modx/modresponse.class.php(83): modParser->processElementTags('', '<!DOCTYPE html ...', true, false, '[[', ']]', Array, 10)
    #13 /var/www/vhosts/doman.com/subdomains/sso/httpdocs/core/model/modx/modrequest.class.php(144): modResponse->outputContent(Array)
    #14 /var/www/vhosts/doman.com/subdomains/sso/httpdocs/core/model/modx/modrequest.class.php(128): modRequest->prepareResponse()
    #15 /var/www/vhosts/doman.com/subdomains/sso/httpdocs/core/model/modx/modx.class.php(1291): modRequest->handleRequest()
    #16 /var/www/vhosts/doman.com/subdomains/sso/httpdocs/index.php(72): modX->handleRequest()
    #17 {main}
    [2012-09-22 23:19:08] (ERROR @ /index.php) [OnWebLogin]1




    No idea what is causing this, any thoughts?
    here is the plugin itself:

    <?php
    /* Work flow
    *
    * Check if the user has a moodle cookie [?]
    * Check if the user has a moodle account & add account if necessary
    * check if user has a moodle cookie & active session already
    * update session cookie info 
    * 
    */
    
    $modx->log(modX::LOG_LEVEL_ERROR, 'User '.$_SESSION['umoodle'].' authenticated, attempting moodle login.');
    
    // Some vars!
    $key = $modx->config['moodlesso_mcryptkey'];
    $username = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode($_SESSION['umoodle']), MCRYPT_MODE_CBC, md5(md5($key))), "\0");
    $password = rtrim(mcrypt_decrypt(MCRYPT_RIJNDAEL_256, md5($key), base64_decode($_SESSION['pmoodle']), MCRYPT_MODE_CBC, md5(md5($key))), "\0");  
    $ckfile = tempnam("/tmp", "MOODCOOKIE_");
    $url = $modx->config['moodlesso_murl']; //'http://domain.com/login/index.php';
    $fields_string = 'username='.$username.'&password='.$password.'&rememberusername=1&Login';
    rtrim($fields_string, '&');
    
    // moodle DB access vars
    $mdbhost = $modx->config['moodlesso_mdbhost']; 
    $mdbname = $modx->config['moodlesso_mdbname']; 
    $mdbuser = $modx->config['moodlesso_mdbuser']; 
    $mdbpass = $modx->config['moodlesso_mdbpass']; 
    
    // moodle webservice vars
    $musertoken = $modx->config['moodlesso_token']; 
    $muserdomain = $modx->config['moodlesso_domainname']; 
    
    
    $modx->log(modX::LOG_LEVEL_ERROR, 'User name is really = '.$username);
    
    
    
    
    
    
    
    
    
    
    
    
    	/*
    	*
    	* Function tries to authenticate with the moodle database
    	* parse and set user cookies.
    	*
    	*/
    	function getMoodleCookies($url, $fields_string, $ckfile){
    		//open curl connection
    		$ch = curl_init();
    		
    		//set the url, number of POST vars, POST data
    		curl_setopt($ch,CURLOPT_URL, $url);
    		curl_setopt($ch,CURLOPT_POST, 1);
    		curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
    		curl_setopt($ch,CURLOPT_COOKIEJAR, $ckfile);
    		curl_setopt($ch,CURLOPT_RETURNTRANSFER, true);
    		
    		//execute post
    		$content = curl_exec($ch);
    		$response = curl_getinfo( $ch );
    		
    		//close connection
    		curl_close($ch);
    		
    		// change permissions on the cookie jar so we can read it.
    		chmod($ckfile,0777);
    		
    		// parse the cookie jar and set user cookies
    		$file_handle = fopen($ckfile, "r");
    		$file_data = fread($file_handle,  filesize($ckfile));
    		$lines = explode(PHP_EOL, $file_data);
    		fclose($file_handle);
    		
    		// create the cookie arrays
    		$cookiesession = explode('\t',str_replace("\t", "\\t\t", $lines[4]));
    		$cookiesession = array_map('trim', $cookiesession);
    		$cookieid = explode('\t',str_replace("\t", "\\t\t", $lines[5]));
    		$cookieid = array_map('trim', $cookieid);
    		
    		// set moodle session and id cookies
    		// setcookie(name,value,expire,path,domain,secure)
    		$MOODLEID1_ = setcookie('MOODLEID1_',$cookieid[6],0,'/',$cookieid[0]);
    		$MoodleSession = setcookie('MoodleSession',$cookiesession[6],0,'/',$cookiesession[0]);
    		
    		return true;
    	
    	}
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	/*
    	*
    	* Function to check if there is a moodle user 
    	*
    	*/
    	function getMoodleUser($username,$mdbhost,$mdbuser,$mdbpass,$mdbname){
    	  
    		mysql_connect($mdbhost,$mdbuser,$mdbpass);
    		@mysql_select_db($mdbname) or die('Unable to connect to moodle database! '.mysql_error());
    		$query = "select * from user where username = '".$username."';";
    		$result = mysql_query($query);
    	  	$num = mysql_numrows($result);
    		mysql_close();
    
    		if($num == 0){
    
    			return 0;
    			
    		}else{
    
    			$moodleuserid = mysql_result($result,0,'id');
    			return $moodleuserid;
    			
    		}
    
    	}
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	/*
    	*
    	* Function to check if moodle user has a session
    	* by comparing userid and sid in the sessions table to see if they match  
    	*
    	*/
    	function checkMoodleSession($sid,$uid,$mdbhost,$mdbuser,$mdbpass,$mdbname){
    	  
    		mysql_connect($mdbhost,$mdbuser,$mdbpass);
    		@mysql_select_db($mdbname) or die('Unable to connect to moodle database! '.mysql_error());
    		$query = "select * from sessions where sid = '".$sid."' and userid = '".$uid."';";
    		$result = mysql_query($query);
    	  	$num = mysql_numrows($result);
    		mysql_close();
    
    		if($num = 0){
    			
    			return false;
    			
    		}else{
    			
    			return true;
    			
    		}
    
    	}
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	/*
    	*
    	* Function to create moodle user
    	*
    	*/
    	function createMoodleUser($username,$password,$musertoken,$muserdomain){
    		global $modx;
    	  	$functionname = 'core_user_create_users';
    		
    		// create params
    		$moduser = $modx->getObject('modUser', array('username'=>$username));	
    		$profile = $moduser->getOne('Profile');
    		$email = $profile->get('email');
    		$firstname = $profile->get('fullname');
    		$city = $profile->get('city');
    		$country = $profile->get('country');
    		$comment = $profile->get('comment');
    		
    		
    		$user = new stdClass();
    		$user->username = $username;
    		$user->password = $password;
    		$user->firstname = $firstname;
    		$user->lastname = $firstname;
    		$user->email = $email;
    		$user->auth = 'manual';
    		$user->idnumber = 'testidnumber1';
    		$user->lang = 'en';
    		$user->theme = 'standard';
    		$user->timezone = '-12.5';
    		$user->mailformat = 0;
    		$user->description = $comment;
    		$user->city = $city;
    		$user->country = $country;
    		
    		$params = array($user);
    
    		// SOAP CALL
    		$serverurl = $muserdomain . '/webservice/soap/server.php'. '?wsdl=1&wstoken=' . $musertoken;
    	  
    		// Do the main soap call
    		$client = new SoapClient($serverurl);
    		
    		try {
    			$resp = $client->__soapCall($functionname, array($params));
    		} catch (Exception $e) {
    		  	//echo 'parms =  <pre>'.print_r($params).'</pre>';
    			//echo 'exception caught <pre>'.$e.'</pre>';
    			$modx->log(modX::LOG_LEVEL_ERROR, 'There was an error creating a new user in moodle, user = '.$username.' exception = '.$e);
    			return false;
    		}
    		if (isset($resp)) {
    		  	//echo 'response got'.$resp;
    			$modx->log(modX::LOG_LEVEL_ERROR, 'User '.$username.' created successfully in moodle');
    			return true;
    		}
    	  
    	}
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    	
    // find out if there is a moodle user to operate on
    $moodleuserid = getMoodleUser($username,$mdbhost,$mdbuser,$mdbpass,$mdbname);
    
    if ($moodleuserid != 0){
      
      	// moodle user is true, try to get a session
    	$sid = getMoodleCookies($url,$fields_string,$ckfile);
      	$uid = $moodleuserid;
    	
    	// check to see if they really got a session
    	if (!checkMoodleSession($sid,$uid,$mdbhost,$mdbuser,$mdbpass,$mdbname)){
    		
    		// log an error if they didn't
    		$modx->log(modX::LOG_LEVEL_ERROR, 'A user authenticated with modx, was found in moodle, but did not get a moodle session. Thier passwords are probably out of sync');
    		
    	}else{
    		
    		// log some info if they did! 
    		$modx->log(modX::LOG_LEVEL_ERROR, 'Modx user successfully authenticated with moodle!');
    		
    	}
    
    }else{
    	
    	// create a moodle user! 
    	$modx->log(modX::LOG_LEVEL_ERROR, 'Modx user '.$username.' successfully authenticated but was NOT found in moodle - creating moodle user!');
    	$moodlecreate = createMoodleUser($username,$password,$musertoken,$muserdomain);
    	// try to get the session
    	getMoodleCookies($url,$fields_string,$ckfile);
    	
    	if($moodlecreate == 'false'){
    		
    		$modx->log(modX::LOG_LEVEL_ERROR, 'Modx user '.$username.' was not created in moodle.');
    		
    	}
    
    }
    
    
    
    
    
    
    
    
    
    
    // delete temp files and session variables
    unlink($ckfile);
    unset($_SESSION['pmoodle']);
    unset($_SESSION['umoodle']);
    
    
    // return true no matter what so the user can still log into modx!
    return true;
    




    any thoughts on this would be greatly appreciated!
      *** Not just websites, we also create signage, banners, print, trade show displays and more! ***

      Sean Kimball CLP, CLS.
      Technical Director / Sr. Developer | BigBlock Studios
      ._______________________________________________.
      Bigblock Studios http://www.bigblockstudios.ca Web site design & development.
      27-1300 King Street East. Box 167 Oshawa, Ontario L1H8J4 Canada.
      phone/fax: 905-426-5525
      • 18373 ☆ A M B ☆
      • 3,141 Posts
      Mark Hamstra Reply #2, 14 years ago
      It looks like your SOAP call to Moodle is returning some undefined error:
      [2012-09-22 23:19:08] (ERROR @ /index.php) There was an error creating a new user in moodle, user = user001 exception = SoapFault exception: [Receiver] Unknown error | ERRORCODE: dmlwriteexception in /var/www/vhosts/doman.com/subdomains/sso/httpdocs/core/cache/includes/elements/modplugin/15.include.cache.php:234
      According to http://docs.moodle.org/23/en/error/moodle/dmlwriteexception you should enable debugging in Moodle and check out their logs or whatever for more information, but it has to do with writing to the database.

      This question might be more suited in the Moodle forums, though obviously they'll tell you to come back here with any questions on the actual plugin tongue
        Mark Hamstra • Developer spending his days working on Premium Extras and a MODX Site Dashboard with the ability to remotely upgrade MODX and extras to make the MODX world a little better.

        Tweet me @mark_hamstra, check my infrequent blog at markhamstra.com, my slightly more frequent ramblings at MODX.today or see code at Github.
        • 26503
        • 620 Posts
        Sean Kimball Reply #3, 14 years ago
        Thanks Mark, I do have it cross posted to the moodle forums, but they are pretty weak on info - probably has to do with the subscription method. [you try to subscribe to a thread & you get subscribed to the whole topic - too much spam!]

          *** Not just websites, we also create signage, banners, print, trade show displays and more! ***

          Sean Kimball CLP, CLS.
          Technical Director / Sr. Developer | BigBlock Studios
          ._______________________________________________.
          Bigblock Studios http://www.bigblockstudios.ca Web site design & development.
          27-1300 King Street East. Box 167 Oshawa, Ontario L1H8J4 Canada.
          phone/fax: 905-426-5525
          • 26503
          • 620 Posts
          Sean Kimball Reply #4, 14 years ago
          I did get this solved BTW - only by comparing data being sent to the database structure. Turns out one of the fields was too long. .... moodle logs were useless.
            *** Not just websites, we also create signage, banners, print, trade show displays and more! ***

            Sean Kimball CLP, CLS.
            Technical Director / Sr. Developer | BigBlock Studios
            ._______________________________________________.
            Bigblock Studios http://www.bigblockstudios.ca Web site design & development.
            27-1300 King Street East. Box 167 Oshawa, Ontario L1H8J4 Canada.
            phone/fax: 905-426-5525
            • 8425
            • 159 Posts
            Hi Sean,
            Would you mind sharing your fix?
            Greatly appreciated
            Thanks
              • 26503
              • 620 Posts
              Sean Kimball Reply #6, 12 years ago
              Quote from: eclipseTalk at Sep 23, 2014, 12:00 PM
              Hi Sean,
              Would you mind sharing your fix?
              Greatly appreciated
              Thanks


              I forget what the exact fix was, but if I was sending too much data for a field, I either lengthened the field or truncated the data being sent. Basically it was mysql failing the query, nothing to do with the plugin.
                *** Not just websites, we also create signage, banners, print, trade show displays and more! ***

                Sean Kimball CLP, CLS.
                Technical Director / Sr. Developer | BigBlock Studios
                ._______________________________________________.
                Bigblock Studios http://www.bigblockstudios.ca Web site design & development.
                27-1300 King Street East. Box 167 Oshawa, Ontario L1H8J4 Canada.
                phone/fax: 905-426-5525
                • 8425
                • 159 Posts
                Great thanks for the prompt reply
                  • 5430
                  • 247 Posts
                  Ok, so this is a super old post, but I've just been tasked with finding an SSO solution between MODX and Moodle, and would love to give this a shot. Are you running this on a fairly typical server environment? Any odd/unusual PHP config needed for this? I assume you're running the plugin on the OnWebLogin event?

                  Sean, I can't thank you enough for sharing this, it's likely to save me a ton of time. I may PM you if I run into trouble getting things up and running, would that be ok with you?
                    • 26503
                    • 620 Posts
                    Quote from: claytonk at Jul 03, 2017, 11:52 AM
                    Ok, so this is a super old post, but I've just been tasked with finding an SSO solution between MODX and Moodle, and would love to give this a shot. Are you running this on a fairly typical server environment? Any odd/unusual PHP config needed for this? I assume you're running the plugin on the OnWebLogin event?

                    Sean, I can't thank you enough for sharing this, it's likely to save me a ton of time. I may PM you if I run into trouble getting things up and running, would that be ok with you?

                    It's been 4 years since I looked at it - but it has been running ever since. .... the only issues which you will have to address would be if a user changes their credentials (password) in either system(this happens frequently). The plugin only checks if a user exists, if not creates it - it won't check passwords & update after the fact. (too risky/security) Your very-very best option would be to create an LDAP directory for your users and maintain all the user data there rather than either system. I'm 99% sure Moodle has an existing LDAP plugin & writing one for Modx should be fairly straight forward.
                      *** Not just websites, we also create signage, banners, print, trade show displays and more! ***

                      Sean Kimball CLP, CLS.
                      Technical Director / Sr. Developer | BigBlock Studios
                      ._______________________________________________.
                      Bigblock Studios http://www.bigblockstudios.ca Web site design & development.
                      27-1300 King Street East. Box 167 Oshawa, Ontario L1H8J4 Canada.
                      phone/fax: 905-426-5525
                      • 5430
                      • 247 Posts
                      Thanks. I know Moodle has an LDAP plugin, and I've seen LDAP extras for MODX but I'm pretty sure it's set up to validate to an external LDAP server and I don't want to migrate all my user data since passwords would have to be reset. I'll give it a look though, I agree an LDAP setup for data syncing would be best. I know Moodle has a database option for validation as well, but that sounds pretty insecure.

                      Thanks again for the input. We'll see how it goes.