Расшифровываем короткие ссылки Confluence с помощью nginx

Автор: | 05.11.2018

В числе продуктов австралийской компании Atlassian есть Jira Service Desk для организации работы службы поддержки и Confluence для совместной работы над wiki-подобной базой знаний. Особенностью этих продуктов является совместная интеграция между собой, в частности клиентам Jira Service Desk можно читать статьи в Confluence без назначения соответствующей лицензии. Но это работает ровно до тех пор, пока оператор поддержки не пришлёт клиенту короткую ссылку на Confluence в формате

https://confluence.example.com/x/UgCZAQ
https://confluence.example.com/x/UgCZAQ.

И вот тут нас ждёт сюрприз, так как эта ссылка у клиента не откроется. При этом если разрешить к Confluence анонимный доступ, то для гостей такая ссылка работать будет, но для клиентов Jira Service Desk — нет, разработчики Atlassian тут непреклонны. Ошибка известна разработчикам, но исправлять её не торопятся и обходного решения нет: CONFSERVER-55964.

Можно было бы смириться с данной особенностью, но есть проблема — ссылки в формате TinyURL принудительно генерируются при использовании штатной функции «Поделиться этой страницей». А раз так, то придётся самим искать обходной путь. К счастью, формат таких ссылок не является секретом и даже есть статья о том, как их генерировать самостоятельно: How to programmatically generate the tiny link of a Confluence page. Как видно алгоритм там не сложной и обратимый, а значит написать обратную реализацию не составит труда.

Примечание 1. В данной статье подразумевается, что в качестве frontend-сервера для Confluence используется nginx.
Примечание 2. Для расшифровки нам потребуется модуль ngx_http_perl_module, соответственно он должен присутствовать в вашей системе.

Для обратного преобразования короткой ссылки в формате TinyURL в обычную ссылку в формате PageID создадим небольшой модуль

tinyurl.pm
tinyurl.pm, в котором выполним обратные преобразования и перенаправим пользователя на соответствующую страницу в Confluence:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
package tinyurl;
use nginx;
use MIME::Base64;
use constant URL => '/pages/viewpage.action?pageId=';
sub decode {
my $r = shift;
my $id = $r->filename;
# Transform tiny string to base64 string
$id =~ s/(.*)\///ge;
$id .= "A" x (8 - length($id));
$id =~ tr/-/\//;
$id =~ tr/_/+/;
# Convert base64 string to page ID
$id = decode_base64($id);
$id = unpack('L', $id);
# Redirect to page
$r->status(302);
$r->header_out('content-length', 0);
$r->header_out('location', URL . $id);
$r->send_http_header('text/html');
return OK;
}
1;
__END__
package tinyurl; use nginx; use MIME::Base64; use constant URL => '/pages/viewpage.action?pageId='; sub decode { my $r = shift; my $id = $r->filename; # Transform tiny string to base64 string $id =~ s/(.*)\///ge; $id .= "A" x (8 - length($id)); $id =~ tr/-/\//; $id =~ tr/_/+/; # Convert base64 string to page ID $id = decode_base64($id); $id = unpack('L', $id); # Redirect to page $r->status(302); $r->header_out('content-length', 0); $r->header_out('location', URL . $id); $r->send_http_header('text/html'); return OK; } 1; __END__
package tinyurl;

use nginx;
use MIME::Base64;

use constant URL => '/pages/viewpage.action?pageId=';

sub decode {
	my $r = shift;
	my $id = $r->filename;

	# Transform tiny string to base64 string
	$id =~ s/(.*)\///ge;
	$id .= "A" x (8 - length($id));
	$id =~ tr/-/\//;
	$id =~ tr/_/+/;

	# Convert base64 string to page ID
	$id = decode_base64($id);
	$id = unpack('L', $id);

	# Redirect to page
	$r->status(302);
	$r->header_out('content-length', 0);
	$r->header_out('location', URL . $id);
	$r->send_http_header('text/html');

	return OK;
}

1;
__END__

Внесём изменения в конфигурацию nginx:

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
load_module "ngx_http_perl_module.so";
http {
perl_require tinyurl.pm;
server {
server_name confluence.example.com;
location /x/ {
perl tinyurl::decode;
}
}
}
load_module "ngx_http_perl_module.so"; … http { perl_require tinyurl.pm; … server { server_name confluence.example.com; … location /x/ { perl tinyurl::decode; } } }
load_module "ngx_http_perl_module.so";
…

http {
	perl_require tinyurl.pm;
	…

	server {
		server_name confluence.example.com;
		…

		location /x/ {
			perl tinyurl::decode;
		}
	}
}

После выполнения

nginx -s reload
nginx -s reload за обработку коротких ссылок вместо Confluence будет отвечать nginx и при запросе
https://confluence.example.com/x/UgCZAQ
https://confluence.example.com/x/UgCZAQ любой пользователь будет перенаправлен на
https://confluence.example.com/pages/viewpage.action?pageId=26804306
https://confluence.example.com/pages/viewpage.action?pageId=26804306.

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *