summaryrefslogblamecommitdiffstats
path: root/shib/api.php
blob: 2c80f3786e858a16a6b829c8d60442a31db59f64 (plain) (tree)





















                                                                                             





                                                             
                                                                                                                         


                                                 
                                                                                                                          
                               
                                                                    
                                                                                      
                          
                                                                                  





                                                                                          
                                                                                                                                   
                                  


                                               
                                                                                                                                               
                                                                                                                                     
                                                                                                                                        
                                                                                                                              
                                                                                             



                                                                  
         

                                                                     




                                                                               

                                                                                 




                                                                     
                                                  

                                                                                                  
















                                                                                                                                                   




                                                                                

                               

                                                         
                          


                                                             
                                          
                                                      
                                                                                                                                 






                                                                                                                   

                                                                        


                                                            
                                                                               




                                                                                                                         













                                                                                                                                                    





                                                            

                                                                              

                                                                                
                                                
                                             
                                                            

                                                         




                  




                                                                                          








                                                                           


                                                                                


                                                              



                                                  
<?php

chdir('..');

require_once 'config.php';

/*
Header('Content-Type: text/plain; charset=utf-8');
die( json_encode($_SERVER, JSON_PRETTY_PRINT) );

// */

// Autoload classes from ./inc which adhere to naming scheme <lowercasename>.inc.php
function slxAutoloader($class)
{
	$file = 'inc/' . preg_replace('/[^a-z0-9]/', '', mb_strtolower($class)) . '.inc.php';
	if (!file_exists($file))
		return;
	require_once $file;
}
spl_autoload_register('slxAutoloader');

$response = array();

