<?php


namespace remotelearner\aadsample\AAD;

use remotelearner\aadsample\AADSAMPLEException;

/**
 * Azure AD specific IDToken implementation.
 */
class IDToken extends \remotelearner\aadsample\OIDC\IDToken {
    /**
     * Get a sensible username for the user represented by the idtoken.
     *
     * @return string A username for the user.
     */
    public function get_username() {
        $upn = $this->claim('upn');
        return (!empty($upn)) ? $upn : parent::get_username();
    }

    /**
     * Get a unique identifier for the user represented by the idtoken.
     *
     * @return string A unique identifier.
     */
    public function get_uniqid() {
        $oid = $this->claim('oid');
        return (!empty($oid)) ? $oid : parent::get_uniqid();
    }

    /**
     * Get current AAD signing keys.
     *
     * @param string $tenantid The tenant ID.
     * @param \remotelearner\aadsample\HttpClientInterface $httpclient HTTP Client instance.
     * @return array Array of keys.
     */
    public static function get_keys(\remotelearner\aadsample\HttpClientInterface $httpclient, $tenantid = null) {
        if (!empty($tenantid)) {
            $url = 'https://login.windows.net/'.$tenantid.'/.well-known/openid-configuration';
            $oidcconfig = $httpclient->get($url);
            $oidcconfig = @json_decode($oidcconfig, true);
            if (empty($oidcconfig) || !is_array($oidcconfig) || !isset($oidcconfig['jwks_uri'])) {
                throw new AADSAMPLEException('Could not get openid connect config (1).');
            }
            $jwks_uri = $oidcconfig['jwks_uri'];
        } else {
            $jwks_uri = 'https://login.windows.net/common/discovery/keys';
        }

        $keydata = $httpclient->get($oidcconfig['jwks_uri']);
        $keydata = @json_decode($keydata, true);
        if (empty($keydata) || !is_array($keydata) || !isset($keydata['keys'])) {
            throw new AADSAMPLEException('Could not get openid connect config (2).');
        }

        $keys = [];
        foreach ($keydata['keys'] as $i => $keyinfo) {
            if (isset($keyinfo['x5c']) && is_array($keyinfo['x5c'])) {
                foreach ($keyinfo['x5c'] as $encodedkey) {
                    $keys[] = static::transform_key($encodedkey);
                }
            }
        }
        return $keys;
    }

    /**
     * Transform encoded key into OpenSSL-compatible form.
     *
     * @param string $key Encoded key.
     * @return string OpenSSL-compatible key.
     */
    public static function transform_key($key) {
        $output = "-----BEGIN CERTIFICATE-----\n";
        $output .= wordwrap($key, 64, "\n", true);
        $output .= "\n-----END CERTIFICATE-----";
        return $output;
    }
}
