From 09d36d36f49be98ea934e8f8383a412eb047ba39 Mon Sep 17 00:00:00 2001
From: Andrew Hoffmann <andrew.hoffmann@wisc.edu>
Date: Tue, 6 Dec 2016 12:57:30 -0600
Subject: [PATCH] LocalUserDetailsProvider throws Exception if JSON is invalid,
 returns null if JSON is missing

---
 .../uwphps/local/JsonDecodingException.php    |  9 ++++++
 .../uwphps/local/LocalUserDetailsProvider.php | 15 +++++++---
 .../local/LocalUserDetailsProviderTest.php    | 30 ++++++++++++++-----
 src/test/resources/badjson.json               |  3 ++
 4 files changed, 46 insertions(+), 11 deletions(-)
 create mode 100644 src/main/edu/wisc/doit/uwphps/local/JsonDecodingException.php
 create mode 100644 src/test/resources/badjson.json

diff --git a/src/main/edu/wisc/doit/uwphps/local/JsonDecodingException.php b/src/main/edu/wisc/doit/uwphps/local/JsonDecodingException.php
new file mode 100644
index 0000000..88fa5ef
--- /dev/null
+++ b/src/main/edu/wisc/doit/uwphps/local/JsonDecodingException.php
@@ -0,0 +1,9 @@
+<?php
+namespace edu\wisc\doit\uwphps\local;
+
+/**
+ * Exception when JSON cannot be decoded
+ */
+class JsonDecodingException extends \RuntimeException
+{
+}
\ No newline at end of file
diff --git a/src/main/edu/wisc/doit/uwphps/local/LocalUserDetailsProvider.php b/src/main/edu/wisc/doit/uwphps/local/LocalUserDetailsProvider.php
index 7a15d83..9abe0cb 100644
--- a/src/main/edu/wisc/doit/uwphps/local/LocalUserDetailsProvider.php
+++ b/src/main/edu/wisc/doit/uwphps/local/LocalUserDetailsProvider.php
@@ -26,16 +26,23 @@ class LocalUserDetailsProvider extends PreauthUserDetailsProvider
     }
 
     /**
-     * {@inheritdoc}
+     * Loads user from configured JSON file.
+     *
+     * @return UWUserDetails  user, null if file is missing
+     * @throws JsonDecodingException  if unable to decode user JSON file
      */
     public function loadUser()
     {
-        $jsonString = file_get_contents($this->filePath);
-        if ($jsonString === false) {
+        if (!is_readable($this->filePath)) {
             return null;
         }
 
-        $attributes = json_decode($jsonString, true);
+        $attributes = json_decode(file_get_contents($this->filePath), true);
+
+        // Throw exception if file cannot be decoded
+        if ($attributes === null) {
+            throw new JsonDecodingException('Unable to parse JSON in file: ' . realpath($this->filePath));
+        }
 
         return new UWUserDetails(
             $attributes[static::EPPN],
diff --git a/src/test/edu/wisc/doit/uwphps/local/LocalUserDetailsProviderTest.php b/src/test/edu/wisc/doit/uwphps/local/LocalUserDetailsProviderTest.php
index 3ee4255..a277d06 100644
--- a/src/test/edu/wisc/doit/uwphps/local/LocalUserDetailsProviderTest.php
+++ b/src/test/edu/wisc/doit/uwphps/local/LocalUserDetailsProviderTest.php
@@ -1,6 +1,5 @@
 <?php
-
-use edu\wisc\doit\uwphps\local\LocalUserDetailsProvider;
+namespace edu\wisc\doit\uwphps\local;
 
 /**
  * Tests for {@link LocalUserDetailsProvider}.
@@ -8,12 +7,12 @@ use edu\wisc\doit\uwphps\local\LocalUserDetailsProvider;
 class LocalUserDetailsProviderTest extends \PHPUnit_Framework_TestCase
 {
 
-    /**
-     * @test
-     */
-    public function loadUser()
+    private $resourcesDir = __DIR__ . '/../../../../../resources';
+
+    /** @test */
+    public function loadsUser()
     {
-        $userDetailsService = new LocalUserDetailsProvider(__DIR__ . "/../../../../../resources/localuser.json");
+        $userDetailsService = new LocalUserDetailsProvider("{$this->resourcesDir}/localuser.json");
         $user = $userDetailsService->loadUser();
         $this->assertEquals("bbadger@wisc.edu", $user->getEppn());
         $this->assertEquals("UW123A456", $user->getPvi());
@@ -25,4 +24,21 @@ class LocalUserDetailsProviderTest extends \PHPUnit_Framework_TestCase
         $this->assertEquals("BADGER", $user->getLastName());
     }
 
+    /** @test */
+    public function loadsNullUserWhenMissingFile()
+    {
+        $provider = new LocalUserDetailsProvider("{$this->resourcesDir}/nobody.json");
+        $this->assertNull($provider->loadUser());
+    }
+
+    /**
+     * @test
+     * @expectedException \edu\wisc\doit\uwphps\local\JsonDecodingException
+     */
+    public function throwsIfInvalidJson()
+    {
+        $provider = new LocalUserDetailsProvider("{$this->resourcesDir}/badjson.json");
+        $provider->loadUser();
+    }
+
 }
diff --git a/src/test/resources/badjson.json b/src/test/resources/badjson.json
new file mode 100644
index 0000000..096ced5
--- /dev/null
+++ b/src/test/resources/badjson.json
@@ -0,0 +1,3 @@
+This file should not contain valid JSON.
+
+See: LocalUserDetailsProviderTest
\ No newline at end of file
-- 
GitLab