Mojar-Google-Analytics

 view release on metacpan or  search on metacpan

lib/Mojar/Auth/Jwt.pm  view on Meta::CPAN


# JWT Claim Set
has 'iss';
has scope => sub { q{https://www.googleapis.com/auth/analytics.readonly} };
has aud => q{https://accounts.google.com/o/oauth2/token};
has iat => sub { time };
has duration => 60*60;  # 1 hour
has exp => sub { time + $_[0]->duration };

# JWT Signature
has 'private_key';

# Mogrified chunks

sub header {
  my $self = shift;

  if (@_ == 0) {
    my @h = map +( ($_, $self->$_) ), qw(typ alg);
    return $self->{header} = $self->mogrify( { @h } );
  }

lib/Mojar/Auth/Jwt.pm  view on Meta::CPAN

    );
  }
  else {
    %$self = ( %$self, @_ );
  }
  return $self;
}

has cipher => sub {
  my $self = shift;
  foreach ('private_key') {
    croak qq{Missing required field ($_)} unless defined $self->$_;
  }

  my $cipher = Crypt::OpenSSL::RSA->new_private_key($self->private_key);
  $cipher->use_pkcs1_padding;
  $cipher->use_sha256_hash;  # Requires openssl v0.9.8+
  return $cipher;
};

# Public methods

sub reset {
  my ($self) = @_;
  delete @$self{qw(iat exp body signature)};

lib/Mojar/Auth/Jwt.pm  view on Meta::CPAN


=head1 NAME

Mojar::Auth::Jwt - JWT authentication for Google services

=head1 SYNOPSIS

  use Mojar::Auth::Jwt;
  $jwt = Mojar::Auth::Jwt->new(
    iss => $auth_user,
    private_key => $private_key
  );
  $tx = $ua->post_form($jwt->aud, 'UTF-8', {
    grant_type => $grant_type,
    assertion => $jwt->encode
  });
  $token = $_->json->{access_token}
    if $_ = $tx->success;

=head1 DESCRIPTION

lib/Mojar/Auth/Jwt.pm  view on Meta::CPAN

Start of validity (epoch seconds).  Defaults to now.

=item duration

Length of validity period.  Defaults to an hour.

=item exp

Expiry time (epoch seconds).  Defaults to now + duration.

=item private_key

Private key.

=item header

JWT header.

=item body

JWT content.

=item signature

Signed encapsulation of header + body

=item cipher

Cipher object, built from Crypt::OpenSSL::RSA.  Before accessing, ensure
C<private_key> has been set.

=back

=head1 METHODS

=over 4

=item new

Constructor; typically only C<iss> and C<private_key> are needed.

=item reset

Clear out stale fields.

=item encode

Encode header and body and sign with a signature.  Either ensure header and body
are already set or pass them as parameters.

lib/Mojar/Google/Analytics.pm  view on Meta::CPAN

    );
  }
  return $self;
}

has res => sub { Mojar::Google::Analytics::Response->new };

# Authentication token
has 'auth_user';
has grant_type => 'urn:ietf:params:oauth:grant-type:jwt-bearer';
has 'private_key';
has jwt => sub {
  my $self = shift;
  my %param = map +($_ => $self->$_), 'private_key';
  $param{iss} = $self->auth_user;
  Mojar::Auth::Jwt->new(
    iss => $self->auth_user,
    private_key => $self->private_key
  )
};
has validity_margin => 10;  # Too close to expiry (seconds)
has token => sub { $_[0]->_request_token };

# Public methods