if (empty($_SERVER['persistent-id'])) {
	// No persistent id given, should not happen!
	$response['status'] = 'error';
	$response['error'] = 'Shibboleth meta data missing!';
	file_put_contents('/tmp/shib-nopid-' . time() . '-' . $_SERVER['REMOTE_ADDR'] . '.txt', print_r($_SERVER, true));
} else {
	// Query database for user
	$shibId = md5($_SERVER['persistent-id']);
	$user = Database::queryFirst("SELECT user.userid, user.organizationid, user.firstname, user.lastname, user.email "
		. " FROM user "
		. " INNER JOIN organization USING (organizationid) "
		. " WHERE user.shibid = :shibid LIMIT 1", array('shibid' => $shibId));
	// Figure out role
	if (strpos(";{$_SERVER['entitlement']};", CONFIG_ENTITLEMENT) !== false) {
		$role = 'TUTOR';
	} else if (strpos(";{$_SERVER['affiliation']};", ';employee@') !== false
			|| strpos(";{$_SERVER['affiliation']};", ';staff@') !== false
			|| strpos(";{$_SERVER['affiliation']};", ';faculty@') !== false) {
		$role = 'TUTOR';
	} else {
		file_put_contents('/tmp/shib-student-' . time() . '-' . $_SERVER['REMOTE_ADDR'] . '.txt', print_r($_SERVER, true));
		$role = 'STUDENT';
		// NEW: Ignore students for now
		$response = array(
			'status' => 'error',
			'error' => "Sie wurden als Student eingestuft und können sich daher nicht an der " . CONFIG_SUITE . "-Suite anmelden."
				. "\nFalls Ihr Nutzerkonto kein Studentenkonto ist stellen Sie sicher, dass Ihr IdP für berechtigte"
				. "\nAccounts entweder das " . CONFIG_SUITE . "-Entitlement ausliefert, oder das Attribut 'affiliation'"
				. "\nausgeliefert wird, und es entweder 'employee@..', 'staff@..' oder 'faculty@..' enthält."
				. "\n\nMehr Informationen finden Sie unter " . CONFIG_HELPURL
		);
		Header('Content-Type: text/plain; charset=utf-8');
		die(json_encode($response, JSON_PRETTY_PRINT));
		// end IGNORE STUDENTS
	}
	if ($user === false) {
		// Not found, so we don't know which satellite to use
		if ($role === 'STUDENT') {
			$response['status'] = 'ok';
			if (isset($_SERVER['givenName'])) {
				$response['firstName'] = $_SERVER['givenName'];
			}
			if (isset($_SERVER[CONFIG_SURNAME])) {
				$response['lastName'] = $_SERVER[CONFIG_SURNAME];
			}
			if (isset($_SERVER['mail'])) {
				$response['mail'] = $_SERVER['mail'];
			}
			$response['userId'] = $shibId;
			// Try to figure out orgId
			if (!isset($response['organizationId']) && isset($_SERVER[CONFIG_EPPN])) {
				if (preg_match('/@(.+)$/', $_SERVER[CONFIG_EPPN], $out)) {
					$out = Database::queryFirst("SELECT organizationid FROM organization_suffix WHERE suffix = :suffix", array(
						'suffix' => $out[1]
					));
					if ($out !== false) {
						$response['organizationId'] = $out['organizationid'];
					}
				}
			}
			if (!isset($response['organizationId']) && isset($_SERVER['affiliation'])) {
				if (preg_match('/(^|;)[^@]+@([^;]+)/', $_SERVER['affiliation'], $out)) {
					$out = Database::queryFirst("SELECT organizationid FROM organization_suffix WHERE suffix = :suffix", array(
						'suffix' => $out[2]
					));
					if ($out !== false) {
						$response['organizationId'] = $out['organizationid'];
					}
				}
			}
			// This one we send to the running master server handler
			$rpc = $response;
			$rpc['role'] = $role;
			// This one we only send to the user
			// TODO
			/*
			$response['satellites'] = $sat1;
			$response['satellites2'] = $sat2;
			*/
		} else {
			$response['status'] = 'unregistered';
		}
		$response['id'] = $shibId;
		$response['url'] = CONFIG_MASTERWEBIF;
		file_put_contents('/tmp/shib-unreg-' . time() . '-' . $_SERVER['REMOTE_ADDR'] . '.txt', print_r($_SERVER, true));
	} else {
		// Found, see if we got personal information, either temporarily through metadata, or from database
		$firstName = $user['firstname'];
		$lastName = $user['lastname'];
		$mail = $user['email'];
		if (empty($firstName) && isset($_SERVER['givenName']))
			$firstName = trim($_SERVER['givenName']);
		if (empty($lastName) && isset($_SERVER[CONFIG_SURNAME]))
			$lastName = trim($_SERVER[CONFIG_SURNAME]);
		if (empty($mail) && isset($_SERVER['mail']))
			$mail = trim($_SERVER['mail']);
		//
		$login = (empty($user['userid']) ? $shibId : $user['userid'] );
		if (empty($firstName) || empty($lastName) || empty($login)) {
			// This means the user did not provide personal information on signup, nor does the IdP send them
			$response['status'] = 'anonymous';
		} else {
			// Seems ok!
			// Determine satellite(s)
			$res = Database::simpleQuery("SELECT satellitename, addresses, certsha256 FROM satellite"
				. " WHERE organizationid = :organizationid AND userid IS NULL", array('organizationid' => $user['organizationid']));
			$sat1 = array(); // Legacy
			$sat2 = array();
			while ($row = $res->fetch(PDO::FETCH_ASSOC)) {
				$addrs = json_decode($row['addresses'], true);
				if (!is_array($addrs) || empty($addrs))
					continue;
				$sat1[$row['satellitename']] = $addrs[0];
				$sat2[$row['satellitename']] = array(
					'addresses' => $addrs,
					'certHash' => $row['certsha256']
				);
			}
			//
			$response['status'] = 'ok';
			$response['firstName'] = $firstName;
			$response['lastName'] = $lastName;
			$response['mail'] = $mail;
			$response['userId'] = $user['userid'];
			$response['organizationId'] = $user['organizationid'];
			// This one we send to the running master server handler
			$rpc = $response;
			$rpc['userId'] = $login;
			$rpc['role'] = $role;
			// This one we only send to the user
			$response['satellites'] = $sat1;
			$response['satellites2'] = $sat2;
		}
	}
}

if (isset($rpc)) {
			$reply = RPC::submit($rpc);
			if (preg_match('/^TOKEN:(\w+) SESSIONID:(\w+)$/', $reply, $out)) {
				$response['token'] = $out[1];
				$response['sessionId'] = $out[2];
			} else {
				if (empty($rpc['mail'])) {
					$reply .= ' (No email given)';
				}
				if (empty($rpc['firstName'])) {
					$reply .= ' (No first name given)';
				}
				if (empty($rpc['lastName'])) {
					$reply .= ' (No last name given)';
				}
				if (empty($rpc['organizationId'])) {
					$reply .= ' (No organization id found)';
				}
				$response['error'] = $reply;
				$response['status'] = 'error';
			}
}

Header('Content-Type: text/plain; charset=utf-8');
echo json_encode($response, JSON_PRETTY_PRINT);