1*d10b5556SXylle<?php 2*d10b5556SXylle 3*d10b5556SXylle/** 4*d10b5556SXylle * Licensed to Jasig under one or more contributor license 5*d10b5556SXylle * agreements. See the NOTICE file distributed with this work for 6*d10b5556SXylle * additional information regarding copyright ownership. 7*d10b5556SXylle * 8*d10b5556SXylle * Jasig licenses this file to you under the Apache License, 9*d10b5556SXylle * Version 2.0 (the "License"); you may not use this file except in 10*d10b5556SXylle * compliance with the License. You may obtain a copy of the License at: 11*d10b5556SXylle * 12*d10b5556SXylle * http://www.apache.org/licenses/LICENSE-2.0 13*d10b5556SXylle * 14*d10b5556SXylle * Unless required by applicable law or agreed to in writing, software 15*d10b5556SXylle * distributed under the License is distributed on an "AS IS" BASIS, 16*d10b5556SXylle * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 17*d10b5556SXylle * See the License for the specific language governing permissions and 18*d10b5556SXylle * limitations under the License. 19*d10b5556SXylle * 20*d10b5556SXylle * PHP Version 7 21*d10b5556SXylle * 22*d10b5556SXylle * @file CAS/ProxiedService/Imap.php 23*d10b5556SXylle * @category Authentication 24*d10b5556SXylle * @package PhpCAS 25*d10b5556SXylle * @author Adam Franco <afranco@middlebury.edu> 26*d10b5556SXylle * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 27*d10b5556SXylle * @link https://wiki.jasig.org/display/CASC/phpCAS 28*d10b5556SXylle */ 29*d10b5556SXylle 30*d10b5556SXylle/** 31*d10b5556SXylle * Provides access to a proxy-authenticated IMAP stream 32*d10b5556SXylle * 33*d10b5556SXylle * @class CAS_ProxiedService_Imap 34*d10b5556SXylle * @category Authentication 35*d10b5556SXylle * @package PhpCAS 36*d10b5556SXylle * @author Adam Franco <afranco@middlebury.edu> 37*d10b5556SXylle * @license http://www.apache.org/licenses/LICENSE-2.0 Apache License 2.0 38*d10b5556SXylle * @link https://wiki.jasig.org/display/CASC/phpCAS 39*d10b5556SXylle */ 40*d10b5556SXylleclass CAS_ProxiedService_Imap 41*d10b5556SXylleextends CAS_ProxiedService_Abstract 42*d10b5556SXylle{ 43*d10b5556SXylle 44*d10b5556SXylle /** 45*d10b5556SXylle * The username to send via imap_open. 46*d10b5556SXylle * 47*d10b5556SXylle * @var string $_username; 48*d10b5556SXylle */ 49*d10b5556SXylle private $_username; 50*d10b5556SXylle 51*d10b5556SXylle /** 52*d10b5556SXylle * Constructor. 53*d10b5556SXylle * 54*d10b5556SXylle * @param string $username Username 55*d10b5556SXylle * 56*d10b5556SXylle * @return void 57*d10b5556SXylle */ 58*d10b5556SXylle public function __construct ($username) 59*d10b5556SXylle { 60*d10b5556SXylle if (!is_string($username) || !strlen($username)) { 61*d10b5556SXylle throw new CAS_InvalidArgumentException('Invalid username.'); 62*d10b5556SXylle } 63*d10b5556SXylle 64*d10b5556SXylle $this->_username = $username; 65*d10b5556SXylle } 66*d10b5556SXylle 67*d10b5556SXylle /** 68*d10b5556SXylle * The target service url. 69*d10b5556SXylle * @var string $_url; 70*d10b5556SXylle */ 71*d10b5556SXylle private $_url; 72*d10b5556SXylle 73*d10b5556SXylle /** 74*d10b5556SXylle * Answer a service identifier (URL) for whom we should fetch a proxy ticket. 75*d10b5556SXylle * 76*d10b5556SXylle * @return string 77*d10b5556SXylle * @throws Exception If no service url is available. 78*d10b5556SXylle */ 79*d10b5556SXylle public function getServiceUrl () 80*d10b5556SXylle { 81*d10b5556SXylle if (empty($this->_url)) { 82*d10b5556SXylle throw new CAS_ProxiedService_Exception( 83*d10b5556SXylle 'No URL set via '.get_class($this).'->getServiceUrl($url).' 84*d10b5556SXylle ); 85*d10b5556SXylle } 86*d10b5556SXylle 87*d10b5556SXylle return $this->_url; 88*d10b5556SXylle } 89*d10b5556SXylle 90*d10b5556SXylle /********************************************************* 91*d10b5556SXylle * Configure the Stream 92*d10b5556SXylle *********************************************************/ 93*d10b5556SXylle 94*d10b5556SXylle /** 95*d10b5556SXylle * Set the URL of the service to pass to CAS for proxy-ticket retrieval. 96*d10b5556SXylle * 97*d10b5556SXylle * @param string $url Url to set 98*d10b5556SXylle * 99*d10b5556SXylle * @return void 100*d10b5556SXylle * @throws CAS_OutOfSequenceException If called after the stream has been opened. 101*d10b5556SXylle */ 102*d10b5556SXylle public function setServiceUrl ($url) 103*d10b5556SXylle { 104*d10b5556SXylle if ($this->hasBeenOpened()) { 105*d10b5556SXylle throw new CAS_OutOfSequenceException( 106*d10b5556SXylle 'Cannot set the URL, stream already opened.' 107*d10b5556SXylle ); 108*d10b5556SXylle } 109*d10b5556SXylle if (!is_string($url) || !strlen($url)) { 110*d10b5556SXylle throw new CAS_InvalidArgumentException('Invalid url.'); 111*d10b5556SXylle } 112*d10b5556SXylle 113*d10b5556SXylle $this->_url = $url; 114*d10b5556SXylle } 115*d10b5556SXylle 116*d10b5556SXylle /** 117*d10b5556SXylle * The mailbox to open. See the $mailbox parameter of imap_open(). 118*d10b5556SXylle * 119*d10b5556SXylle * @var string $_mailbox 120*d10b5556SXylle */ 121*d10b5556SXylle private $_mailbox; 122*d10b5556SXylle 123*d10b5556SXylle /** 124*d10b5556SXylle * Set the mailbox to open. See the $mailbox parameter of imap_open(). 125*d10b5556SXylle * 126*d10b5556SXylle * @param string $mailbox Mailbox to set 127*d10b5556SXylle * 128*d10b5556SXylle * @return void 129*d10b5556SXylle * @throws CAS_OutOfSequenceException If called after the stream has been opened. 130*d10b5556SXylle */ 131*d10b5556SXylle public function setMailbox ($mailbox) 132*d10b5556SXylle { 133*d10b5556SXylle if ($this->hasBeenOpened()) { 134*d10b5556SXylle throw new CAS_OutOfSequenceException( 135*d10b5556SXylle 'Cannot set the mailbox, stream already opened.' 136*d10b5556SXylle ); 137*d10b5556SXylle } 138*d10b5556SXylle if (!is_string($mailbox) || !strlen($mailbox)) { 139*d10b5556SXylle throw new CAS_InvalidArgumentException('Invalid mailbox.'); 140*d10b5556SXylle } 141*d10b5556SXylle 142*d10b5556SXylle $this->_mailbox = $mailbox; 143*d10b5556SXylle } 144*d10b5556SXylle 145*d10b5556SXylle /** 146*d10b5556SXylle * A bit mask of options to pass to imap_open() as the $options parameter. 147*d10b5556SXylle * 148*d10b5556SXylle * @var int $_options 149*d10b5556SXylle */ 150*d10b5556SXylle private $_options = null; 151*d10b5556SXylle 152*d10b5556SXylle /** 153*d10b5556SXylle * Set the options for opening the stream. See the $options parameter of 154*d10b5556SXylle * imap_open(). 155*d10b5556SXylle * 156*d10b5556SXylle * @param int $options Options for the stream 157*d10b5556SXylle * 158*d10b5556SXylle * @return void 159*d10b5556SXylle * @throws CAS_OutOfSequenceException If called after the stream has been opened. 160*d10b5556SXylle */ 161*d10b5556SXylle public function setOptions ($options) 162*d10b5556SXylle { 163*d10b5556SXylle if ($this->hasBeenOpened()) { 164*d10b5556SXylle throw new CAS_OutOfSequenceException( 165*d10b5556SXylle 'Cannot set options, stream already opened.' 166*d10b5556SXylle ); 167*d10b5556SXylle } 168*d10b5556SXylle if (!is_int($options)) { 169*d10b5556SXylle throw new CAS_InvalidArgumentException('Invalid options.'); 170*d10b5556SXylle } 171*d10b5556SXylle 172*d10b5556SXylle $this->_options = $options; 173*d10b5556SXylle } 174*d10b5556SXylle 175*d10b5556SXylle /********************************************************* 176*d10b5556SXylle * 2. Open the stream 177*d10b5556SXylle *********************************************************/ 178*d10b5556SXylle 179*d10b5556SXylle /** 180*d10b5556SXylle * Open the IMAP stream (similar to imap_open()). 181*d10b5556SXylle * 182*d10b5556SXylle * @return resource Returns an IMAP stream on success 183*d10b5556SXylle * @throws CAS_OutOfSequenceException If called multiple times. 184*d10b5556SXylle * @throws CAS_ProxyTicketException If there is a proxy-ticket failure. 185*d10b5556SXylle * The code of the Exception will be one of: 186*d10b5556SXylle * PHPCAS_SERVICE_PT_NO_SERVER_RESPONSE 187*d10b5556SXylle * PHPCAS_SERVICE_PT_BAD_SERVER_RESPONSE 188*d10b5556SXylle * PHPCAS_SERVICE_PT_FAILURE 189*d10b5556SXylle * @throws CAS_ProxiedService_Exception If there is a failure sending the 190*d10b5556SXylle * request to the target service. 191*d10b5556SXylle */ 192*d10b5556SXylle public function open () 193*d10b5556SXylle { 194*d10b5556SXylle if ($this->hasBeenOpened()) { 195*d10b5556SXylle throw new CAS_OutOfSequenceException('Stream already opened.'); 196*d10b5556SXylle } 197*d10b5556SXylle if (empty($this->_mailbox)) { 198*d10b5556SXylle throw new CAS_ProxiedService_Exception( 199*d10b5556SXylle 'You must specify a mailbox via '.get_class($this) 200*d10b5556SXylle .'->setMailbox($mailbox)' 201*d10b5556SXylle ); 202*d10b5556SXylle } 203*d10b5556SXylle 204*d10b5556SXylle phpCAS::traceBegin(); 205*d10b5556SXylle 206*d10b5556SXylle // Get our proxy ticket and append it to our URL. 207*d10b5556SXylle $this->initializeProxyTicket(); 208*d10b5556SXylle phpCAS::trace('opening IMAP mailbox `'.$this->_mailbox.'\'...'); 209*d10b5556SXylle $this->_stream = @imap_open( 210*d10b5556SXylle $this->_mailbox, $this->_username, $this->getProxyTicket(), 211*d10b5556SXylle $this->_options 212*d10b5556SXylle ); 213*d10b5556SXylle if ($this->_stream) { 214*d10b5556SXylle phpCAS::trace('ok'); 215*d10b5556SXylle } else { 216*d10b5556SXylle phpCAS::trace('could not open mailbox'); 217*d10b5556SXylle // @todo add localization integration. 218*d10b5556SXylle $message = 'IMAP Error: '.$this->_url.' '. var_export(imap_errors(), true); 219*d10b5556SXylle phpCAS::trace($message); 220*d10b5556SXylle throw new CAS_ProxiedService_Exception($message); 221*d10b5556SXylle } 222*d10b5556SXylle 223*d10b5556SXylle phpCAS::traceEnd(); 224*d10b5556SXylle return $this->_stream; 225*d10b5556SXylle } 226*d10b5556SXylle 227*d10b5556SXylle /** 228*d10b5556SXylle * Answer true if our request has been sent yet. 229*d10b5556SXylle * 230*d10b5556SXylle * @return bool 231*d10b5556SXylle */ 232*d10b5556SXylle protected function hasBeenOpened () 233*d10b5556SXylle { 234*d10b5556SXylle return !empty($this->_stream); 235*d10b5556SXylle } 236*d10b5556SXylle 237*d10b5556SXylle /********************************************************* 238*d10b5556SXylle * 3. Access the result 239*d10b5556SXylle *********************************************************/ 240*d10b5556SXylle /** 241*d10b5556SXylle * The IMAP stream 242*d10b5556SXylle * 243*d10b5556SXylle * @var resource $_stream 244*d10b5556SXylle */ 245*d10b5556SXylle private $_stream; 246*d10b5556SXylle 247*d10b5556SXylle /** 248*d10b5556SXylle * Answer the IMAP stream 249*d10b5556SXylle * 250*d10b5556SXylle * @return resource 251*d10b5556SXylle * @throws CAS_OutOfSequenceException if stream is not opened yet 252*d10b5556SXylle */ 253*d10b5556SXylle public function getStream () 254*d10b5556SXylle { 255*d10b5556SXylle if (!$this->hasBeenOpened()) { 256*d10b5556SXylle throw new CAS_OutOfSequenceException( 257*d10b5556SXylle 'Cannot access stream, not opened yet.' 258*d10b5556SXylle ); 259*d10b5556SXylle } 260*d10b5556SXylle return $this->_stream; 261*d10b5556SXylle } 262*d10b5556SXylle 263*d10b5556SXylle /** 264*d10b5556SXylle * CAS_Client::serviceMail() needs to return the proxy ticket for some reason, 265*d10b5556SXylle * so this method provides access to it. 266*d10b5556SXylle * 267*d10b5556SXylle * @return string 268*d10b5556SXylle * @throws CAS_OutOfSequenceException If called before the stream has been 269*d10b5556SXylle * opened. 270*d10b5556SXylle */ 271*d10b5556SXylle public function getImapProxyTicket () 272*d10b5556SXylle { 273*d10b5556SXylle if (!$this->hasBeenOpened()) { 274*d10b5556SXylle throw new CAS_OutOfSequenceException( 275*d10b5556SXylle 'Cannot access errors, stream not opened yet.' 276*d10b5556SXylle ); 277*d10b5556SXylle } 278*d10b5556SXylle return $this->getProxyTicket(); 279*d10b5556SXylle } 280*d10b5556SXylle} 281*d10b5556SXylle?> 282