phpoutlook

Correct syntax to extract email address in 'autodiscover.php'


I need to extract the email address from "php://input" and render it within xml output - as part of the outlook 'autodiscover.xml' process. Working as expected, but I just need to pass the email address as the login name.

Here is the autodiscover.php I am working with, it works to pull the address, but I only get the username portion, not the entire UPN/address.

<?php
//get raw POST data so we can extract the email address
$raw = file_get_contents("php://input");
$matches = array();
preg_match('/<EMailAddress>([^@]+)@([^\.]+).*<\/EMailAddress>/', $raw, $matches);

In the xml rendering code, these are the fields I am trying to populate with the entire email address, example user123@example.tld

This code renders only the "user123" as LoginName

<LoginName><?php echo $matches[1]; ?></LoginName>

<Domain><?php echo $matches[2]; ?></Domain>

I have tried $matches[0]; and it adds EMailAddress inline like so:

<LoginName>
<EMailAddress>user123@example.tld</EMailAddress>
</LoginName>

Is there a simple way to just pass the entire address for the 'LoginName' stanza?

What I have output with the above code:

<LoginName>user123</LoginName>

What I am trying to pass:

<LoginName>user123@example.tld</LoginName>

Update: Revised code

<?php
$postData = file_get_contents('php://input'); //Autodiscover requests are HTTP posts with XML content
$xml = simplexml_load_string($postData);
$user = $xml->Request->EMailAddress; //copy the email address from the request into a variable

//set Content-Type
header("Content-Type: application/xml");
?>
<?php echo '<?xml version="1.0" encoding="utf-8" ?>'; ?>
<Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/responseschema/2006">
  <Response xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a">
   <Account>
      <AccountType>email</AccountType>
      <Action>settings</Action>
      <Protocol>
         <Type>POP3</Type>
         <Server>mail.example.tld</Server>
         <Port>995</Port>
         <LoginName><?php echo $user; ?></LoginName>
/...../
      </Protocol>
   </Account>
</Response>
</Autodiscover>

Throws an error: Stack trace: #0 {main} thrown in /var/www/example/autodiscover/autodiscover/autodiscover.php on line 3" while reading response header from upstream, client: 52.109.8.10, server: autodiscover.example.tld, request: "POST /autodiscover/autodiscover.php HTTP/2.0", upstream: "fastcgi://unix:/var/run/php/php8.2-fpm.sock:", host: "autodiscover.example.tld"


Solution

  • Parsing XML with regular expressions is hard to get right and always unreliable, but it's trivial with SimpleXML:

    $raw = '
    <WhateverTheRootElementIs>
        <LoginName>
            <EMailAddress>user123@example.tld</EMailAddress>
        </LoginName>
    </WhateverTheRootElementIs>
    ';
    
    $xml = simplexml_load_string($raw);
    echo $xml->LoginName->EMailAddress;
    

    Demo