OAuth::Lite::ServerUtil - server side utility


OAuth-Lite documentation Contained in the OAuth-Lite distribution.

Index


Code Index:

NAME

Top

OAuth::Lite::ServerUtil - server side utility

SYNOPSIS

Top

    my $util = OAuth::Lite::ServerUtil->new;
    $util->support_signature_method('HMAC-SHA1');
    $util->allow_extra_params(qw/file size/);

    unless ($util->validate_params($oauth_params)) {
        return $server->error(400, $util->errstr);
    }

    $util->verify_signature(
        method          => $r->method,
        params          => $oauth_params,
        url             => $request_uri,
        consumer_secret => $consumer->secret,
    ) or return $server->error(401, $util->errstr);

And see OAuth::Lite::Server::mod_perl2 source code.

DESCRIPTION

Top

This module helps you to implement application that acts as OAuth Service Provider.

METHODS

Top

new

Constructor

    my $util = OAuth::Lite::ServerUtil->new;

Set strict true by default, and it judge unsupported param as invalid when validating params. You can build ServerUtil as non-strict mode, then it accepts unsupported parameters.

    my $util = OAuth::Lite::ServerUtil->new( strict => 0 );

allow_extra_param($param_name);

When you validate oauth parameters, if an extra parameter is included, the validation will fail.

    my $params = {
        oauth_version => '1.0',
        ...and other oauth parameters,
    };
    $params->{file} = "foo.jpg";

    # fail!
    unless ($util->validate_params($params)) {
        $your_app->error( $util->errstr );
    }

So, if you want allow extra parameter, use this method.

    $util->allow_extra_param('file');

    my $params = {
        oauth_version => '1.0',
        ...and other oauth parameters,
    };
    $params->{file} = "foo.jpg";

    # Now this results successfully.
    unless ($util->validate_params($params)) {
        $your_app->error( $util->errstr );
    }

allow_extra_params($param1, $param2, ...)

You can allow multiple extra parameters at once.

    $util->allow_extra_params(qw/file size/);

support_signature_method($method_class_name);

Set the signature method class's name that your server can supports.

    $util->support_signature_method('HMAC_SHA1');

This method requires indicated signature method class inside. So, you should install OAuth::Lite::SignatureMethod::$method_class_name beforehand. For example, when your choise is HMAC_SHA1, you need to have OAuth::Lite::SignatureMethod::HMAC_SHA1 installed in your server.

support_signature_methods($method1, $method2, ...);

You can set multiple signature method class at once.

    $util->support_signature_methods(qw/HMAC_SHA1 RSA_SHA1/);

validate_params($params, [$check_token]);

Check if the request includes all required params and doesn't include unsupported params. It doesn't check unsupported params when working on strict mode.

    unless ($util->validate_params($params)) {
        $your_app->error( $util->errstr );
    }

When the request is to exchange tokens or to access to protected resources, pass 1 for second argument. This flag indicates that oauth_token param is needed.

    unless ($util->validate_params($params, 1)) {
        $your_app->error( $util->errstr );
    }

validate_signature_method($method_name)

    unless ($util->validate_signature_method('HMAC-SHA1')) {

        $your_app->error(qq/Unsupported signature method/);
        ...
    }

verify_signature(%args)

method - HTTP request method
params - parameters hash reference
url - requested uri
consumer_secret - consumer secret value(optional)
token_secret - token secret value(optional)
    # you can omit consumer_secret and token_secret if you don't need them.
    $util->verify_signature(
        method          => $r->method, 
        params          => $params,
        url             => $requested_uri,
        consumer_secret => $consumer_secret,
        token_secret    => $token_secret,
    ) or die $utl->errstr;

SEE ALSO

Top

OAuth::Lite::Server::mod_perl2

AUTHOR

Top

Lyo Kato, lyo.kato _at_ gmail.com

COPYRIGHT AND LICENSE

Top


OAuth-Lite documentation Contained in the OAuth-Lite distribution.
package OAuth::Lite::ServerUtil;

use strict;
use warnings;

use base 'Class::ErrorHandler';

use OAuth::Lite::Util qw(
    decode_param
    create_signature_base_string
);
use OAuth::Lite::Problems qw(:all);
use List::MoreUtils qw(any none);
use UNIVERSAL::require;
use Carp ();

sub new {
    my $class = shift;
    my %args = @_;
    my $strict = exists $args{strict} ? $args{strict} : 1;
    my $self = bless {
        supported_signature_methods => {},
        allowed_extra_params        => [],
        strict                      => $strict,
    }, $class;
    $self;
}

sub allow_extra_param {
    my ($self, $param) = @_;
    push @{ $self->{allowed_extra_params} }, $param;
}

sub allow_extra_params {
    my $self = shift;
    $self->allow_extra_param($_) for @_;
}

sub support_signature_method {
    my ($self, $method_class) = @_;
    $method_class =~ s/-/_/g;
    my $class = join('::', 'OAuth::Lite::SignatureMethod', $method_class);
    $class->require or Carp::croak sprintf(q{Couldn't require class, %s}, $class);
    $self->{supported_signature_methods}{$class->method_name} = $class;
}

sub support_signature_methods {
    my $self = shift;
    $self->support_signature_method($_) for @_;
}

sub validate_params {
    my ($self, $origin_params, $check_token) = @_;
    my $params = {%$origin_params}; #copy
    delete $params->{oauth_consumer_key} or return $self->error(PARAMETER_ABSENT);
    delete $params->{oauth_nonce} or return $self->error(PARAMETER_ABSENT);
    delete $params->{oauth_timestamp} or return $self->error(PARAMETER_ABSENT);
    delete $params->{oauth_signature_method} or return $self->error(PARAMETER_ABSENT);
    delete $params->{oauth_signature} or return $self->error(PARAMETER_ABSENT);
    delete $params->{oauth_version};
    if ($check_token) {
        delete $params->{oauth_token} or return $self->error(PARAMETER_ABSENT);
    }
    if ( $self->{strict} ) {
        my @extra_params = keys %$params;
        my @allowed = @{ $self->{allowed_extra_params} };
        for my $extra ( @extra_params ) {
            if (none { $extra eq $_ } @allowed) {
                return $self->error(PARAMETER_REJECTED);
            }
        }
    }
    1;
}

sub validate_signature_method {
    my ($self, $method) = @_;
    return unless $method;
    any { $_ eq $method } keys %{$self->{supported_signature_methods}};
}

sub verify_signature {
    my ($self, %args) = @_;

    my $http_method = $args{method} or Carp::croak(qq/method not found/);
    my $url         = $args{url}    or Carp::croak(qq/url not found/);
    my $params      = $args{params} or Carp::croak(qq/params not found/);

    my $consumer_secret  = $args{consumer_secret} || '';
    my $token_secret     = $args{token_secret} || '';
    my $signature_method = $params->{oauth_signature_method};
    my $signature        = $params->{oauth_signature};

    my $base_string = create_signature_base_string($http_method, $url, $params);
    unless ($self->validate_signature_method($signature_method)) {
        return $self->error(SIGNATURE_METHOD_REJECTED);
    }
    my $method_class = $self->{supported_signature_methods}{$signature_method};
    my $method = $method_class->new(
        consumer_secret => $consumer_secret,
        token_secret    => $token_secret,
    );
    unless ($method->verify($base_string, $signature)) {
        return $self->error(SIGNATURE_INVALID);
    }
    1;
}

1;