#!/usr/bin/env perl use strict; use warnings; use v5.10; use DateTime::Format::ISO8601; use File::Basename; use Net::IP; use POSIX qw(strftime); use Socket; use utf8; use ACU::API::Projects; use ACU::API::Submission; use ACU::LDAP; use ACU::Log; $ACU::Log::log_file = "/var/log/hooks/" . basename($0) . ".log"; use ACU::Process; my ($ref, $oldsha, $newsha) = @ARGV; my $promo; my $id_project; my $repo_login; my @apping = qw(zinger_a zebard_w zanell_a yao_p vinois_a sraka_y soupam_j seck_a ngomsi_s morin_h milis_e menkar_m eusebe_r crief_a chhum_s boumra_n blemus_a bengan_l amasho_a); my @salonD = qw(aniss_i bogalh_j boulea_b cloare_l elhach_h gabrie_j kaplan_p manuel_c palson_c pizzin_a wajntr_a); my @salonS = qw(allio_a cadet_l digius_p drouin_n dubois_d dupuis_a langre_m lim_j); # First, extract information, from config then guess from repository adress if (my $tmp = `git config hooks.promo`) { chomp $tmp; $promo = $tmp; } if (my $tmp = `git config hooks.idproject`) { chomp $tmp; $id_project = $tmp; } if (my $tmp = `git config hooks.login`) { chomp $tmp; $repo_login = $tmp; } $promo = $1 if (!$promo && $ENV{'GL_REPO'} =~ m/([0-9]{4}).*/); $id_project = $1 if (!$id_project && $ENV{'GL_REPO'} =~ m/.*\/(.*)\//); $repo_login = $1 if (!$repo_login && $ENV{'GL_REPO'} =~ m/.*\/.*\/(.*)/); exit(0) if (!$promo || !$id_project || !$repo_login); if ($ref =~ m<^refs/tags/ACU-(.+)$>) { my $tag = $1; log DEBUG, "Pushed tag for repository $ENV{GL_REPO}: $tag with IP $ENV{'SSH_CLIENT'}"; # Disallow no ACU if ($ENV{GL_USER} ne "frotti_b" && $ENV{GL_USER} ne "chen_a" && $ENV{GL_USER} ne "boisse_r" && $ENV{GL_USER} ne "genite_n" && $ENV{GL_USER} ne "mercie_d") { log ERROR, "Vous n'êtes pas autorisé à envoyer ce tag."; exit(9); } my $project = get_project_info($tag); # Extract matching tag my @rendus = grep { exists $_->{vcs} and $_->{vcs}{tag} eq $tag; } @{ $project->{submissions} }; if (! @rendus) { log ERROR, "$tag n'est pas un tag valide."; exit(8); } } elsif ($ref =~ m<^refs/tags/(.+)$>) { my $tag = $1; log DEBUG, "Pushed tag for repository $ENV{GL_REPO}: $tag with IP $ENV{'SSH_CLIENT'}"; my $project = get_project_info($tag); # Extract matching tag my @rendus = grep { exists $_->{vcs} and $_->{vcs}{tag} eq $tag; } @{ $project->{submissions} }; if (@rendus) { if ($newsha eq '0' x 40) { log USAGE, "Mais pour quelle raison voudriez-vous supprimer un tag ?!"; exit(7); } chomp (my $tokengiven = `git cat-file tag $newsha 2> /dev/null | sed -e '1,/^\$/d'`); if (! check_submission_date($tokengiven, @rendus)) { exit (9); } } else { log ERROR, "$tag n'est pas un tag valide."; exit(8) } } exit 0; sub get_project_info { my $project; eval { $project = API::Projects::get($id_project, $promo); }; if ($@ or !$project) { my $err = $@; log TRACE, $err; log ERROR, "Impossible d'envoyer de tags ; si le problème persiste, passez au laboratoire."; exit(1); } log TRACE, $project; return $project; } sub check_submission_date { my $tokengiven = shift; my $glts = DateTime::Format::ISO8601->parse_datetime( do { my $t = $ENV{'GL_TS'}; $t =~ tr/./T/; $t }); for my $rendu (@_) { my $open = DateTime::Format::ISO8601->parse_datetime($rendu->{period}{begin}); my $close = DateTime::Format::ISO8601->parse_datetime($rendu->{period}{end}); # if ($id_project eq "atelier-cpp-j4" && grep { $_ eq $repo_login } @apping) if ($id_project eq "raytracer" && "dubois_d" eq $repo_login) { # $open = DateTime::Format::ISO8601->parse_datetime("2013-12-06T00:00:00"); $close = DateTime::Format::ISO8601->parse_datetime("2013-12-08T18:42:00"); } say "Date courante : ", $glts->strftime("%d/%m/%Y %H:%M:%S"); if (DateTime->compare($glts, $open) == -1) { say "Date d'ouverture : ", $open->strftime("%d/%m/%Y %H:%M:%S"); log ERROR, "Tag rejeté : le rendu n'est pas encore ouvert."; exit(4); } say "Date de fermeture : ", $close->strftime("%d/%m/%Y %H:%M:%S"); if (DateTime->compare($glts, $close) == 1) { log ERROR, "Tag rejeté : le rendu est clos."; exit(5); } my $token = $rendu->{vcs}{token}; if ($token ne "" and $token ne $tokengiven and $newsha ne '0' x 40) { log ERROR, "Tag rejeté : mauvais token."; exit(6); } } return 1; }