Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
76 changes: 55 additions & 21 deletions api.wordpress.org/public_html/dotorg/slack/announce.php
Original file line number Diff line number Diff line change
@@ -1,38 +1,72 @@
<?php
/**
* Slack slash-command handler for @here and @channel announcements.
*
* Standalone handler: WordPress is not loaded, so request data is never slashed. Slack
* authenticates itself with one of the shared `WEBHOOK_TOKEN_*` secrets below; nonces do
* not exist in server-to-server webhooks.
*
* phpcs:disable WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
*
* @package WordPressdotorg\API\Slack
*/

namespace {
require dirname( dirname( __DIR__ ) ) . '/includes/hyperdb/bb-10-hyper-db.php';
require dirname( dirname( __DIR__ ) ) . '/includes/slack-config.php';
}

namespace Dotorg\Slack\Announce {
namespace Dotorg\Slack\Announce;

require dirname( dirname( __DIR__ ) ) . '/includes/slack/announce/lib.php';
require dirname( __DIR__, 2 ) . '/includes/hyperdb/bb-10-hyper-db.php';
require dirname( __DIR__, 2 ) . '/includes/slack-config.php';
require dirname( __DIR__, 2 ) . '/includes/slack/announce/lib.php';

function get_avatar( $username, $slack_id, $team_id ) {
/**
* Returns the Gravatar URL for the WordPress.org account linked to a Slack user.
*
* Defined in this namespace so that `run()` in lib.php picks it up as an optional hook;
* it falls back to the Slack profile image when this function is not available.
*
* @param string $username The Slack user name. Unused, part of the hook signature.
* @param string $slack_id The Slack user ID to look up.
* @param string $team_id The Slack team ID. Unused, part of the hook signature.
* @return string The Gravatar URL, or an empty string when the Slack account is not linked.
*/
function get_avatar( $username, $slack_id, $team_id ) { // phpcs:ignore Generic.CodeAnalysis.UnusedFunctionParameter -- Signature is fixed by the call in lib.php.
global $wpdb;

$wp_user_id = $wpdb->get_var( $wpdb->prepare(
"SELECT user_id FROM slack_users WHERE slack_id = %s",
$slack_id
) );
$wp_user_id = $wpdb->get_var(
$wpdb->prepare(
'SELECT user_id FROM slack_users WHERE slack_id = %s',
$slack_id
)
);

if ( ! $wp_user_id ) {
return '';
}

$email = $wpdb->get_var(
$wpdb->prepare(
"SELECT user_email FROM $wpdb->users WHERE ID = %d",
$wp_user_id
)
);

$email = $wpdb->get_var( $wpdb->prepare(
"SELECT user_email FROM $wpdb->users WHERE ID = %d",
$wp_user_id
) );
if ( ! $email ) {
return '';
}

$hash = hash( 'sha256', strtolower( trim( $email ) ) );
return sprintf( 'https://secure.gravatar.com/avatar/%s?s=96d=mm&r=G&%s', $hash, time() );
return sprintf( 'https://secure.gravatar.com/avatar/%s?s=96&d=mm&r=G&%s', $hash, time() );
}

// Slack sends the token as POST data; anything else is not a webhook request.
if ( ! isset( $_POST['token'] ) || ! is_string( $_POST['token'] ) || '' === $_POST['token'] ) {
return;
}

$i = 0;
// WEBHOOK_TOKEN_1, WEBHOOK_TOKEN_2, etc.
while ( defined( __NAMESPACE__ . '\\WEBHOOK_TOKEN_' . ++$i ) ) {
while ( defined( __NAMESPACE__ . '\\WEBHOOK_TOKEN_' . ( ++$i ) ) ) {
if ( hash_equals( constant( __NAMESPACE__ . '\\WEBHOOK_TOKEN_' . $i ), $_POST['token'] ) ) {
run( $_POST );
break;
}
}

}

36 changes: 28 additions & 8 deletions api.wordpress.org/public_html/dotorg/slack/committers.php
Original file line number Diff line number Diff line change
@@ -1,19 +1,39 @@
<?php

// Allow committers to publicly mention other committers via @committers.
/**
* Slack outgoing-webhook handler that redirects @committers mentions to the slash command.
*
* Standalone handler: WordPress is not loaded, so request data is never slashed. Slack
* authenticates itself with the shared `WEBHOOK_TOKEN` secret below; nonces do not exist
* in server-to-server webhooks.
*
* phpcs:disable WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput.MissingUnslash
*
* @package WordPressdotorg\API\Slack
*/

namespace Dotorg\Slack\Committers;

require dirname( dirname( __DIR__ ) ) . '/includes/slack-config.php';
require dirname( __DIR__, 2 ) . '/includes/slack-config.php';

// Slack sends the token as POST data; anything else is not a webhook request.
if ( ! isset( $_POST['token'] ) || ! is_string( $_POST['token'] ) || '' === $_POST['token'] ) {
return;
}

if ( ! hash_equals( WEBHOOK_TOKEN, $_POST['token'] ) ) {
return;
}

echo json_encode( array(
'username' => 'wordpressdotorg',
'link_names' => 1,
'text' => sprintf( '@%s: Use the `/committers` command.', $_POST['user_name'] ),
) );
// The Slack user name of whoever triggered the webhook, echoed back in the JSON response below.
$user_name = (string) filter_var( $_POST['user_name'] ?? '', FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW );

// phpcs:ignore WordPress.WP.AlternativeFunctions.json_encode_json_encode -- No WP loaded.
echo json_encode(
array(
'username' => 'wordpressdotorg',
'link_names' => 1,
'text' => sprintf( '@%s: Use the `/committers` command.', $user_name ),
)
);

exit;