package LATMOS::Accounts::Bases::Sql::Group; use 5.010000; use strict; use warnings; use base qw(LATMOS::Accounts::Bases::Sql::objects); use LATMOS::Accounts::Log; our $VERSION = (q$Rev$ =~ /^Rev: (\d+) /)[0]; =head1 NAME LATMOS::Accounts::Bases::Sql::Group - Groups objects support =cut sub _object_table { 'group' } sub _key_field { 'name' } sub _has_extended_attributes { 1 } sub _get_attr_schema { my ($class, $base) = @_; $class->SUPER::_get_attr_schema($base, { gidNumber => { inline => 1, uniq => 1, iname => 'gidnumber', mandatory => 1, }, gidnumber => { inline => 1, uniq => 1, hide => 1, }, exported => { inline => 1, }, name => { inline => 1, ro => 1 }, cn => { inline => 1, ro => 1, iname => 'name', }, create => { inline => 1, ro => 1 }, date => { inline => 1, ro => 1 }, memberUID => { monitored => 1, hide => 1, reference => 'user', multiple => 1, delayed => 1, ro => sub { $_[0] && (($_[0]->_get_c_field('sutype') ||'') =~ /^(jobtype|contrattype)$/ || $_[0]->_get_c_field('autoMemberFilter')) ? 1 : 0 }, }, member => { monitored => 1, reference => 'user', multiple => 1, delayed => 1, can_values => sub { $base->list_objects('user') }, ro => sub { $_[0] && (($_[0]->_get_c_field('sutype') ||'') =~ /^(jobtype|contrattype)$/ || $_[0]->_get_c_field('autoMemberFilter')) ? 1 : 0 }, }, sAMAccountName => { iname => 'name', ro => 1 }, groupname => { ro => 1 }, managedBy => { monitored => 1, reference => 'user', can_values => sub { my %uniq = map { $_ => 1 } grep { $_ } ($_[1] ? $_[1]->get_attributes('manager') : ()), $base->search_objects('user', 'active=*'); sort keys %uniq; }, }, managedAlsoBy => { monitored => 1, reference => 'user', multiple => 1, delayed => 1, can_values => sub { my %uniq = map { $_ => 1 } grep { $_ } ($_[1] ? $_[1]->get_attributes('manager') : ()), $base->search_objects('user', 'active=*'); sort keys %uniq; }, }, sutype => { reference => 'sutype', monitored => 1, }, autoMemberFilter => { multiple => 1, } } ) } sub get_field { my ($self, $field) = @_; for ($field) { /^(member|memberUID)$/ and do { my $sth = $self->db->prepare_cached( q{ select value from group_attributes join "group" on "group".ikey = group_attributes.okey join "user" on "user".name = group_attributes.value where "group".name = ? and attr = ? } . ($self->base->{wexported} ? '' : 'and "user".exported = true') ); $sth->execute($self->id, 'memberUID'); my @res; while (my $res = $sth->fetchrow_hashref) { push(@res, $res->{value}); } return \@res; }; } $self->SUPER::get_field($field); } sub _set_group_members { my ($self, $members) = @_; my %member; my $res = 0; foreach (@{ $self->get_field('memberUID') }) { $member{$_}{c} = 1; } foreach (ref $members ? @{ $members || []} : $members) { $_ or next; # avoid undef $member{$_}{n} = 1; } foreach (keys %member) { $member{$_}{c} && $member{$_}{n} and next; # no change ! my $user = $self->base->get_object('user', $_) or next; if ($member{$_}{n}) { my $sth = $self->db->prepare_cached( q{insert into group_attributes_users (value, attr, okey) values (?,?,?)} ); $sth->execute($_, 'memberUID', $self->_get_ikey); $res++; } elsif ($member{$_}{c}) { if (($user->get_c_field('department') || '') eq $self->id) { $self->base->log(LA_WARN, "Don't removing user %s from group %s: is it's department", $user->id, $self->id); next; } my $sth = $self->db->prepare_cached( q{delete from group_attributes_users where value = ? and attr = ? and okey = ?} ); $sth->execute($_, 'memberUID', $self->_get_ikey); $res++; } # else {} # can't happend } return $res; } sub set_fields { my ($self, %data) = @_; my %fdata; my $res = 0; foreach my $attr (keys %data) { $attr =~ /^memberUID|member$/ and do { if (($self->_get_c_field('sutype') ||'') =~ /^(jobtype|contrattype)$/ || $self->get_field('autoMemberFilter')) { $self->base->log(LA_WARN, "Group %s is managed, ignoring member set request", $self->id); next; } $res += $self->_set_group_members($data{$attr}); next; }; $fdata{$attr} = $data{$attr}; } if (keys %fdata) { my $setres = $self->SUPER::set_fields(%fdata); if (exists($fdata{autoMemberFilter})) { $res += $self->populate_dyn_group; } return unless(defined($setres)); $res += ($setres || 0); } $res } =head2 populate_dyn_group Synchronise group's members according filter set into C attribute. =cut sub populate_dyn_group { my ($self) = @_; if (!$self->get_field('autoMemberFilter')) { return 0; } $self->base->log(LA_DEBUG, "Populating group %s from autoMemberFilter attribute", $self->id ); my $filter = $self->get_field('autoMemberFilter'); $self->_set_group_members( [ $self->base->search_objects( 'user', ref $filter ? @{ $filter } : $filter ) ] ) } 1; __END__ =head1 SEE ALSO L =head1 AUTHOR Olivier Thauvin, Eolivier.thauvin@latmos.ipsl.frE =head1 COPYRIGHT AND LICENSE Copyright (C) 2008, 2009 CNRS SA/CETP/LATMOS This library is free software; you can redistribute it and/or modify it under the same terms as Perl itself, either Perl version 5.10.0 or, at your option, any later version of Perl 5 you may have available. =cut