summaryrefslogtreecommitdiff
path: root/Postman/Postman-Mail/PostmanGmailApiModuleTransport.php
blob: 98fc1f1bcb7274dcd1f3a4973b2fffeea4a4921e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
<?php
require_once 'PostmanModuleTransport.php';

/**
 * This class integrates Postman with the Gmail API
 * http://ctrlq.org/code/19860-gmail-api-send-emails
 *
 * @author jasonhendriks
 *        
 */
class PostmanGmailApiModuleTransport extends PostmanAbstractZendModuleTransport implements PostmanZendModuleTransport {
	const SLUG = 'gmail_api';
	const PORT = 443;
	const HOST = 'www.googleapis.com';
	const ENCRYPTION_TYPE = 'ssl';
	public function __construct($rootPluginFilenameAndPath) {
		parent::__construct ( $rootPluginFilenameAndPath );
		
		// add a hook on the plugins_loaded event
		add_action ( 'admin_init', array (
				$this,
				'on_admin_init' 
		) );
	}
	public function getProtocol() {
		return 'https';
	}
	
	/**
	 * (non-PHPdoc)
	 *
	 * @see PostmanAbstractModuleTransport::isServiceProviderGoogle()
	 */
	public function isServiceProviderGoogle($hostname) {
		return true;
	}
	
	/**
	 * (non-PHPdoc)
	 *
	 * @see PostmanModuleTransport::createMailEngine()
	 */
	public function createMailEngine() {
		require_once 'PostmanZendMailEngine.php';
		return new PostmanZendMailEngine ( $this );
	}
	
	/**
	 * (non-PHPdoc)
	 *
	 * @see PostmanZendModuleTransport::createZendMailTransport()
	 */
	public function createZendMailTransport($fakeHostname, $fakeConfig) {
		if (PostmanOptions::AUTHENTICATION_TYPE_OAUTH2 == $this->getAuthenticationType ()) {
			$config = PostmanOAuth2ConfigurationFactory::createConfig ( $this );
		} else {
			$config = PostmanBasicAuthConfigurationFactory::createConfig ( $this );
		}
		
		// Google's autoloader will try and load this so we list it first
		require_once 'PostmanGmailApiModuleZendMailTransport.php';
		
		// Gmail Client includes
		require_once 'google-api-client/vendor/autoload.php';
		
		// build the Gmail Client
		$authToken = PostmanOAuthToken::getInstance ();
		$client = new Google_Client ();
		$client->setClientId ( $this->options->getClientId () );
		$client->setClientSecret ( $this->options->getClientSecret () );
		$client->setRedirectUri ( '' );
		// rebuild the google access token
		$token = new stdClass ();
		$token->access_token = $authToken->getAccessToken ();
		$token->refresh_token = $authToken->getRefreshToken ();
		$token->token_type = 'Bearer';
		$token->expires_in = 3600;
		$token->id_token = null;
		$token->created = 0;
		$client->setAccessToken ( json_encode ( $token ) );
		// We only need permissions to compose and send emails
		$client->addScope ( "https://www.googleapis.com/auth/gmail.compose" );
		$service = new Google_Service_Gmail ( $client );
		$config [PostmanGmailApiModuleZendMailTransport::SERVICE_OPTION] = $service;
		
		return new PostmanGmailApiModuleZendMailTransport ( self::HOST, $config );
	}
	
	/**
	 * Determines whether Mail Engine locking is needed
	 *
	 * @see PostmanModuleTransport::requiresLocking()
	 */
	public function isLockingRequired() {
		return PostmanOptions::AUTHENTICATION_TYPE_OAUTH2 == $this->getAuthenticationType ();
	}
	public function getSlug() {
		return self::SLUG;
	}
	public function getName() {
		return __ ( 'Gmail API', 'post-smtp' );
	}
	public function isEnvelopeFromValidationSupported() {
		return false;
	}
	public function getHostname() {
		return self::HOST;
	}
	public function getPort() {
		return self::PORT;
	}
	public function getAuthenticationType() {
		return $this->options->getAuthenticationType ();
	}
	public function getSecurityType() {
		return null;
	}
	public function getCredentialsId() {
		$this->options = $this->options;
		if ($this->options->isAuthTypeOAuth2 ()) {
			return $this->options->getClientId ();
		} else {
			return $this->options->getUsername ();
		}
	}
	public function getCredentialsSecret() {
		$this->options = $this->options;
		if ($this->options->isAuthTypeOAuth2 ()) {
			return $this->options->getClientSecret ();
		} else {
			return $this->options->getPassword ();
		}
	}
	public function isServiceProviderMicrosoft($hostname) {
		return false;
	}
	public function isServiceProviderYahoo($hostname) {
		return false;
	}
	public function isOAuthUsed($authType) {
		return true;
	}
	
