diff options
Diffstat (limited to 'extensions/SAML2Auth/lib/IDP.pm')
-rw-r--r-- | extensions/SAML2Auth/lib/IDP.pm | 381 |
1 files changed, 381 insertions, 0 deletions
diff --git a/extensions/SAML2Auth/lib/IDP.pm b/extensions/SAML2Auth/lib/IDP.pm new file mode 100644 index 000000000..fd02fe3e7 --- /dev/null +++ b/extensions/SAML2Auth/lib/IDP.pm @@ -0,0 +1,381 @@ +# 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/. + +package Bugzilla::Extension::SAML2Auth::IDP; + +use strict; +use warnings; +use 5.10.1; +use Scalar::Util qw(blessed); + +use Bugzilla::Constants; +use Bugzilla::Field; +use Bugzilla::Util; +use Bugzilla::Error; +use Date::Parse; + +use base qw(Bugzilla::Object); + +use Bugzilla::Extension::SAML2Auth::Util; + +############################### +#### Initialization #### +############################### + +use constant DB_TABLE => 'saml2auth_idp'; +use constant DB_COLUMNS => qw( + id + name + cacert + icon + url + metadata + expires + isactive + userregexp + comment + saml_extern_id_attr + ldap_extern_id_attr + ldap_mail_attrs +); + +use constant UPDATE_COLUMNS => qw( + name + cacert + icon + url + metadata + expires + isactive + userregexp + comment + saml_extern_id_attr + ldap_extern_id_attr + ldap_mail_attrs +); + +use constant VALIDATORS => { + name => \&_check_name, + cacert => \&_check_filename, + icon => \&_check_filename, + url => \&_check_url, + metadata => \&_check_cert, + expires => \&_check_datetime, + isactive => \&Bugzilla::Object::check_boolean, + userregexp => \&_check_user_regexp, + comment => \&_check_comment, + saml_extern_id_attr => \&_check_comment, + ldap_extern_id_attr => \&_check_comment, + ldap_mail_attrs => \&_check_comment, +}; + +############################### +#### Validators #### +############################### + +sub _check_datetime { + my ($invocant, $date_time) = @_; + + # Empty datetimes are empty strings or strings only containing + # 0's, whitespace, and punctuation. + if ($date_time =~ /^[\s0[:punct:]]*$/) { + return; + } + + $date_time = trim($date_time); + my ($ss, $mm, $hh, $day, $month, $year, $zone) = strptime($date_time); + + unless (defined $year && defined $month && defined $day) { + ThrowUserError('illegal_date', {date => $date_time, format => 'YYYY-MM-DD'}); + } + unless (defined $ss && defined $mm && defined $hh) { + ThrowUserError('illegal_time', {'time' => $date_time, format => 'HH:MM:SS'}); + } + return ($date_time); +} + +sub _check_filename { + my ($invocant, $filename) = @_; + + $filename = trim($filename); + return ($filename); +} + +sub _check_name { + my ($invocant, $name) = @_; + $name = trim($name); + ThrowUserError('invalid_parameter', + {name => 'name', err => 'Name must not be empty'}) + unless $name; + return $name; +} + +sub _check_url { + my ($invocant, $url) = @_; + if (!defined $url || $url eq '') { + ThrowUserError('invalid_parameter', + {name => 'url', err => 'URL must not be empty'}); + } + return ($url); +} + +sub _check_cert { + my ($invocant, $cert) = @_; + $cert = trim($cert); + return ($cert); +} + +sub _check_user_regexp { + my ($invocant, $regex) = @_; + $regex = trim($regex) || ''; + ThrowUserError("invalid_regexp") unless (eval {qr/$regex/}); + return ($regex); +} + +sub _check_comment { + my ($invocant, $comment) = @_; + $comment = trim($comment); + return ($comment); +} + +############################### +#### Methods #### +############################### + +sub set_name { $_[0]->set('name', $_[1]); return; } +sub set_cacert { $_[0]->set('cacert', $_[1]); return; } +sub set_icon { $_[0]->set('icon', $_[1]); return; } +sub set_url { $_[0]->set('url', $_[1]); return; } +sub set_metadata { $_[0]->set('metadata', $_[1]); return; } +sub set_expires { $_[0]->set('expires', $_[1]); return; } +sub set_isactive { $_[0]->set('isactive', $_[1]); return; } +sub set_userregexp { $_[0]->set('userregexp', $_[1]); return; } +sub set_comment { $_[0]->set('comment', $_[1]); return; } + +sub set_saml_extern_id_attr { + $_[0]->set('saml_extern_id_attr', $_[1]); + return; +} + +sub set_ldap_extern_id_attr { + $_[0]->set('ldap_extern_id_attr', $_[1]); + return; +} +sub set_ldap_mail_attrs { $_[0]->set('ldap_mail_attrs', $_[1]); return; } + +# IDP groups specify who is NOT allowed to use it! +sub set_groups { + my $self = shift; + my $group_ids = shift; + + my @groups; + if (ref $group_ids) { + @groups = @$group_ids; + } + else { + @groups = ($group_ids); + } + + my $dbh = Bugzilla->dbh; + + $dbh->do(q{DELETE FROM saml2auth_idp_groups WHERE idp_id = ?}, undef, + $self->id); + + my $sth = $dbh->prepare(q{INSERT INTO saml2auth_idp_groups VALUES (?, ?)}); + + foreach my $group_id (@groups) { + next unless $group_id =~ /(\d+)/; + my $id = $1; + my $group = Bugzilla::Group->new($id); + $sth->execute($self->id, $id) if ($group); + } + + delete $self->{groups}; + + return; +} + +############################### +#### Accessors #### +############################### + +sub id { return ($_[0]->{id}); } +sub name { return ($_[0]->{name}); } +sub cacert { return ($_[0]->{cacert}); } +sub icon { return ($_[0]->{icon}); } +sub url { return ($_[0]->{url}); } +sub metadata { return ($_[0]->{metadata}); } +sub expires { return ($_[0]->{expires}); } +sub isactive { return ($_[0]->{isactive}); } +sub userregexp { return ($_[0]->{userregexp}); } +sub comment { return ($_[0]->{comment}); } +sub saml_extern_id_attr { return ($_[0]->{saml_extern_id_attr}); } +sub ldap_extern_id_attr { return ($_[0]->{ldap_extern_id_attr}); } +sub ldap_mail_attrs { return ($_[0]->{ldap_mail_attrs}); } + +# IDP groups specify who is NOT allowed to use it! +sub groups { + my $self = shift; + + unless ($self->{groups}) { + my $dbh = Bugzilla->dbh; + + my $ids + = $dbh->selectcol_arrayref( + q{SELECT DISTINCT group_id FROM saml2auth_idp_groups WHERE idp_id = ?}, + undef, $self->id); + + $self->{groups} = $ids; + } + return ($self->{groups}); +} + +sub expired { + my $self = shift; + unless ($self->{expired}) { + my $dbh = Bugzilla->dbh; + $self->{expired} + = $dbh->selectrow_array( + 'SELECT expires < NOW() from saml2auth_idp where id = ?', + undef, $self->id); + } + return ($self->{expired}); +} + +1; + +__END__ + +=head1 Description + +Bugzilla::Extension::SAML2Auth::IDP - A module for encapsulating IDP metadata. + +=head1 Fields + +=over 4 + +=item id + +The index for this IDP in the database. + +=item name + +The name of this IDP. + +=item cacert + +The full path to the CA certificate file used to authenticate certificates from this IDP. + +=item icon + +The FontAwesome icon used in the Login Menu for this IDP. + +=item url + +The metadata URL for this IDP. + +=item metadata + +A stored copy of this IDPs metadata. + +=item expires + +The date this IDPs stored metadata expires. + +=item isactive + +Is this IDP allowed to be used? + +=item userregexp + +A perl regular expression for email addresses to allow or deny for this IDP. + +=item groups + +A collection of groups who are NOT permitted to use this IDP. + +=item saml_extern_id_attr + +The attribute in the SAML response that conatins the unique external ID. + +=item ldap_extern_id_attr + +The attribute in LDAP that conatins the unique external ID. + +=item ldap_mail_attrs + +A comma separated list of LDAP attributes to use for mail address, in descending order of preference. + +=back + +=head1 Accessors + +These methods allow you to get the specified field from the IPD. + +=over 4 + +=item id + +=item name + +=item cacert + +=item icon + +=item url + +=item metadata + +=item expires + +=item isactive + +=item userregexp + +=item groups + +=item saml_extern_id_attr + +=item ldap_extern_id_attr + +=item ldap_mail_attrs + +=item expired + +A function that checks to see if the expires date has passed. + +=back + +=head1 Methods + +These methods allow you to set the spcified field from the IPD. + +=over 4 + +=item set_name + +=item set_cacert + +=item set_icon + +=item set_url + +=item set_metadata + +=item set_expires + +=item set_isactive + +=item set_userregexp + +=item set_groups + +=item set_saml_extern_id_attr + +=item set_ldap_extern_id_attr + +=item set_ldap_mail_attrs + +=back + |