From 58ce95a255c04e1b6ecac0d794bc4dbeb23871de Mon Sep 17 00:00:00 2001 From: Romain d'Alverny Date: Sun, 16 Jan 2022 17:01:53 +0100 Subject: Add test coverage, add tests, refactor OPML code --- app/classes/CSRF.php | 4 +-- app/classes/Opml.php | 11 +++++++- app/classes/OpmlManager.php | 65 +++++++++++++++++++++++++++++---------------- 3 files changed, 54 insertions(+), 26 deletions(-) (limited to 'app') diff --git a/app/classes/CSRF.php b/app/classes/CSRF.php index 9a700cf..cf9fc1e 100644 --- a/app/classes/CSRF.php +++ b/app/classes/CSRF.php @@ -3,7 +3,7 @@ class CSRF { /** @var string */ - const HMAC_ALGORITHM = 'sha1'; + const HMAC_ALGORITHM = 'sha256'; /** @var string */ const SESSION_KEY_NAME = '_csrf_key'; @@ -48,7 +48,7 @@ class CSRF public static function getKey() { if (empty($_SESSION[self::SESSION_KEY_NAME])) { - $_SESSION[self::SESSION_KEY_NAME] = random_bytes(16); + $_SESSION[self::SESSION_KEY_NAME] = bin2hex(random_bytes(16)); } return $_SESSION[self::SESSION_KEY_NAME]; } diff --git a/app/classes/Opml.php b/app/classes/Opml.php index c5f185f..b91b43e 100644 --- a/app/classes/Opml.php +++ b/app/classes/Opml.php @@ -9,6 +9,9 @@ class Opml public string $ownerEmail = ''; public string $ownerId = ''; + public string $dateCreated = ''; + public string $dateModified = ''; + public string $title = ''; /** @var array */ @@ -21,7 +24,7 @@ class Opml 'TITLE' => 'name', 'XMLURL' => 'feed', 'DESCRIPTION' => 'description', - 'ISDOWN' => 'isDown' + 'ISDOWN' => 'isDown', ); @@ -81,6 +84,12 @@ class Opml case 'OWNERID': $this->ownerId = $cdata; break; + case 'DATECREATED': + $this->dateCreated = $cdata; + break; + case 'DATEMODIFIED': + $this->dateModified = $cdata; + break; } } diff --git a/app/classes/OpmlManager.php b/app/classes/OpmlManager.php index cd3d685..679d1c4 100644 --- a/app/classes/OpmlManager.php +++ b/app/classes/OpmlManager.php @@ -3,7 +3,7 @@ class OpmlManager { - public static function load($file) + public static function load(string $file) : Opml { if (!file_exists($file)) { throw new Exception('OPML file not found!'); @@ -22,44 +22,63 @@ class OpmlManager return $opml; } - /** - * @param Opml $opml - * @param string $file - */ - public static function save($opml, $file) + public static function format(Opml $opml, $freezeDateModified = false) : string { - $out = ''."\n"; - $out.= ''."\n"; - $out.= ''."\n"; - $out.= ''.htmlspecialchars($opml->getTitle()).''."\n"; - $out.= ''.gmdate('c').''."\n"; - $out.= ''.gmdate('c').''."\n"; + $owner = ''; if ($opml->ownerName != '') { - $out.= ''.htmlspecialchars($opml->ownerName).''."\n"; + $owner .= ''.htmlspecialchars($opml->ownerName).''."\n"; } if ($opml->ownerEmail != '') { - $out.= ''.htmlspecialchars($opml->ownerEmail).''."\n"; + $owner .= ''.htmlspecialchars($opml->ownerEmail).''."\n"; } if ($opml->ownerId != '') { - $out.= ''.htmlspecialchars($opml->ownerId).''."\n"; + $owner .= ''.htmlspecialchars($opml->ownerId).''."\n"; } - $out.= 'http://opml.org/spec2.opml'."\n"; - $out.= ''."\n"; - $out.= ''."\n"; + $entries = ''; foreach ($opml->entries as $person) { - $out .= sprintf( - '', + $entries .= sprintf( + "\t" . '', htmlspecialchars($person['name'], ENT_QUOTES), htmlspecialchars($person['website'], ENT_QUOTES), htmlspecialchars($person['feed'], ENT_QUOTES), htmlspecialchars($person['isDown'] ?? '', ENT_QUOTES) ) . "\n"; } - $out.= ''."\n"; - $out.= ''; - file_put_contents($file, $out); + $template = << + + + %s + %s + %s + %s + http://opml.org/spec2.opml + + +%s + + +XML; + + return sprintf( + $template, + htmlspecialchars($opml->getTitle()), + $opml->dateCreated, + $freezeDateModified ? $opml->dateModified : date_format(date_create('now', new DateTimeZone('UTC')), DateTimeInterface::ATOM), + $owner, + $entries + ); + } + + /** + * @param Opml $opml + * @param string $file + */ + public static function save(Opml $opml, string $file) : int|bool + { + return file_put_contents($file, self::format($opml)); } public static function backup($file) -- cgit v1.2.1