/Vector/ReplyTag.pm
package Vector::ReplyTag;
use Digest::SHA qw/sha1/;
use MIME::Base64;
use Vector::Channel;
use Vector::User;
use strict;

our $replytag_re = qr'\[replytag:([A-Za-z0-9+/=]{48})\]';

my $secret = '/yeXjbdTz28pGboTta26wrF7GY/SdZf2L5MP1S1oRHX61d4pA2+I+42CPt+aiS8qO4VDb5VOy+NLlYv1ny2OaAEpEu56YNo4EApxDMJ826QnS2VeywWz578KWbKtptwO3KsxO9qeD/SCCr4kTwONxQUNCvGSYvgLoBOITtN7KG+5RRuvYx2HXQpYI3MjBlHP+xTy19MCmK/kYdPp8sjtfUSsSEYGNV6ZbVJY8eQDryewzRQNULyA1hXhPMidyXxv';

sub calculate_hmac {
	my ($channel, $thread, $username) = @_;

	return sha1("$secret$channel$thread$username$secret");
}

sub create {
	my ($post) = @_;

	my $hmac = calculate_hmac($post->{channel}, $post->{thread}->{post_id}, $post->{user}->{username});
	my $replytag = encode_base64(pack('LLLLA20', $post->{channel_id}, $post->{thread}->{post_id}, $post->{user_id}, 0, $hmac));
	chomp $replytag;

	return "[replytag:$replytag]";
}

sub decode {
	my ($replytag) = @_;

	if ($replytag =~ $replytag_re) {
		my ($channel_id, $thread, $user_id, undef, $hmac) = unpack('LLLLA20', decode_base64($1));

		my $channel = Vector::Channel::name($channel_id);
		my $username = Vector::User->fetch_by_id($user_id)->{username};
		my $hmac_v = calculate_hmac($channel, $thread, $username);

		return unless $hmac eq $hmac_v;

		return {
			channel_id => $channel_id,
			thread => $thread,
			user_id => $user_id,
		};
	} else {
		return undef;
	}
}

1;