Page MenuHomeDevCentral

No OneTemporary

diff --git a/app/Analyzers/GitHubPayloadAnalyzer.php b/app/Analyzers/GitHubPayloadAnalyzer.php
index 739709f..b38cfd3 100644
--- a/app/Analyzers/GitHubPayloadAnalyzer.php
+++ b/app/Analyzers/GitHubPayloadAnalyzer.php
@@ -1,314 +1,315 @@
<?php
namespace Nasqueron\Notifications\Analyzers;
use Config;
+use Storage;
class GitHubPayloadAnalyzer {
///
/// Private members
///
/**
* The project name, used to load specific configuration and offer defaults
* @var string
*/
private $project;
/**
* The GitHub event triggering this request
* @var string
*/
private $event;
/**
* The request content, as a structured data
* @var stdClass
*/
private $payload;
/**
* The configuration for the payload analyzer
* @var GitHubPayloadAnalyzerConfiguration;
*/
private $configuration;
///
/// Constructor
///
/**
* Creates a new GitHubPayloadAnalyzer instance.
*
* @param string $project
* @param string $event
* @param stdClass $payload
*/
public function __construct($project, $event, $payload) {
$this->project = $project;
$this->event = $event;
$this->payload = $payload;
$this->loadConfiguration($project);
}
///
/// Configuration
///
const CONFIG_DEFAULT_FILE = 'default.json';
public function getConfigurationFileName () {
$dir = Config::get('services.github.analyzer.configDir');
$filename = $dir . '/' . $this->project . '.json';
- if (!file_exists($filename)) {
+ if (!Storage::has($filename)) {
return $dir . '/' . static::CONFIG_DEFAULT_FILE;
}
return $filename;
}
public function loadConfiguration () {
$fileName = $this->getConfigurationFileName();
$mapper = new \JsonMapper();
$this->configuration = $mapper->map(
- json_decode(file_get_contents($fileName)),
+ json_decode(Storage::get($fileName)),
new GitHubPayloadAnalyzerConfiguration()
);
}
///
/// Properties
///
public function getRepository () {
if ($this->isAdministrativeEvent()) {
return '';
}
return $this->payload->repository->name;
}
///
/// Qualification of the payload
///
public function isAdministrativeEvent () {
$administrativeEvents = [
'membership', // Member added to team
'ping', // Special ping ponf event, fired on new hook
'repository', // Repository created
];
return in_array($this->event, $administrativeEvents);
}
/**
* Gets the group for a specific payload
*
* @return string the group, central part of the routing key
*/
public function getGroup () {
// Some events are organization-level only and can't be mapped to an
// existing repository.
if ($this->isAdministrativeEvent()) {
return $this->configuration->administrativeGroup;
}
// If the payload is about some repository matching a table of
// symbols, we need to sort it to the right group.
$repository = $this->getRepository();
foreach ($this->configuration->repositoryMapping as $mapping) {
if ($mapping->doesRepositoryBelong($repository)) {
return $mapping->group;
}
}
// By default, fallback group is the project name or a specified value.
if (empty($this->configuration->defaultGroup)) {
return strtolower($this->project);
}
return $this->configuration->defaultGroup;
}
///
/// Description of the payload
///
/**
* Gets repository and branch information
*
* @return string
*/
public function getWhere () {
$repo = $this->payload->repository->name;
$branch = $this->payload->ref;
return static::getRepositoryAndBranch($repo, $branch);
}
/**
* Gets a repository and branch information string
*
* @param string $repo The repository
* @param string $branch The branch
* @return string "<repo>" or "<repo> (branch <branch>)" when branch isn't master
*/
public static function getRepositoryAndBranch ($repo = "", $branch = "") {
if ($repo === "") {
return "";
}
if (starts_with($branch, "refs/heads/")) {
$branch = substr($branch, 11);
}
if ($branch === "" || $branch === "master") {
return $repo;
}
return "$repo (branch $branch)";
}
/**
* Gets the title of the head commit
*
* @return string
*/
private function getHeadCommitTitle () {
return static::getCommitTitle($this->payload->head_commit->message);
}
/**
* Extracts the commit title from the whole commit message.
*
* @param string $message The commit message
* @return string The commit title
*/
public static function getCommitTitle ($message) {
// Discards extra lines
$pos = strpos($message, "\n");
if ($pos > 0) {
$message = substr($message, 0, $pos);
}
// Short messages are returned as is
$len = strlen($message);
if ($len <= 72) {
return $message;
}
// Longer messages are truncated
return substr($message, 0, 71) . '…';
}
/**
* Gets the description text for the head commit.
*
* @return string
*/
private function getHeadCommitDescription () {
$commit = $this->payload->head_commit;
$title = $this->getHeadCommitTitle();
$committer = $commit->committer->username;
$author = $commit->author->username;
$message = "$committer committed $title";
if ($committer !== $author) {
$message .= " (authored by $author)";
}
return $message;
}
/**
* Gets a short textual description of the event
*
* @return string
*/
public function getDescription () {
switch ($this->event) {
case "create":
$repository = $this->payload->repository->full_name;
$type = $this->payload->ref_type;
$ref = $this->payload->ref;
if ($type == "tag" || $type == "branch") {
return "New $type on $repository: $ref";
}
return "Unknown create: $type $ref";
case "ping":
$quote = $this->payload->zen;
return "« $quote » — GitHub Webhooks ping zen aphorism.";
case "push":
$n = count($this->payload->commits);
if ($n == 1) {
return $this->getHeadCommitDescription();
}
$repoAndBranch = $this->getWhere();
$user = $this->payload->pusher->name;
return "$user pushed $n commits to $repoAndBranch";
case "repository":
$repository = $this->payload->repository->full_name;
$message = "New repository $repository";
if ($this->payload->repository->fork) {
$message .= " (fork)";
}
if ($description = $this->payload->repository->description) {
$message .= " — $description";
}
return $message;
case "status":
return $this->payload->description
. " — "
. $this->payload->context;
default:
return "Some $this->event happened";
}
}
/**
* Gets a link to view the event on GitHub
*
* @return string The most relevant URL
*/
public function getLink () {
switch ($this->event) {
case "create":
$type = $this->payload->ref_type;
$ref = $this->payload->ref;
$url = $this->payload->repository->html_url;
if ($type == "tag") {
$url .= "/releases/tag/" . $ref;
} elseif ($type == "branch") {
$url .= "/tree/" . $ref;
}
return $url;
case "push":
$n = count($this->payload->commits);
if ($n == 1) {
return $this->payload->head_commit->url;
}
return $this->payload->compare;
case "repository":
return $this->payload->repository->html_url;
case "status":
return $this->payload->target_url;
default:
return "";
}
}
}
diff --git a/app/Analyzers/PhabricatorPayloadAnalyzer.php b/app/Analyzers/PhabricatorPayloadAnalyzer.php
index eab5abf..d043717 100644
--- a/app/Analyzers/PhabricatorPayloadAnalyzer.php
+++ b/app/Analyzers/PhabricatorPayloadAnalyzer.php
@@ -1,122 +1,123 @@
<?php
namespace Nasqueron\Notifications\Analyzers;
use Nasqueron\Notifications\Phabricator\PhabricatorStory;
use Config;
+use Storage;
class PhabricatorPayloadAnalyzer {
///
/// Private members
///
/**
* The project name, used to load specific configuration and offer defaults
* @var string
*/
private $project;
/**
* The story
* @var PhabricatorStory
*/
private $story;
/**
* The configuration for the payload analyzer
* @var PhabricatorPayloadAnalyzerConfiguration;
*/
private $configuration;
///
/// Constructor
///
/**
* Creates a new GitHubPayloadAnalyzer instance.
*
* @param string $project
* @param string $event
* @param stdClass $payload
*/
public function __construct($project, PhabricatorStory $story) {
$this->project = $project;
$this->story = $story;
$this->loadConfiguration($project);
}
///
/// Configuration
///
const CONFIG_DEFAULT_FILE = 'default.json';
public function getConfigurationFileName () {
$dir = Config::get('services.phabricator.analyzer.configDir');
$filename = $dir . '/' . $this->project . '.json';
- if (!file_exists($filename)) {
+ if (!Storage::has($filename)) {
return $dir . '/' . static::CONFIG_DEFAULT_FILE;
}
return $filename;
}
public function loadConfiguration () {
$fileName = $this->getConfigurationFileName();
$mapper = new \JsonMapper();
$this->configuration = $mapper->map(
- json_decode(file_get_contents($fileName)),
+ json_decode(Storage::get($fileName)),
new PhabricatorPayloadAnalyzerConfiguration()
);
}
///
/// Qualification of the story
///
public function isAdministrativeEvent () {
//TODO: determine events who qualify as administrative
return false;
}
/**
* Gets the group for a specific story
*
* @return string the group, central part of the routing key
*/
public function getGroup () {
// Some events are organization-level only and can't be mapped
// to projects.
if ($this->isAdministrativeEvent()) {
return $this->configuration->administrativeGroup;
}
// If the payload is about some repository matching a table of
// symbols, we need to sort it to the right group.
foreach ($this->configuration->groupsMapping as $mapping) {
foreach ($this->story->getProjects() as $project) {
if ($mapping->doesProjectBelong($project)) {
return $mapping->group;
}
}
}
// Words
foreach ($this->configuration->groupsMapping as $mapping) {
if ($mapping->doesStoryBelong($this->story)) {
return $mapping->group;
}
}
// By default, fallback group is the project name or a specified value.
if (empty($this->configuration->defaultGroup)) {
return strtolower($this->project);
}
return $this->configuration->defaultGroup;
}
}
diff --git a/app/Console/Commands/PhabricatorGetProjectsMap.php b/app/Console/Commands/PhabricatorGetProjectsMap.php
index 30fb683..9822eea 100644
--- a/app/Console/Commands/PhabricatorGetProjectsMap.php
+++ b/app/Console/Commands/PhabricatorGetProjectsMap.php
@@ -1,62 +1,63 @@
<?php
namespace Nasqueron\Notifications\Console\Commands;
use Illuminate\Console\Command;
+use Storage;
use Nasqueron\Notifications\Phabricator\ProjectsMap;
class PhabricatorGetProjectsMap extends Command {
/**
* The name and signature of the console command.
*
* @var string
*/
protected $signature = 'phabricator:projectsmap';
/**
* The console command description.
*
* @var string
*/
protected $description = 'Regerate the projects map for each Phabricator instances';
/**
* Create a new command instance.
*
* @return void
*/
public function __construct() {
parent::__construct();
}
/**
* Execute the console command.
*
* @return mixed
*/
public function handle() {
foreach ($this->getServicesCredentials() as $service) {
if ($service->gate == "Phabricator") {
$this->info("Querying projects map for " . $service->instance);
$map = ProjectsMap::fetch($service->instance);
$map->saveToCache();
$this->table(
['PHID', 'Project name'],
$map->toArray()
);
}
}
}
/**
* Gets service credentials
*
* @return stdClass the services credentials
*/
protected function getServicesCredentials () {
$path = config('services.gate.credentials');
- $data = json_decode(file_get_contents($path));
+ $data = json_decode(Storage::get($path));
return $data->services;
}
}
diff --git a/app/Http/Controllers/Gate/GateController.php b/app/Http/Controllers/Gate/GateController.php
index 1b80231..c045c21 100644
--- a/app/Http/Controllers/Gate/GateController.php
+++ b/app/Http/Controllers/Gate/GateController.php
@@ -1,128 +1,129 @@
<?php
namespace Nasqueron\Notifications\Http\Controllers\Gate;
use Nasqueron\Notifications\Features;
use Nasqueron\Notifications\Http\Controllers\Controller;
use Report;
+use Storage;
/**
* Represents a controller handling an entry-point for API payloads
*/
class GateController extends Controller {
///
/// Private members
///
/**
* @var string
*/
protected $door;
///
/// Requests
///
/**
* Handles GET requests
*/
public function onGet () {
// Virtually all the push APIs will send they payloads
// using a POST request, so we can provide a sensible
// default GET error message.
return view('gate/ispostonly');
}
/**
* Logs the request
*/
protected function logRequest () {
Log::info('[Gate] New payload.', [
'service' => static::SERVICE_NAME,
'door' => $this->door,
]);
}
///
/// Reports
///
/**
* Initializes the report and registers it
*/
protected function initializeReport () {
if (Features::isEnabled('ActionsReport')) {
Report::attachToGate(static::SERVICE_NAME, $this->door);
}
}
/**
* Renders the report
*
* @return Illuminate\Http\Response|null
*/
protected function renderReport () {
if (Features::isEnabled('ActionsReport')) {
return Report::render();
}
}
///
/// Credentials
///
/**
* Gets services credentials
*
* @return stdClass the services credentials
*/
protected function getServicesCredentials () {
$path = config('services.gate.credentials');
- $data = json_decode(file_get_contents($path));
+ $data = json_decode(Storage::get($path));
return $data->services;
}
/**
* Determines if a service definition matches this current gate and door.
*
* @param stdClass $service the service to check
* @return true if the service matches our gate and door; otherwise, false.
*/
protected function doesServiceMatch ($service) {
return $service->gate == static::SERVICE_NAME
&& $service->door == $this->door;
}
/**
* Gets service credentials for this gate and door
*
* @return stdClass the service credentials
*/
public function getService () {
foreach ($this->getServicesCredentials() as $service) {
if ($this->doesServiceMatch($service)) {
return $service;
}
}
return null;
}
/**
* Gets secret for this service and door.
*
* @return string the secret, or if unknown, an empty string
*/
protected function getSecret () {
$service= $this->getService();
if ($service !== null) {
return $service->secret;
}
return "";
}
}
diff --git a/app/Phabricator/PhabricatorAPI.php b/app/Phabricator/PhabricatorAPI.php
index fbac06a..e151f68 100644
--- a/app/Phabricator/PhabricatorAPI.php
+++ b/app/Phabricator/PhabricatorAPI.php
@@ -1,163 +1,165 @@
<?php
namespace Nasqueron\Notifications\Phabricator;
+use Storage;
+
class PhabricatorAPI {
///
/// Private members
///
/**
* The Phabricator main URL
*
* @var string
*/
private $instance;
/**
* The token generated at /settings/panel/apitokens/ to query the API
*
* @var string
*/
private $apiToken;
///
/// Constructors
///
/**
* Initializes a new instance of the Phabricator API class
*
* @param string $instance The Phabricator main URL, without trailing slash
* @param string $apiToken The token generated at /settings/panel/apitokens/
*/
public function __construct ($instance, $apiToken) {
$this->instance = $instance;
$this->apiToken = $apiToken;
}
public static function forInstance ($instance) {
$service = self::getServiceForInstance($instance);
if ($service === null) {
throw new \RuntimeException("No credentials for Phabricator instance $instance.");
}
return new self($service->instance, $service->secret);
}
/**
* Gets an API instance for the specify project
*
* @param string $project The name of the project (this matches the door parameter in credentials.json)
* @return PhabricatorAPI|null A PhabricatorAPI instance for the project if found; otherwise, null.
*/
public static function forProject ($project) {
$service = self::getServiceForProject($project);
if ($service === null) {
return null;
}
return new self($service->instance, $service->secret);
}
///
/// Helper methods for static constructors
///
private static function getServices () {
$path = config('services.gate.credentials');
- $data = json_decode(file_get_contents($path));
+ $data = json_decode(Storage::get($path));
return $data->services;
}
private static function getServiceForInstance ($instance) {
foreach (self::getServices() as $service) {
if ($service->gate === "Phabricator" && $service->instance === $instance) {
return $service;
}
}
return null;
}
private static function getServiceForProject ($project) {
foreach (self::getServices() as $service) {
if ($service->gate === "Phabricator" && $service->door === $project) {
return $service;
}
}
return null;
}
///
/// Public methods
///
/**
* Calls a Conduit API method
*
* @param $method The method to call (e.g. repository.create)
* @param $arguments The arguments to use
*/
public function call ($method, $arguments = []) {
$url = $this->instance . '/api/' . $method;
$arguments['api.token'] = $this->apiToken;
$reply = json_decode(static::post($url, $arguments));
if ($reply->error_code !== NULL) {
throw new PhabricatorAPIException(
$reply->error_code,
$reply->error_info
);
}
return $reply->result;
}
/**
* Gets the first result of an API reply
*
* @param Traversable|array $reply
* @return mixed
*/
public static function getFirstResult ($reply) {
if (is_object($reply) && property_exists($reply, 'data')) {
$reply = $reply->data;
}
foreach ($reply as $value) {
return $value;
}
}
///
/// CURL session
///
protected static function getPostFields ($arguments) {
$items = [];
foreach ($arguments as $key => $value) {
$items[] = urlencode($key) . '=' . urlencode($value);
}
return implode('&', $items);
}
protected static function post ($url, $arguments) {
$options = [
CURLOPT_URL => $url,
CURLOPT_HEADER => false,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_FOLLOWLOCATION => 1,
CURLOPT_POSTFIELDS => static::getPostFields($arguments),
];
$ch = curl_init();
curl_setopt_array($ch, $options);
$result = curl_exec($ch);
curl_close($ch);
return $result;
}
}
diff --git a/config/services.php b/config/services.php
index 452af52..1963d23 100644
--- a/config/services.php
+++ b/config/services.php
@@ -1,54 +1,54 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Third Party Services
|--------------------------------------------------------------------------
|
| This file is for storing the credentials for third party services such
| as Stripe, Mailgun, Mandrill, and others. This file provides a sane
| default location for this type of information, allowing packages
| to have a conventional place to find your various credentials.
|
*/
'mailgun' => [
'domain' => env('MAILGUN_DOMAIN'),
'secret' => env('MAILGUN_SECRET'),
],
'mandrill' => [
'secret' => env('MANDRILL_SECRET'),
],
'ses' => [
'key' => env('SES_KEY'),
'secret' => env('SES_SECRET'),
'region' => 'us-east-1',
],
'stripe' => [
'model' => Nasqueron\Notifications\User::class,
'key' => env('STRIPE_KEY'),
'secret' => env('STRIPE_SECRET'),
],
'github' => [
'analyzer' => [
- 'configDir' => storage_path(env('GITHUB_ANALYZER_CONFIG_DIR', 'app/GitHubPayloadAnalyzer'))
+ 'configDir' => env('GITHUB_ANALYZER_CONFIG_DIR', 'GitHubPayloadAnalyzer')
]
],
'phabricator' => [
'analyzer' => [
- 'configDir' => storage_path(env('PHABRICATOR_ANALYZER_CONFIG_DIR', 'app/PhabricatorPayloadAnalyzer'))
+ 'configDir' => env('PHABRICATOR_ANALYZER_CONFIG_DIR', 'PhabricatorPayloadAnalyzer')
]
],
'gate' => [
- 'credentials' => storage_path(env('CREDENTIALS', 'app/credentials.json')),
+ 'credentials' => env('CREDENTIALS', 'credentials.json'),
]
];

File Metadata

Mime Type
text/x-diff
Expires
Mon, Nov 25, 18:53 (10 h, 4 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
2260763
Default Alt Text
(24 KB)

Event Timeline