sub fetch {
  my ($self) = @_;
  croak 'Failed to see a built request' unless my $req = $self->req;

lib/Mojar/Google/Analytics.pm  view on Meta::CPAN


=head1 NAME

Mojar::Google::Analytics - Fetch Google Analytics reporting data

=head1 SYNOPSIS

  use Mojar::Google::Analytics;
  $analytics = Mojar::Google::Analytics->new(
    auth_user => q{1234@developer.gserviceaccount.com},
    private_key => $pk,
    profile_id => q{5678}
  );
  $analytics->req(
    dimensions => [qw(pagePath)],
    metrics => [qw(visitors pageviews)],
    sort => 'pagePath',
    start_index => $start,
    max_results => $max_resultset
  );
  if (my $res = $analytics->fetch) {

lib/Mojar/Google/Analytics.pm  view on Meta::CPAN

C<https://www.googleapis.com/analytics/v3/data/ga>.

=item ua

An instance of the user agent to use.  Defaults to a Mojo::UserAgent.

=item timeout

  $analytics = Mojar::Google::Analytics->new(
    auth_user => q{1234@developer.gserviceaccount.com},
    private_key => $pk,
    profile_id => q{5678},
    timeout => 120
  );

The inactivity timeout for the user agent.  Any change from the default (60 sec)
must be applied before the first use of the user agent, and so is best done when
creating your analytics object.

=item profile_id

lib/Mojar/Google/Analytics.pm  view on Meta::CPAN

=item auth_user

The user GA generated for you when you registered your application.  Should
end in C<@developer.gserviceaccount.com>.

=item grant_type

Currently the only supported value is
C<urn:ietf:params:oauth:grant-type:jwt-bearer>.

=item private_key

Your account's private key.

=item jwt

The JWT object.  Defaults to

  Mojar::Auth::Jwt->new(
    iss => $self->auth_user,
    private_key => $self->private_key
  )

=item validity_margin

How close (in seconds) to the expiry time should the current token be replaced.
Defaults to 10 seconds.

=item token

The current access token.

lib/Mojar/Google/Analytics.pm  view on Meta::CPAN

=head1 METHODS

=over 4

=item new

Sets the credentials for access.

  $analytics = Mojar::Google::Analytics->new(
    auth_user => q{1234@developer.gserviceaccount.com},
    private_key => $pk,
    profile_id => q{5678}
  );

=item fetch

Fetches first/next batch of results based on set credentials and the C<req>
object.  Automatically checks/renews the access token.

  $result = $analytics->fetch  # replaces $analytics->res

lib/Mojar/Google/Analytics/Response.pm  view on Meta::CPAN


=head1 NAME

Mojar::Google::Analytics::Response - Response object from GA reporting.

=head1 SYNOPSIS

  use Mojar::Google::Analytics::Response;
  $response = Mojar::Google::Analytics::Response->new(
    auth_user => q{1234@developer.gserviceaccount.com},
    private_key => $pk,
    profile_id => q{5678}
  );

=head1 DESCRIPTION

Container object returned from Google Analytics Core Reporting.

=head1 ATTRIBUTES

=over 4

lib/Mojar/Guide/GoogleAnalytics.pod  view on Meta::CPAN


=over 4

=item auth_user

The API user that Google created for you when you registered to use the API.
This is typically something of the form

  123456789@developer.gserviceaccount.com

=item private_key

The private key you generated to use against the API.  This is typically held in
a file (with a .pem suffix) and slurped up each time you want to use it.  Check
that the file contains a line for "BEGIN PRIVATE KEY" and also for "END PRIVATE
KEY".

=item profile_id

A string of digits identifying the appropriate profile; exactly the same one you
tested earlier.

=back

Then create your analytics object.

  my $analytics = Mojar::Google::Analytics->new(
    auth_user => q{123456789@developer.gserviceaccount.com},
    private_key => $pk,
    profile_id => '123456'
  );

You may optionally disable timeouts (default 60 sec) by including

  timeout => 0

=head1 FETCH RESULTS

=head2 Build the Request

test/20-auth.t  view on Meta::CPAN

      exp => q{1328554385}
    ), 'Decoded object agrees';
};

SKIP: {
  skip 'set TEST_KEY to enable this test (developer only!)', 1
    unless $ENV{TEST_KEY};
subtest q{Roundtrip encode->decode} => sub {
  my $jwt2;
  ok $jwt2 = $jwt->decode($jwt->encode(
      private_key => path('data/privatekey.pem')->slurp)), 'decode(encode())';
  delete @$jwt{qw( header body signature json cipher private_key )};
  is_deeply $jwt2, $jwt, 'Round trip';
};
};

done_testing();

test/70-retrieval.t  view on Meta::CPAN

  ok $pk, 'pk';
  $profile = slurp_chomped 'data/profile.txt';
  ok $profile, 'profile';
};

my ($analytics, $res);

subtest q{Basics} => sub {
  ok $analytics = Mojar::Google::Analytics->new(
    auth_user => $user,
    private_key => $pk,
    profile_id => $profile
  ), 'new(profile_id => ..)';

  ok $analytics->req(
    metrics => [qw(visits)]
  ), 'req(..)';
};

subtest q{Bad Auth} => sub {
  $analytics->{auth_user} .= 'X';



( run in 0.304 second using v1.01-cache-2.11-cpan-4d50c553e7e )