	/**
	 * (non-PHPdoc)
	 *
	 * @see PostmanAbstractModuleTransport::getDeliveryDetails()
	 */
	public function getDeliveryDetails() {
		/* translators: where (1) is the secure icon and (2) is the transport name */
		return sprintf ( __ ( 'Postman will send mail via the <b>%1$s %2$s</b>.', 'post-smtp' ), '🔐', $this->getName () );
	}
	
	/**
	 * (non-PHPdoc)
	 *
	 * @see PostmanAbstractZendModuleTransport::validateTransportConfiguration()
	 */
	protected function validateTransportConfiguration() {
		$messages = parent::validateTransportConfiguration ();
		if (empty ( $messages )) {
			$this->setReadyForOAuthGrant ();
			if ($this->isPermissionNeeded ()) {
				/* translators: %1$s is the Client ID label, and %2$s is the Client Secret label */
				$message = sprintf ( __ ( 'You have configured OAuth 2.0 authentication, but have not received permission to use it.', 'post-smtp' ), $this->getScribe ()->getClientIdLabel (), $this->getScribe ()->getClientSecretLabel () );
				$message .= sprintf ( ' <a href="%s">%s</a>.', PostmanUtils::getGrantOAuthPermissionUrl (), $this->getScribe ()->getRequestPermissionLinkText () );
				array_push ( $messages, $message );
				$this->setNotConfiguredAndReady ();
			}
		}
		return $messages;
	}
	
	/**
	 * Given a hostname, what ports should we test?
	 *
	 * May return an array of several combinations.
	 */
	public function getSocketsForSetupWizardToProbe($hostname, $smtpServerGuess) {
		$hosts = array ();
		if ($smtpServerGuess == null || PostmanUtils::isGoogle ( $smtpServerGuess )) {
			array_push ( $hosts, parent::createSocketDefinition ( $this->getHostname (), $this->getPort () ) );
		}
		return $hosts;
	}
	
	/**
	 * Postman Gmail API supports delivering mail with these parameters:
	 *
	 * 70 gmail api on port 465 to www.googleapis.com
	 *
	 * @param mixed $hostData        	
	 */
	public function getConfigurationBid(PostmanWizardSocket $hostData, $userAuthOverride, $originalSmtpServer) {
		$recommendation = array ();
		$recommendation ['priority'] = 0;
		$recommendation ['transport'] = self::SLUG;
		$recommendation ['enc'] = PostmanOptions::SECURITY_TYPE_NONE;
		$recommendation ['auth'] = PostmanOptions::AUTHENTICATION_TYPE_OAUTH2;
		$recommendation ['hostname'] = null; // scribe looks this
		$recommendation ['label'] = $this->getName ();
		$recommendation ['display_auth'] = 'oauth2';
		if ($hostData->hostname == self::HOST && $hostData->port == self::PORT) {
			/* translators: where variables are (1) transport name (2) host and (3) port */
			$recommendation ['message'] = sprintf ( __ ( ('Postman recommends the %1$s to host %2$s on port %3$d.') ), $this->getName (), self::HOST, self::PORT );
			$recommendation ['priority'] = 27000;
		}
		
		return $recommendation;
	}
	
	/**
	 */
	public function createOverrideMenu(PostmanWizardSocket $socket, $winningRecommendation, $userSocketOverride, $userAuthOverride) {
		$overrideItem = parent::createOverrideMenu ( $socket, $winningRecommendation, $userSocketOverride, $userAuthOverride );
		// push the authentication options into the $overrideItem structure
		$overrideItem ['auth_items'] = array (
				array (
						'selected' => true,
						'name' => __ ( 'OAuth 2.0 (requires Client ID and Client Secret)', 'post-smtp' ),
						'value' => 'oauth2' 
				) 
		);
		return $overrideItem;
	}
	
	/**
	 * Functions to execute on the admin_init event
	 *
	 * "Runs at the beginning of every admin page before the page is rendered."
	 * ref: http://codex.wordpress.org/Plugin_API/Action_Reference#Actions_Run_During_an_Admin_Page_Request
	 */
	public function on_admin_init() {
		// only administrators should be able to trigger this
		if (PostmanUtils::isAdmin ()) {
			$this->registerStylesAndScripts ();
		}
	}
	
	/**
	 */
	public function registerStylesAndScripts() {
		// register the stylesheet and javascript external resources
		$pluginData = apply_filters ( 'postman_get_plugin_metadata', null );
		wp_register_script ( 'postman_gmail_script', plugins_url ( 'Postman/Postman-Mail/postman_gmail.js', $this->rootPluginFilenameAndPath ), array (
				PostmanViewController::JQUERY_SCRIPT,
				'jquery_validation',
				PostmanViewController::POSTMAN_SCRIPT 
		), $pluginData ['version'] );
	}
	
	/**
	 */
	public function enqueueScript() {
		wp_enqueue_script ( 'postman_gmail_script' );
	}
}