Make it possible to run indieauth-openid as .phar
authorChristian Weiske <cweiske@cweiske.de>
Fri, 21 Apr 2017 20:33:00 +0000 (22:33 +0200)
committerChristian Weiske <cweiske@cweiske.de>
Fri, 21 Apr 2017 20:44:35 +0000 (22:44 +0200)
.gitignore
README.rst
build.xml [new file with mode: 0644]
config.php.dist [new file with mode: 0644]
src/phar-stub.php [new file with mode: 0644]
www/about.php
www/index.php

index 4a22837..a617350 100644 (file)
@@ -1,2 +1,5 @@
-data/tokens.sq3
-README.html
+/config.php
+/data/tokens.sq3
+/dist/
+/lib/
+/README.html
index bd7637c..ba0a4ec 100644 (file)
@@ -11,6 +11,7 @@ __ http://openid.net/
 Setup
 =====
 
+0. Install dependencies
 1. Setup your webserver: make ``www/`` the root (document) directory of the
    new virtual host
 2. Make ``data/`` world-writable (or at least writable by the web server)
@@ -20,6 +21,16 @@ Setup
      <link rel="authorization_endpoint" href="http://indieauth-openid.example.org/" />
 
 
+Configuration
+=============
+A sqlite file ``data/tokens.sq3`` is created by indieauth-openid.
+To configure that path, copy ``config.php.dist`` to ``config.php`` and
+adjust it.
+
+If you're using the ``.phar`` file, append ``.config.php`` to the full
+file name - e.g. ``indieauth-openid-0.1.0.phar.config.php``.
+
+
 ============
 Dependencies
 ============
@@ -32,6 +43,14 @@ Dependencies
   * OpenID
 
 
+Installation
+============
+Install the dependencies::
+
+    $ pear install net_url2-2.2.1
+    $ pear install openid-alpha
+
+
 =======
 License
 =======
diff --git a/build.xml b/build.xml
new file mode 100644 (file)
index 0000000..bd8d096
--- /dev/null
+++ b/build.xml
@@ -0,0 +1,67 @@
+<?xml version="1.0" encoding="utf-8"?>
+<project name="indieauth-openid" default="phar" basedir=".">
+  <!--
+    indieauth-openid phing build file.
+  -->
+  <property name="version"    value="0.1.0" />
+  <property name="stability"  value="beta" />
+  <property name="libdir"      value="${phing.dir}/lib"/>
+
+  <property name="pharfile"    value="${phing.project.name}-${version}.phar" />
+
+  <property name="pharpath"    value="${phing.dir}/dist/${pharfile}" />
+
+  <fileset id="fs.phar" dir="${phing.dir}">
+   <include name="lib/**"/>
+   <include name="www/**"/>
+
+   <include name="ChangeLog"/>
+   <include name="README.rst"/>
+
+   <exclude name="**/.git/"/>
+   <exclude name="**/.gitignore/"/>
+  </fileset>
+
+  <target name="phar" depends="preparedirs,collectdeps"
+          description="Create phar file for release"
+  >
+   <delete file="${pharpath}"/>
+   <pharpackage basedir="${phing.dir}"
+                destfile="${pharpath}"
+                stub="${phing.dir}/src/phar-stub.php"
+                alias="phorkie.phar"
+   >
+    <fileset refid="fs.phar"/>
+   </pharpackage>
+
+   <exec executable="bzip2" dir="${phing.dir}/dist">
+    <arg value="-kf"/>
+    <arg file="${pharpath}"/>
+   </exec>
+  </target>
+
+
+  <target name="collectdeps" description="Copy package dependencies to lib/">
+   <delete dir="${libdir}"/>
+   <mkdir dir="${libdir}"/>
+
+   <!-- requires phing >= 2.8.0 -->
+   <copy todir="${libdir}">
+    <pearPackageFileset package="pear.php.net/Cache_Lite"/><!-- OpenID -->
+    <pearPackageFileset package="pear.php.net/Crypt_DiffieHellman"/><!-- OpenID -->
+    <pearPackageFileset package="pear.php.net/HTTP_Request2"/><!-- OpenID -->
+    <pearPackageFileset package="pear.php.net/Net_URL2"/>
+    <pearPackageFileset package="pear.php.net/OpenID"/>
+    <pearPackageFileset package="pear.php.net/PEAR">
+     <include name="PEAR/Exception.php"/>
+     <include name="PEAR.php"/>
+    </pearPackageFileset>
+    <pearPackageFileset package="pear.php.net/Services_Yadis"/><!-- OpenID -->
+    <pearPackageFileset package="pear.php.net/Validate"/><!-- OpenID (Yadis) -->
+   </copy>
+  </target>
+
+  <target name="preparedirs">
+    <mkdir dir="dist" />
+  </target>
+</project>
diff --git a/config.php.dist b/config.php.dist
new file mode 100644 (file)
index 0000000..f8005a7
--- /dev/null
@@ -0,0 +1,5 @@
+<?php
+//copy this to config.php and adjust it to your liking
+// when using the .phar, append ".config.php" to the phar file name
+$dsn = 'sqlite:/tmp/file.sq3';
+?>
diff --git a/src/phar-stub.php b/src/phar-stub.php
new file mode 100644 (file)
index 0000000..19a31a4
--- /dev/null
@@ -0,0 +1,59 @@
+<?php
+/**
+ * Phar stub file for indieauth-openid. Handles startup of the .phar file.
+ */
+if (!in_array('phar', stream_get_wrappers()) || !class_exists('Phar', false)) {
+    echo "Phar extension not avaiable\n";
+    exit(255);
+}
+
+$web = 'www/index.php';
+
+/**
+ * Rewrite the HTTP request path to an internal file.
+ * Maps "" and "/" to "www/index.php".
+ *
+ * @param string $path Path from the browser, relative to the .phar
+ *
+ * @return string Internal path.
+ */
+function rewritePath($path)
+{
+    if ($path == '') {
+        //we need a / to get the relative links on index.php work
+        if (!isset($_SERVER['REQUEST_SCHEME'])) {
+            $_SERVER['REQUEST_SCHEME'] = 'http';
+        }
+        $url = $_SERVER['REQUEST_SCHEME'] . '://'
+            . $_SERVER['HTTP_HOST']
+            . preg_replace('/[?#].*$/', '', $_SERVER['REQUEST_URI'])
+            . '/';
+        header('Location: ' . $url);
+        exit(0);
+    } else if ($path == '/') {
+        return 'www/index.php';
+    }
+
+    if (substr($path, -4) == '.css') {
+        header('Expires: ' . date('r', time() + 86400 * 7));
+    }
+    return 'www' . $path;
+}
+
+if ($_SERVER['REQUEST_METHOD'] == 'HEAD') {
+    //work around https://bugs.php.net/bug.php?id=51918
+    header('IndieAuth: authorization_endpoint');
+    exit();
+}
+
+set_include_path(
+    'phar://' . __FILE__
+    . PATH_SEPARATOR . 'phar://' . __FILE__ . '/lib/'
+);
+Phar::webPhar(null, $web, null, array(), 'rewritePath');
+
+//TODO: implement CLI setup check
+echo "indieauth-openid can only be used in the browser\n";
+exit(1);
+__HALT_COMPILER();
+?>
index 425b23a..c56b9aa 100644 (file)
@@ -4,7 +4,10 @@ if (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS']) {
 } else {
     $prot = 'http';
 }
