slack/src/Http/Controllers/SlackAppController.php

179 lines
5.5 KiB
PHP

<?php
namespace Slack\Http\Controllers;
use GuzzleHttp\Client;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Facades\Log;
use Illuminate\Support\Facades\Redirect;
use Slack\Jobs\TeamUpdate;
use Slack\Models\{Enterprise,Team,Token,User};
use App\Http\Controllers\Controller;
class SlackAppController extends Controller
{
protected const LOGKEY = 'CSA';
private const slack_authorise_url = 'https://slack.com/oauth/v2/authorize';
private const slack_oauth_url = 'https://slack.com/api/oauth.v2.access';
/**
* Install this app - Slack Button
*/
public function button()
{
return sprintf(
'<a href="%s?%s" style="align-items:center;color:#000;background-color:#fff;border:1px solid #ddd;border-radius:4px;display:inline-flex;font-family:Lato, sans-serif;font-size:18px;font-weight:600;height:40px;justify-content:center;text-decoration:none;width:180px">'
.'<svg xmlns="http://www.w3.org/2000/svg" style="height:24px;width:24px;margin-right:12px" viewBox="0 0 122.8 122.8">'
.'<path d="M25.8 77.6c0 7.1-5.8 12.9-12.9 12.9S0 84.7 0 77.6s5.8-12.9 12.9-12.9h12.9v12.9zm6.5 0c0-7.1 5.8-12.9 12.9-12.9s12.9 5.8 12.9 12.9v32.3c0 7.1-5.8 12.9-12.9 12.9s-12.9-5.8-12.9-12.9V77.6z" fill="#e01e5a"></path>'
.'<path d="M45.2 25.8c-7.1 0-12.9-5.8-12.9-12.9S38.1 0 45.2 0s12.9 5.8 12.9 12.9v12.9H45.2zm0 6.5c7.1 0 12.9 5.8 12.9 12.9s-5.8 12.9-12.9 12.9H12.9C5.8 58.1 0 52.3 0 45.2s5.8-12.9 12.9-12.9h32.3z" fill="#36c5f0"></path>'
.'<path d="M97 45.2c0-7.1 5.8-12.9 12.9-12.9s12.9 5.8 12.9 12.9-5.8 12.9-12.9 12.9H97V45.2zm-6.5 0c0 7.1-5.8 12.9-12.9 12.9s-12.9-5.8-12.9-12.9V12.9C64.7 5.8 70.5 0 77.6 0s12.9 5.8 12.9 12.9v32.3z" fill="#2eb67d"></path>'
.'<path d="M77.6 97c7.1 0 12.9 5.8 12.9 12.9s-5.8 12.9-12.9 12.9-12.9-5.8-12.9-12.9V97h12.9zm0-6.5c-7.1 0-12.9-5.8-12.9-12.9s5.8-12.9 12.9-12.9h32.3c7.1 0 12.9 5.8 12.9 12.9s-5.8 12.9-12.9 12.9H77.6z" fill="#ecb22e"></path>'
.'</svg>Add to Slack</a>',
self::slack_authorise_url,
http_build_query($this->parameters())
);
}
public function home()
{
return sprintf('Hi, for instructions on how to install me, please reach out to <strong>%s</strong>.',config('slack.app_admin','Your slack admin'));
}
public function setup()
{
return Redirect::to(self::slack_authorise_url.'?'.http_build_query($this->parameters()));
}
/**
* Install this Slack Application.
*
* @param Request $request
* @return string
* @throws \GuzzleHttp\Exception\GuzzleException
*/
public function install(Request $request,bool $oauth=FALSE)
{
if (! config('slack.client_id') OR ! config('slack.client_secret'))
abort(403,'Slack ClientID or Secret not set');
$client = new Client;
$response = $client->request('POST',self::slack_oauth_url,[
'auth'=>[config('slack.client_id'),config('slack.client_secret')],
'form_params'=>[
'code'=>$request->get('code'),
'redirect_url'=>$request->url(),
],
]);
if ($response->getStatusCode() != 200)
abort(403,'Something didnt work, status code not 200');
$output = json_decode($response->getBody());
if (App::environment() == 'local')
file_put_contents('/tmp/install',print_r($output,TRUE));
if (! $output->ok)
abort(403,'Something didnt work, status not OK ['.(string)$response->getBody().']');
// Are we an enterprise?
$eo = NULL;
if ($output->enterprise) {
$eo = Enterprise::firstOrNew(
[
'enterprise_id'=>$output->enterprise->id
]);
$eo->name = $output->enterprise->name;
$eo->active = TRUE;
$eo->save();
}
// Store our team details
$so = Team::firstOrNew(
[
'team_id'=>$output->team->id
]);
// We just installed, so we'll make it active, even if it already exists.
$so->description = $output->team->name;
$so->active = 1;
$so->enterprise_id = $eo ? $eo->id : NULL;
$so->save();
dispatch((new TeamUpdate($so))->onQueue('slack'));
// Store our app token
$to = $so->token;
if (! $to) {
$to = new Token;
$to->description = 'App: Oauth';
}
$to->active = 1;
$to->token = $output->access_token;
$to->scope = $output->scope;
$so->token()->save($to);
Log::debug(sprintf('%s:TOKEN Created [%s]',self::LOGKEY,$to->id),['m'=>__METHOD__]);
// Create the bot user
// Store the user who install, and make them admin
$bo = User::firstOrNew(
[
'user_id'=>$output->bot_user_id,
]);
$bo->enterprise_id = $eo ? $eo->id : NULL;
$bo->team_id = $so->id;
$bo->active = 0;
$bo->admin = 0;
$bo->save();
$so->bot_id = $bo->id;
$so->save();
Log::debug(sprintf('%s:BOT Created [%s]',self::LOGKEY,$bo->id),['m'=>__METHOD__]);
// Store the user who install, and make them admin
$uo = User::firstOrNew(
[
'user_id'=>$output->authed_user->id,
]);
$uo->enterprise_id = $eo ? $eo->id : NULL;
$uo->team_id = $eo ? NULL : $so->id;
$uo->active = 1;
$uo->admin = 1;
$uo->save();
Log::debug(sprintf('%s:ADMIN Created [%s]',self::LOGKEY,$uo->id),['m'=>__METHOD__]);
// Update Slack Object with admin_id
$so->admin_id = $uo->id;
$so->save();
return $oauth ? $output : sprintf('All set up! Head back to your slack instance <strong>%s</strong>.',$so->description);
}
/**
* Define our parameters to install this Slack Integration
*
* @note The configuration file should include a list of scopes that this application needs
* @return array
*/
private function parameters(): array
{
return [
'client_id' => config('slack.client_id'),
'scope' => join(',',config('slack.bot_scopes')),
'user_scope' => join(',',config('slack.user_scopes')),
];
}
}