# This Source Code Form is subject to the terms of the Mozilla Public # License, v. 2.0. If a copy of the MPL was not distributed with this # file, You can obtain one at http://mozilla.org/MPL/2.0/. # # This Source Code Form is "Incompatible With Secondary Licenses", as # defined by the Mozilla Public License, v. 2.0. package Bugzilla::User::APIKey; use 5.10.1; use strict; use warnings; use base qw(Bugzilla::Object); use Bugzilla::User; use Bugzilla::Util qw(generate_random_password trim remote_ip); use Bugzilla::Error; ##################################################################### # Overriden Constants that are used as methods ##################################################################### use constant DB_TABLE => 'user_api_keys'; use constant DB_COLUMNS => qw( id user_id api_key app_id description revoked last_used last_used_ip ); use constant UPDATE_COLUMNS => qw(description revoked last_used last_used_ip); use constant VALIDATORS => { api_key => \&_check_api_key, app_id => \&_check_app_id, description => \&_check_description, revoked => \&Bugzilla::Object::check_boolean, }; use constant LIST_ORDER => 'id'; use constant NAME_FIELD => 'api_key'; # turn off auditing and exclude these objects from memcached use constant { AUDIT_CREATES => 0, AUDIT_UPDATES => 0, AUDIT_REMOVES => 0, USE_MEMCACHED => 0 }; # Accessors sub id { return $_[0]->{id} } sub user_id { return $_[0]->{user_id} } sub api_key { return $_[0]->{api_key} } sub app_id { return $_[0]->{app_id} } sub description { return $_[0]->{description} } sub revoked { return $_[0]->{revoked} } sub last_used { return $_[0]->{last_used} } sub last_used_ip { return $_[0]->{last_used_ip} } # Helpers sub user { my $self = shift; $self->{user} //= Bugzilla::User->new({name => $self->user_id, cache => 1}); return $self->{user}; } sub update_last_used { my $self = shift; my $timestamp = shift || Bugzilla->dbh->selectrow_array('SELECT LOCALTIMESTAMP(0)'); $self->set('last_used', $timestamp); $self->set('last_used_ip', remote_ip()); $self->update; } # Setters sub set_description { $_[0]->set('description', $_[1]); } sub set_revoked { $_[0]->set('revoked', $_[1]); } # Validators sub _check_api_key { return generate_random_password(40); } sub _check_description { return trim($_[1]) || ''; } sub _check_app_id { my ($invocant, $app_id) = @_; ThrowCodeError("invalid_app_id", { app_id => $app_id }) unless $app_id =~ /^[[:xdigit:]]+$/; return $app_id; } sub create_special { my ($class, @args) = @_; local VALIDATORS->{api_key} = sub { return $_[1] }; return $class->create(@args); } 1; __END__ =head1 NAME Bugzilla::User::APIKey - Model for an api key belonging to a user. =head1 SYNOPSIS use Bugzilla::User::APIKey; my $api_key = Bugzilla::User::APIKey->new($id); my $api_key = Bugzilla::User::APIKey->new({ name => $api_key }); # Class Functions $user_api_key = Bugzilla::User::APIKey->create({ description => $description, }); =head1 DESCRIPTION This package handles Bugzilla User::APIKey. C<Bugzilla::User::APIKey> is an implementation of L<Bugzilla::Object>, and thus provides all the methods of L<Bugzilla::Object> in addition to the methods listed below. =head1 METHODS =head2 Accessor Methods =over =item C<id> The internal id of the api key. =item C<user> The Bugzilla::User object that this api key belongs to. =item C<user_id> The user id that this api key belongs to. =item C<api_key> The API key, which is a random string. =item C<description> An optional string that lets the user describe what a key is used for. For example: "Dashboard key", "Application X key". =item C<revoked> If true, this api key cannot be used. =item C<last_used> The date that this key was last used. undef if never used. =item C<update_last_used> Updates the last used value to the current timestamp. This is updated even if the RPC call resulted in an error. It is not updated when the description or the revoked flag is changed. =item C<set_description> Sets the new description =item C<set_revoked> Sets the revoked flag =back