From 58331ebdefe5fabe5360f0d07a5d0e6471244f92 Mon Sep 17 00:00:00 2001
From: John Ennew <johne@deeson.co.uk>
Date: Fri, 31 Aug 2012 13:10:16 +0100
Subject: [PATCH] Issue #1765196 by ceng: Allow site owner to specify the
 certificates directory

---
 includes/push_notifications.admin.inc |   29 +++++++++++++++++++++++++++++
 push_notifications.module             |   29 +++++++++++++++++++++++++++--
 2 files changed, 56 insertions(+), 2 deletions(-)

diff --git a/includes/push_notifications.admin.inc b/includes/push_notifications.admin.inc
index c481e81..34aa7a0 100644
--- a/includes/push_notifications.admin.inc
+++ b/includes/push_notifications.admin.inc
@@ -150,6 +150,14 @@ function push_notifications_admin_form($form_state) {
     '#default_value' => variable_get('push_notifications_apns_environment', 0),
   );
 
+  $form['configuration_apns']['push_notifications_apns_certificate_folder'] = array(
+    '#type' => 'textfield',
+    '#title' => t('APNS certificate folder path'),
+    '#description' => t('Provide the path to the folder that stores your APNS pem files on your server relative to the document root. e.g. sites/example.org/certificates/. Leave blank to use the certificates folder in the push_notifica  tions module.'),
+    '#default_value' => variable_get('push_notifications_apns_certificate_folder', ''),
+    '#size' => 150,
+  );
+
   $form['configuration_apns']['stream_context_limit'] = array(
     '#type' => 'select',
     '#title' => t('Stream Context Limit'),
@@ -267,6 +275,27 @@ function push_notifications_admin_form_submit($form, &$form_state) {
   // Set GCM API key.
   variable_set('push_notifications_gcm_api_key', $form_state['values']['push_notifications_gcm_api_key']);
 
+  // Set the APNS certificate location.
+  $apns_cert_folder = $form_state['values']['push_notifications_apns_certificate_folder'];
+  if (!empty($apns_cert_folder)) {
+
+    // Add a trailing slash if not present.
+    if ($apns_cert_folder[strlen($apns_cert_folder) - 1] != DIRECTORY_SEPARATOR) {
+      $apns_cert_folder .= DIRECTORY_SEPARATOR;
+    }
+
+    // Remove the leading slash if present.
+    if ($apns_cert_folder[0] == DIRECTORY_SEPARATOR) {
+      $apns_cert_folder = substr($apns_cert_folder, 1);
+    }
+
+    variable_set('push_notifications_apns_certificate_folder', $apns_cert_folder);
+    $apns_cert = _push_notifications_get_apns_certificate();
+    if (!file_exists($apns_cert)) {
+      drupal_set_message(t('Could not find an APNS certificate at @path', array('@path' => $apns_cert)), 'warning');
+    }
+  }
+
   // Set the APNS pem file passphrase.
   variable_set('push_notifications_apns_passphrase', $form_state['values']['passphrase']);
 
diff --git a/push_notifications.module b/push_notifications.module
index 8cb94c5..e24a092 100644
--- a/push_notifications.module
+++ b/push_notifications.module
@@ -331,7 +331,7 @@ function push_notifications_store_token($token = '', $type_id = '', $uid = '', $
 function push_notifications_open_apns() {
   // Determine the absolute path of the certificate.
   // @see http://stackoverflow.com/questions/809682
-  $apns_cert = dirname(__FILE__) . '/certificates/' . PUSH_NOTIFICATIONS_APNS_CERTIFICATE;
+  $apns_cert = _push_notifications_get_apns_certificate();
 
   // Create a stream context.
   $stream_context = stream_context_create();
@@ -918,7 +918,7 @@ function push_notifications_purge_token($token = '') {
 function push_notifications_apns_feedback_service() {
   // Create a Stream context and open an Internet socket connection.
   $stream_context = stream_context_create();
-  $apns_cert = dirname(__FILE__) . '/certificates/' . PUSH_NOTIFICATIONS_APNS_CERTIFICATE;
+  $apns_cert = _push_notifications_get_apns_certificate();
   stream_context_set_option($stream_context, 'ssl', 'local_cert', $apns_cert);
   $apns = stream_socket_client('ssl://' . PUSH_NOTIFICATIONS_APNS_FEEDBACK_HOST . ':' . PUSH_NOTIFICATIONS_APNS_FEEDBACK_PORT, $error, $error_string, 2, STREAM_CLIENT_CONNECT, $stream_context);
   if (!$apns) {
@@ -953,3 +953,28 @@ function push_notifications_apns_feedback_service() {
   watchdog('push_notifications', '!count were removed after pulling the Apple feedback service.', array('!count' => $counter));
 
 }
+
+/**
+ * Get the full path to the APNS certificate.
+ *
+ * @return string
+ *   The path to the certificate file on the server.
+ */
+function _push_notifications_get_apns_certificate() {
+  $path = variable_get('push_notifications_apns_certificate_folder', '');
+
+  if (empty($path)) {
+    $path = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'certificates' . DIRECTORY_SEPARATOR;
+  }
+  else {
+    $path = realpath('.') . DIRECTORY_SEPARATOR . $path;
+  }
+
+  $path .= PUSH_NOTIFICATIONS_APNS_CERTIFICATE;
+
+  if (!file_exists($path)) {
+    watchdog('push_notifications', 'Cannot find apns certificate file at @path', array('@path' => $path), WATCHDOG_WARNING, l(t('settings'), 'admin/config/services/push_notifications/configure'));
+  }
+
+  return $path;
+}
-- 
1.7.7