-$epUrl  = $prot . '://' . $_SERVER['HTTP_HOST'] . '/';
+$epUrl = $prot . '://' . $_SERVER['HTTP_HOST'] . '/';
+if (Phar::running()) {
+    $epUrl .= ltrim($_SERVER['SCRIPT_NAME'], '/') . '/';
+}
 $hepUrl = htmlspecialchars($epUrl);
 
 ?>
index 2e6b4c8..cb69845 100644 (file)
@@ -29,7 +29,22 @@ require_once 'OpenID/Exception.php';
 
 function loadDb()
 {
-    $db = new PDO('sqlite:' . __DIR__ . '/../data/tokens.sq3');
+    $pharFile = \Phar::running();
+    if ($pharFile == '') {
+        $dsn = 'sqlite:' . __DIR__ . '/../data/tokens.sq3';
+        $cfgFilePath = __DIR__ . '/config.php';
+    } else {
+        //remove phar:// from the path
+        $dir = dirname(substr($pharFile, 7)) . '/';
+        $dsn = 'sqlite:' . $dir . '/tokens.sq3';
+        $cfgFilePath = substr($pharFile, 7) . '.config.php';
+    }
+    //allow overriding DSN
+    if (file_exists($cfgFilePath)) {
+        include $cfgFilePath;
+    }
+
+    $db = new PDO($dsn);
     $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
     $db->exec("CREATE TABLE IF NOT EXISTS authtokens(
 code TEXT,
@@ -175,6 +190,8 @@ if (isset($_GET['openid_mode']) && $_GET['openid_mode'] != '') {
         }
     } catch (OpenID_Exception $e) {
         error('Error verifying OpenID login: ' . $e->getMessage());
+    } catch (Exception $e) {
+        error(get_class($e) . ': ' . $e->getMessage());
     }
 }
 
@@ -212,6 +229,8 @@ if ($_SERVER['REQUEST_METHOD'] == 'GET') {
         exit(0);
     } catch (OpenID_Exception $e) {
         error('OpenID error: ' . $e->getMessage());
+    } catch (Exception $e) {
+        error(get_class($e) . ': ' . $e->getMessage());
     }
 } else if ($_SERVER['REQUEST_METHOD'] == 'POST') {
     $redirect_uri = verifyUrlParameter($_POST, 'redirect_uri');