initial commit of file from CVS for smeserver-git on Sat Sep 7 19:54:49 AEST 2024
This commit is contained in:
967
root/usr/share/perl5/vendor_perl/esmith/FormMagick/Panel/git.pm
Executable file
967
root/usr/share/perl5/vendor_perl/esmith/FormMagick/Panel/git.pm
Executable file
@@ -0,0 +1,967 @@
|
||||
#!/usr/bin/perl -w
|
||||
#----------------------------------------------------------------------
|
||||
# vim: ft=perl ts=2 sw=2 et:
|
||||
#----------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2012 - Marco Hess <marco.hess@through-ip.com>
|
||||
#
|
||||
# This file is part of the "Git Repositories" panel in the
|
||||
# SME Server server-manager panel to configure git repositories.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#----------------------------------------------------------------------
|
||||
# $Id: git.pm 1 2012-03-23 11:25:58Z marco $
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::FormMagick::Panel::git;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
|
||||
use esmith::FormMagick;
|
||||
use esmith::AccountsDB;
|
||||
use esmith::ConfigDB;
|
||||
use esmith::DomainsDB;
|
||||
use esmith::GitDB;
|
||||
|
||||
use esmith::cgi;
|
||||
use esmith::util;
|
||||
use File::Basename;
|
||||
use Exporter;
|
||||
use Carp;
|
||||
|
||||
use constant TRUE => 1;
|
||||
use constant FALSE => 0;
|
||||
|
||||
our @ISA = qw(esmith::FormMagick Exporter);
|
||||
|
||||
our @EXPORT = qw(
|
||||
git_home_print_logo
|
||||
git_home_print_description
|
||||
git_home_print_configure_button
|
||||
git_home_print_add_repository_button
|
||||
git_home_print_repository_table
|
||||
git_handle_create_or_modify_repository
|
||||
git_handle_remove_repository
|
||||
git_repository_group_list
|
||||
git_repository_user_list
|
||||
git_repository_validate_name
|
||||
git_repository_validate_name_does_not_exist
|
||||
git_repository_validate_name_length
|
||||
git_repository_validate_description
|
||||
git_repository_print_name_field
|
||||
git_repository_print_description_note
|
||||
git_repository_print_access_note
|
||||
git_repository_print_privileges_note
|
||||
git_repository_print_groups_and_users
|
||||
max_repository_name_length
|
||||
get_config_value
|
||||
getExtraParams
|
||||
git_repository_print_save_or_add_button
|
||||
validate_radio
|
||||
wherenext
|
||||
);
|
||||
|
||||
our $config_db = esmith::ConfigDB->open
|
||||
or die "Can't open the Config database : $!\n" ;
|
||||
|
||||
our $account_db = esmith::AccountsDB->open
|
||||
or die "Can't open the Account database : $!\n" ;
|
||||
|
||||
our $domains_db = esmith::DomainsDB->open
|
||||
or die "Can't open the Domains database : $!\n" ;
|
||||
|
||||
our $git_db = esmith::GitDB->open
|
||||
or die "Can't open the Git database : $!\n" ;
|
||||
|
||||
our $SystemName = $config_db->get_prop('git','SystemName') || get_config_value('', 'SystemName');
|
||||
our $DomainName = $config_db->get_prop('git','DomainName') || get_config_value('', 'DomainName');
|
||||
our $server = $SystemName . "." . $DomainName ;
|
||||
|
||||
# fields and records separator for sub records
|
||||
use constant FS => "," ;
|
||||
use constant RS => ";" ;
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
=pod
|
||||
|
||||
=head1 NAME
|
||||
|
||||
esmith::FormMagick::Panels::git - Git
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use esmith::FormMagick::Panels::git
|
||||
|
||||
my $panel = esmith::FormMagick::Panel::git->new();
|
||||
$panel->display();
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module is the backend to the git panel, responsible
|
||||
for supplying all functions used by that panel. It is a subclass
|
||||
of esmith::FormMagick itself, so it inherits the functionality
|
||||
of a FormMagick object.
|
||||
|
||||
=cut
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# new()
|
||||
# Exactly as for esmith::FormMagick
|
||||
|
||||
sub new
|
||||
{
|
||||
my $proto = shift;
|
||||
my $class = ref($proto) || $proto;
|
||||
my $self = esmith::FormMagick::new($class);
|
||||
$self->{calling_package} = (caller)[0];
|
||||
|
||||
return $self;
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
### HTML GENERATION ROUTINES
|
||||
#######################################################################
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# git_home_print_logo()
|
||||
# Print the Git logo image with a link reference to http://git-scm.com
|
||||
|
||||
sub git_home_print_logo
|
||||
{
|
||||
my $self = shift;
|
||||
my $q = $self->{cgi};
|
||||
|
||||
print qq(<p><a href="http://git-scm.com" target="_blank"><img src="/server-common/git-logo.png" alt="GIT" style="float:right;margin:0 0 0 5px;" /></a></p>);
|
||||
return undef;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# git_home_print_description()
|
||||
|
||||
sub git_home_print_description
|
||||
{
|
||||
my $self = shift;
|
||||
my $q = $self->{cgi};
|
||||
|
||||
print qq(<tr>);
|
||||
print qq(<td><p>) . $self->localise('GIT_HOME_DESCRIPTION', {serverName => $server} ) . qq(</p></td>);
|
||||
print qq(<td><a href="http://git-scm.com" target="_blank"><img src="/server-common/git-logo.png" alt="GIT" style="float:right;margin:0 0 0 5px;" /></a></td>);
|
||||
print qq(</tr>);
|
||||
return undef;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# git_home_print_add_repository_button()
|
||||
# Prints a button to get to the add a new repository screen
|
||||
|
||||
sub git_home_print_add_repository_button
|
||||
{
|
||||
my $self = shift;
|
||||
my $q = $self->{cgi};
|
||||
|
||||
print qq(<tr><td colspan="2"><a class="button-like" href="git?page=0&page_stack=&Next=Next&wherenext=GitCreateModify">) . $self->localise('GIT_REPOSITORY_ADD_BUTTON') . qq(</a></td></tr>);
|
||||
return "";
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# git_home_print_configure_button()
|
||||
# Prints a button to get to the configuration screen
|
||||
|
||||
sub git_home_print_configure_button
|
||||
{
|
||||
my $self = shift;
|
||||
my $q = $self->{cgi};
|
||||
|
||||
print qq(<tr><td colspan="2"><a class="button-like" href="git?page=0&page_stack=&Next=Next&wherenext=GitConfigure">) . $self->localise('GIT_CONFIGURE_BUTTON') . qq(</a></td></tr>);
|
||||
return "";
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# git_home_print_repository_table()
|
||||
# This function displays a table of repositories on the system
|
||||
# including the links to modify and remove the repository
|
||||
|
||||
sub git_home_print_repository_table
|
||||
{
|
||||
my $self = shift;
|
||||
my $q = $self->{cgi};
|
||||
|
||||
my $name = $self->localise('GIT_REPOSITORY_NAME');
|
||||
my $description = $self->localise('DESCRIPTION');
|
||||
my $access = $self->localise('GIT_ALLOW_FROM');
|
||||
my $pull = $self->localise('GIT_PULL_ACCESS');
|
||||
my $push = $self->localise('GIT_PUSH_ACCESS');
|
||||
my $modify = $self->localise('MODIFY');
|
||||
my $remove = $self->localise('REMOVE');
|
||||
my $action_h = $self->localise('ACTION');
|
||||
|
||||
my @repositories = $git_db->get_all_by_prop('type' => 'repository');
|
||||
|
||||
unless( scalar @repositories )
|
||||
{
|
||||
print qq(<tr><td colspan="2"><p>) . $self->localise('GIT_NOTIFY_NO_REPOSITORIES') . qq(</a></td></tr>);
|
||||
return "";
|
||||
}
|
||||
|
||||
print qq(<tr><td colspan="2"><p>) . $self->localise('GIT_REPOSITORY_LIST_DESCRIPTION') . qq(</a></td></tr>);
|
||||
|
||||
print qq(<tr><td colspan="2">);
|
||||
print $q->start_table({-CLASS => "sme-border"}),"\n";
|
||||
print $q->Tr ( esmith::cgi::genSmallCell($q, $name, "header"),
|
||||
esmith::cgi::genSmallCell($q, $description, "header"),
|
||||
esmith::cgi::genSmallCell($q, $access, "header"),
|
||||
esmith::cgi::genSmallCell($q, $pull, "header"),
|
||||
esmith::cgi::genSmallCell($q, $push, "header"),
|
||||
esmith::cgi::genSmallCell($q, $action_h, "header", 2) ), "\n";
|
||||
|
||||
my $scriptname = basename($0);
|
||||
|
||||
foreach my $repository (@repositories)
|
||||
{
|
||||
my $repo_name = $repository->key();
|
||||
my $repo_description = $repository->prop('description');
|
||||
my $repo_allow_access_from = $self->git_repository_access_allowed_from($repository->prop('allow_access_from'));
|
||||
|
||||
my $repo_pull = $self->git_repository_print_groups_and_users( $repository->prop('pull_groups'),
|
||||
$repository->prop('pull_users') );
|
||||
my $repo_push = $self->git_repository_print_groups_and_users( $repository->prop('push_groups'),
|
||||
$repository->prop('push_users') );
|
||||
|
||||
my $params = $self->build_repository_cgi_params($repo_name, $repository->props());
|
||||
my $href = "$scriptname?$params&action=modify&wherenext=";
|
||||
my $actionModify = ' ' . $q->a({href => "${href}GitCreateModify"},$modify) . ' ';
|
||||
my $actionRemove = ' ' . $q->a({href => "${href}GitRemove"}, $remove) . ' ';
|
||||
my $repo_url = $q->a({href => "https://" . $SystemName . "."
|
||||
. $DomainName . "/git/"
|
||||
. $repo_name . ".git" }, $repo_name . ".git" );
|
||||
|
||||
print $q->Tr ( esmith::cgi::genSmallCell($q, $repo_url, "normal"),
|
||||
esmith::cgi::genSmallCell($q, $repo_description, "normal"),
|
||||
esmith::cgi::genSmallCell($q, $repo_allow_access_from, "normal"),
|
||||
esmith::cgi::genSmallCell($q, $repo_pull, "normal"),
|
||||
esmith::cgi::genSmallCell($q, $repo_push, "normal"),
|
||||
esmith::cgi::genSmallCell($q, $actionModify, "normal"),
|
||||
esmith::cgi::genSmallCell($q, $actionRemove, "normal") ), "\n";
|
||||
}
|
||||
|
||||
print $q->end_table,"\n";
|
||||
print qq(</td></tr>);
|
||||
return "";
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# git_repository_print_privileges_note()
|
||||
# Screen: repository
|
||||
|
||||
sub git_repository_print_privileges_note
|
||||
{
|
||||
my $self = shift;
|
||||
my $q = $self->{cgi};
|
||||
|
||||
print qq(<tr><td colspan="2">) . $self->localise('GIT_PRIVILEGES_NOTE') . qq(</td></tr>);
|
||||
return "";
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# git_repository_print_save_or_add_button()
|
||||
# Prints the ADD button when a new repository is addded and the SAVE buttom
|
||||
# whem modifications are made.
|
||||
|
||||
sub git_repository_print_save_or_add_button
|
||||
{
|
||||
my ($self) = @_;
|
||||
my $action = $self->cgi->param("action") || '';
|
||||
|
||||
if( $action eq "modify" ) {
|
||||
$self->print_button("SAVE");
|
||||
} else {
|
||||
$self->print_button("ADD");
|
||||
}
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
# HELPER FUNCTIONS FOR THE PANEL
|
||||
#######################################################################
|
||||
#
|
||||
# Routines for modifying the database and signaling events
|
||||
# from the server-manager panel
|
||||
|
||||
=head2 build_repository_cgi_params($self, $repositoryName, %oldprops)
|
||||
|
||||
Constructs the parameters for the links in the repository table
|
||||
|
||||
=cut
|
||||
|
||||
sub build_repository_cgi_params
|
||||
{
|
||||
my ($self, $repositoryName, %oldprops) = @_;
|
||||
|
||||
#$oldprops{'description'} = $oldprops{Name};
|
||||
#delete $oldprops{Name};
|
||||
|
||||
my %props = (
|
||||
page => 0,
|
||||
page_stack => "",
|
||||
#".id" => $self->{cgi}->param('.id') || "",
|
||||
name => $repositoryName,
|
||||
#%oldprops
|
||||
);
|
||||
|
||||
return $self->props_to_query_string(\%props);
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
*wherenext = \&CGI::FormMagick::wherenext;
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# git_repository_group_list()
|
||||
# Returns a hash of groups for the Create/Modify screen's group
|
||||
# field's drop down list. It includes the special groups 'admin'
|
||||
# for administrators and 'shared' for everybody on the local system.
|
||||
|
||||
sub git_repository_group_list
|
||||
{
|
||||
my $self = shift;
|
||||
my @groups = $account_db->groups();
|
||||
|
||||
my %groups = ( admin => $self->localise('GIT_GROUP_ADMINISTRATORS') ." (admin)",
|
||||
shared => $self->localise('GIT_GROUP_EVERYBODY') ." (shared)" );
|
||||
|
||||
foreach my $group (@groups)
|
||||
{
|
||||
$groups{ $group->key() } = $group->prop('Description')." (".$group->key.")";
|
||||
}
|
||||
|
||||
return \%groups;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# git_repository_user_list()
|
||||
# Returns a hash of users for the Create/Modify screen's user field's
|
||||
# drop down list, It explicitly adds the special user 'admin' as this
|
||||
# user is not listed in the accounds database.
|
||||
|
||||
sub git_repository_user_list
|
||||
{
|
||||
my $self = shift;
|
||||
my @users = $account_db->users();
|
||||
my %users = ( admin => $self->localise('GIT_USER_ADMINISTRATOR') ." (admin)" );
|
||||
|
||||
foreach my $user (@users)
|
||||
{
|
||||
$users{ $user->key() } = $user->prop('LastName').", ". $user->prop('FirstName')." (". $user->key.")";
|
||||
}
|
||||
|
||||
return \%users;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
sub git_repository_print_name_field
|
||||
{
|
||||
my $self = shift;
|
||||
my $in = $self->{cgi}->param('name') || '';
|
||||
my $action = $self->{cgi}->param('action') || '';
|
||||
my $maxLength = $config_db->get_prop('git', 'maxNameLength' ) || '31';
|
||||
|
||||
if ($action eq 'modify' and $in) {
|
||||
my $repository = $git_db->get($in);
|
||||
print qq(<tr><td colspan="2">) . $self->localise('GIT_NAME_FIELD_MODIFY_DESC', {maxLength => $maxLength}) . qq(</td></tr>);
|
||||
print qq(<tr><td class="sme-noborders-label">) . $self->localise('NAME') . qq(</td>\n);
|
||||
print qq(
|
||||
<td class="sme-noborders-content">
|
||||
<input type="text" name="name" value="$in.git" disabled>
|
||||
<input type="hidden" name="action" value="modify">
|
||||
</td>
|
||||
);
|
||||
|
||||
# Read the values for each field from the git db and store
|
||||
# them in the cgi object so our form will have the correct
|
||||
# info displayed.
|
||||
my $q = $self->{cgi};
|
||||
if( $repository ) {
|
||||
$q->param(-name=>'description', -value=>$repository->prop('description'));
|
||||
$q->param(-name=>'allow_access_from', -value=>$repository->prop('allow_access_from'));
|
||||
$q->param(-name=>'pull_groups', -value=>join(FS, split(FS, $repository->prop('pull_groups'))));
|
||||
$q->param(-name=>'pull_users', -value=>join(FS, split(FS, $repository->prop('pull_users'))));
|
||||
$q->param(-name=>'push_groups', -value=>join(FS, split(FS, $repository->prop('push_groups'))));
|
||||
$q->param(-name=>'push_users', -value=>join(FS, split(FS, $repository->prop('push_users'))));
|
||||
}
|
||||
} else {
|
||||
print qq(<tr><td colspan="2">) . $self->localise('GIT_NAME_FIELD_CREATE_DESC', {maxLength => $maxLength}) . qq(</td></tr>);
|
||||
print qq(<tr><td class="sme-noborders-label">) . $self->localise('NAME') . qq(</td>\n);
|
||||
print qq(
|
||||
<td>
|
||||
<input type="text" name="name" value="$in">
|
||||
<input type="hidden" name="action" value="create">
|
||||
</td>
|
||||
);
|
||||
}
|
||||
print qq(</tr>\n);
|
||||
return undef;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# git_repository_print_description_note()
|
||||
# Screen: repository
|
||||
|
||||
sub git_repository_print_description_note
|
||||
{
|
||||
my $self = shift;
|
||||
my $q = $self->{cgi};
|
||||
|
||||
print qq(<tr><td colspan="2">) . $self->localise('GIT_DESCRIPTION_FIELD_DESC') . qq(</td></tr>);
|
||||
return "";
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# git_repository_print_access_note()
|
||||
# Screen: repository
|
||||
|
||||
sub git_repository_print_access_note
|
||||
{
|
||||
my $self = shift;
|
||||
my $q = $self->{cgi};
|
||||
|
||||
print qq(<tr><td colspan="2">) . $self->localise('GIT_ACCESS_FIELD_DESC') . qq(</td></tr>);
|
||||
return "";
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# get_config_value ITEM
|
||||
# A simple accessor for esmith::ConfigDB::Record::value
|
||||
|
||||
sub get_config_value
|
||||
{
|
||||
my $fm = shift;
|
||||
my $item = shift;
|
||||
my $record = $config_db->get($item);
|
||||
if ($record)
|
||||
{
|
||||
return $record->value();
|
||||
}
|
||||
else
|
||||
{
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
# git_repository_print_domains()
|
||||
|
||||
# When this server has more than one domain this function takes
|
||||
# the list of domains and returns a string of html checkboxes
|
||||
# for all these domains.
|
||||
|
||||
# Those domains that are listed with this git environment
|
||||
# will have their checkbox checked.
|
||||
|
||||
# sub git_repository_print_domains
|
||||
# {
|
||||
# # Retrieve the Git account name from the CGI parameters
|
||||
# my $self = shift;
|
||||
# my $name = $self->{'cgi'}->param('name');
|
||||
# my $action = $self->{'cgi'}->param("action") || '';
|
||||
# my $out = "";
|
||||
|
||||
# # Get a full list of all the domains on this server.
|
||||
# my @domains = $DomainsDB->get_all_by_prop( type => 'domain' );
|
||||
# my $numdomains = @domains;
|
||||
|
||||
# # If there is more than one domain, we generate a list
|
||||
# # of checkboxes. Otherwise we just show the primary domain.
|
||||
# if ($numdomains > 1) {
|
||||
|
||||
# # Get the list of the Domains for which Git is active.
|
||||
# my $git_domains_list = "";
|
||||
# if ($AccountsDB->get($name)) {
|
||||
# $git_domains_list = $AccountsDB->get($name)->prop('Domains');
|
||||
# }
|
||||
|
||||
# # Split the comma separated list into the individual bits.
|
||||
# my %git_domains;
|
||||
# foreach my $git_domain ( split ( /,/, $git_domains_list ) ) {
|
||||
# $git_domains{$git_domain} = 1;
|
||||
# }
|
||||
|
||||
# # Now generate the table of domains with a checkbox in front of it.
|
||||
# # If the domain is in our listed domains for Git, the
|
||||
# # checkbox will show checked.
|
||||
# $out = " <tr>\n";
|
||||
# $out .= " <td colspan=2>" . $fm->localise('GIT_FIELD_DOMAINS_DESCRIPTION') . "</td>";
|
||||
# $out .= " </tr>\n";
|
||||
# $out .= " <tr>\n";
|
||||
# $out .= " <td class=\"sme-noborders-label\">" . $fm->localise('GIT_FIELD_DOMAINS') . "</td>\n";
|
||||
# $out .= " <td>\n";
|
||||
# $out .= " <table border='0' cellspacing='0' cellpadding='0'>\n";
|
||||
# $out .= " <tr>\n";
|
||||
|
||||
# foreach my $domain (sort @domains) {
|
||||
# # If this is a ADD form, we default check all domains, otherwise only
|
||||
# # those that are in our Git configuration.
|
||||
# my $checked = "";
|
||||
# if ( $action eq 'modify' ) {
|
||||
# if ( $git_domains{ $domain->key() } ) {
|
||||
# $checked = "checked";
|
||||
# }
|
||||
# } else {
|
||||
# $checked = "checked";
|
||||
# }
|
||||
# $out .= " <tr>\n";
|
||||
# $out .= " <td><input type=\"checkbox\" name=\"gitDomains\" $checked value=\"" . $domain->key . "\"></td>\n";
|
||||
# $out .= " <td>" . $domain->key . "</td>\n";
|
||||
# $out .= " </tr>\n";
|
||||
# }
|
||||
|
||||
# $out .= " </table>\n";
|
||||
# $out .= " </td>\n";
|
||||
# $out .= " </tr>\n";
|
||||
# }
|
||||
# else
|
||||
# {
|
||||
# # We only have a single domain, so we just show this domain but without the
|
||||
# # checkbox (so it can't be unchecked).
|
||||
# my $domainname = $ConfigDB->get('DomainName')->value();
|
||||
# $out = " <tr>\n";
|
||||
# $out .= " <td colspan=2>" . $fm->localise('GIT_FIELD_DOMAIN_DESCRIPTION') . "</td>";
|
||||
# $out .= " </tr>\n";
|
||||
# $out .= " <tr>\n";
|
||||
# $out .= " <td class=\"sme-noborders-label\">" . $fm->localise('GIT_FIELD_DOMAIN') . "</td>\n";
|
||||
# $out .= " <td><input type=\"hidden\" name=\"tracDomains\" value=\"" . $domainname . "\">";
|
||||
# $out .= $domainname . "</td>\n";
|
||||
# $out .= " </tr>\n";
|
||||
# }
|
||||
|
||||
# return $out;
|
||||
# }
|
||||
|
||||
|
||||
#######################################################################
|
||||
# THE ROUTINES THAT ACTUALLY DO THE WORK
|
||||
#######################################################################
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# git_handle_configuration_update()
|
||||
|
||||
sub git_handle_configuration_update
|
||||
{
|
||||
my ($self) = @_;
|
||||
|
||||
if( system ( "/sbin/e-smith/signal-event", "git-modify" ) == 0 ) {
|
||||
$self->success("GIT_SUCCESS_CONFIGURATION_UPDATE");
|
||||
} else {
|
||||
$self->error("GIT_ERROR_CONFIGURATION_UPDATE");
|
||||
}
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# git_handle_create_or_modify_repository()
|
||||
# Determine whether to modify or add the git repository
|
||||
|
||||
sub git_handle_create_or_modify_repository
|
||||
{
|
||||
my ($self) = @_;
|
||||
|
||||
my $action = $self->cgi->param("action") || '';
|
||||
if( $action eq "create") {
|
||||
$self->git_handle_create_repository();
|
||||
} else {
|
||||
$self->git_handle_modify_repository();
|
||||
}
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# git_handle_create_repository()
|
||||
# Handle the create event for the git repository
|
||||
|
||||
sub git_handle_create_repository
|
||||
{
|
||||
my ($self) = @_;
|
||||
my $repositoryName = $self->cgi->param('name');
|
||||
my $msg;
|
||||
|
||||
$msg = $self->git_repository_validate_name($repositoryName);
|
||||
unless( $msg eq "OK" ) {
|
||||
return $self->error($msg);
|
||||
}
|
||||
|
||||
$msg = $self->git_repository_validate_name_length($repositoryName);
|
||||
unless( $msg eq "OK" ) {
|
||||
return $self->error($msg);
|
||||
}
|
||||
|
||||
$msg = $self->git_repository_validate_name_does_not_exist($repositoryName);
|
||||
unless( $msg eq "OK" ) {
|
||||
return $self->error($msg);
|
||||
}
|
||||
|
||||
$msg = $self->validate_radio($self->cgi->param('allow_access_from'));
|
||||
unless( $msg eq "OK" ) {
|
||||
return $self->error($msg);
|
||||
}
|
||||
|
||||
my $groups_allowed_to_pull = "";
|
||||
my @pull_groups = $self->cgi->param('pull_groups');
|
||||
foreach my $pull_group (@pull_groups) {
|
||||
if ($groups_allowed_to_pull) {
|
||||
$groups_allowed_to_pull .= "," . $pull_group;
|
||||
} else {
|
||||
$groups_allowed_to_pull = $pull_group;
|
||||
}
|
||||
}
|
||||
|
||||
my $users_allowed_to_pull = "";
|
||||
my @pull_users = $self->cgi->param('pull_users');
|
||||
foreach my $pull_user (@pull_users) {
|
||||
if ($users_allowed_to_pull) {
|
||||
$users_allowed_to_pull .= "," . $pull_user;
|
||||
} else {
|
||||
$users_allowed_to_pull = $pull_user;
|
||||
}
|
||||
}
|
||||
|
||||
my $groups_allowed_to_push = "";
|
||||
my @push_groups = $self->cgi->param('push_groups');
|
||||
foreach my $push_group (@push_groups) {
|
||||
if ($groups_allowed_to_push) {
|
||||
$groups_allowed_to_push .= "," . $push_group;
|
||||
} else {
|
||||
$groups_allowed_to_push = $push_group;
|
||||
}
|
||||
}
|
||||
|
||||
my $users_allowed_to_push = "";
|
||||
my @push_users = $self->cgi->param('push_users');
|
||||
foreach my $push_user (@push_users) {
|
||||
if( $users_allowed_to_push ) {
|
||||
$users_allowed_to_push .= "," . $push_user;
|
||||
} else {
|
||||
$users_allowed_to_push = $push_user;
|
||||
}
|
||||
}
|
||||
|
||||
# The new_record below will fail if the named repository already exists
|
||||
# which can be the case when the previous one was deleted but not properly
|
||||
# cleaned up.
|
||||
|
||||
if( my $repository = $git_db->new_record($repositoryName,
|
||||
{
|
||||
description => $self->cgi->param('description'),
|
||||
pull_groups => "$groups_allowed_to_pull",
|
||||
pull_users => "$users_allowed_to_pull",
|
||||
push_groups => "$groups_allowed_to_push",
|
||||
push_users => "$users_allowed_to_push",
|
||||
allow_access_from => $self->cgi->param('allow_access_from'),
|
||||
type => 'repository',
|
||||
} ) ) {
|
||||
# Untaint $name before use in system()
|
||||
$repositoryName =~ /(.+)/;
|
||||
$repositoryName = $1;
|
||||
if( system ("/sbin/e-smith/signal-event", "git-repository-create", $repositoryName) == 0 ) {
|
||||
$self->success("GIT_SUCCESS_CREATED_REPOSITORY");
|
||||
} else {
|
||||
$self->error("GIT_ERROR_CREATING_REPOSITORY");
|
||||
}
|
||||
} else {
|
||||
$self->error('GIT_ERROR_CANT_CREATE_REPOSITORY');
|
||||
}
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# git_handle_modify_repository()
|
||||
# Handle the modify event for the repository
|
||||
|
||||
sub git_handle_modify_repository
|
||||
{
|
||||
my ($self) = @_;
|
||||
my $repositoryName = $self->cgi->param('name');
|
||||
my $msg;
|
||||
|
||||
$msg = $self->git_repository_validate_name($repositoryName);
|
||||
unless ($msg eq "OK" ) {
|
||||
return $self->error($msg);
|
||||
}
|
||||
|
||||
$msg = $self->validate_radio($self->cgi->param('allow_access_from'));
|
||||
unless( $msg eq "OK" ) {
|
||||
return $self->error($msg);
|
||||
}
|
||||
|
||||
my $groups_allowed_to_pull = "";
|
||||
my @pull_groups = $self->cgi->param('pull_groups');
|
||||
foreach my $pull_group (@pull_groups) {
|
||||
if( $groups_allowed_to_pull ) {
|
||||
$groups_allowed_to_pull .= "," . $pull_group;
|
||||
} else {
|
||||
$groups_allowed_to_pull = $pull_group;
|
||||
}
|
||||
}
|
||||
|
||||
my $users_allowed_to_pull = "";
|
||||
my @pull_users = $self->cgi->param('pull_users');
|
||||
foreach my $pull_user (@pull_users) {
|
||||
if( $users_allowed_to_pull ) {
|
||||
$users_allowed_to_pull .= "," . $pull_user;
|
||||
} else {
|
||||
$users_allowed_to_pull = $pull_user;
|
||||
}
|
||||
}
|
||||
|
||||
my $groups_allowed_to_push = "";
|
||||
my @push_groups = $self->cgi->param('push_groups');
|
||||
foreach my $push_group (@push_groups) {
|
||||
if( $groups_allowed_to_push ) {
|
||||
$groups_allowed_to_push .= "," . $push_group;
|
||||
} else {
|
||||
$groups_allowed_to_push = $push_group;
|
||||
}
|
||||
}
|
||||
|
||||
my $users_allowed_to_push = "";
|
||||
my @push_users = $self->cgi->param('push_users');
|
||||
foreach my $push_user (@push_users) {
|
||||
if( $users_allowed_to_push ) {
|
||||
$users_allowed_to_push .= "," . $push_user;
|
||||
} else {
|
||||
$users_allowed_to_push = $push_user;
|
||||
}
|
||||
}
|
||||
|
||||
if( my $repository = $git_db->get($repositoryName) ) {
|
||||
if( $repository->prop('type') eq 'repository' ) {
|
||||
$repository->merge_props( description => $self->cgi->param('description'),
|
||||
pull_groups => "$groups_allowed_to_pull",
|
||||
pull_users => "$users_allowed_to_pull",
|
||||
push_groups => "$groups_allowed_to_push",
|
||||
push_users => "$users_allowed_to_push",
|
||||
allow_access_from => $self->cgi->param('allow_access_from'),
|
||||
type => 'repository',
|
||||
);
|
||||
|
||||
# Untaint $name before use in system()
|
||||
$repositoryName =~ /(.+)/;
|
||||
$repositoryName = $1;
|
||||
if( system ("/sbin/e-smith/signal-event", "git-repository-modify", $repositoryName) == 0 ) {
|
||||
$self->success("GIT_SUCCESS_MODIFIED_REPOSITORY");
|
||||
} else {
|
||||
$self->error("GIT_ERROR_MODIFYING_REPOSITORY");
|
||||
}
|
||||
} else {
|
||||
$self->error('GIT_ERROR_CANT_FIND_REPOSITORY');
|
||||
}
|
||||
} else {
|
||||
$self->error('GIT_ERROR_CANT_FIND_REPOSITORY');
|
||||
}
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# git_handle_remove_repository()
|
||||
# Handle the remove event for the repository
|
||||
|
||||
sub git_handle_remove_repository
|
||||
{
|
||||
my ($self) = @_;
|
||||
my $repositoryName = $self->cgi->param('name');
|
||||
if( my $repository = $git_db->get($repositoryName) ) {
|
||||
if( $repository->prop('type') eq 'repository' ) {
|
||||
$repository->set_prop('type', 'repository-deleted');
|
||||
|
||||
# Untaint $repository_name before use in system() ????
|
||||
$repositoryName =~ /(.+)/;
|
||||
$repositoryName = $1;
|
||||
if( system ("/sbin/e-smith/signal-event", "git-repository-delete", $repositoryName) == 0 ) {
|
||||
$self->success("GIT_SUCCESS_DELETED_REPOSITORY");
|
||||
$repository->delete();
|
||||
} else {
|
||||
$self->error("GIT_ERROR_DELETING_REPOSITORY");
|
||||
}
|
||||
} else {
|
||||
$self->error('GIT_ERROR_CANT_FIND_REPOSITORY');
|
||||
}
|
||||
} else {
|
||||
$self->error('GIT_ERROR_CANT_FIND_REPOSITORY');
|
||||
}
|
||||
$self->wherenext('First');
|
||||
}
|
||||
|
||||
#######################################################################
|
||||
# VALIDATION ROUTINES
|
||||
#######################################################################
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# getExtraParams()
|
||||
# Sets variables used in the lexicon to their required values.
|
||||
|
||||
sub getExtraParams
|
||||
{
|
||||
my $self = shift;
|
||||
my $q = $self->{cgi};
|
||||
my $repositoryName = $q->param('name');
|
||||
my $repositoryDescription = '';
|
||||
|
||||
if($repositoryName ) {
|
||||
my $repository = $git_db->get($repositoryName);
|
||||
if( $repository ) {
|
||||
$repositoryDescription = $repository->prop('description');
|
||||
}
|
||||
}
|
||||
return (name => $repositoryName, description => $repositoryDescription);
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# git_repository_validate_name()
|
||||
#
|
||||
# Checks that the name supplied does not contain any unacceptable chars.
|
||||
# Returns OK on success or a localised error message otherwise.
|
||||
|
||||
sub git_repository_validate_name
|
||||
{
|
||||
my( $self, $repositoryName ) = @_;
|
||||
unless( $repositoryName =~ /^([A-Za-z][.\_\-A-Za-z0-9]*)$/ ) {
|
||||
return $self->localise('GIT_ERROR_NAME_HAS_INVALID_CHARS',
|
||||
{repositoryName => $repositoryName});
|
||||
}
|
||||
return "OK";
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# git_repository_access_allowed_from()
|
||||
#
|
||||
# Checks that the name supplied does not contain any unacceptable chars.
|
||||
# Returns OK on success or a localised error message otherwise.
|
||||
|
||||
sub git_repository_access_allowed_from
|
||||
{
|
||||
my ($self, $accessAllowedFrom) = @_;
|
||||
|
||||
if( $accessAllowedFrom eq 'internet' ) {
|
||||
return $self->localise( 'GIT_ACCESS_ALLOWED_FROM_INTERNET' );
|
||||
} elsif( $accessAllowedFrom eq 'local' ) {
|
||||
return $self->localise( 'GIT_ACCESS_ALLOWED_FROM_LOCAL' );
|
||||
} else {
|
||||
return $self->localise( 'GIT_ACCESS_ALLOWED_FROM_CONFIG_ERROR' );
|
||||
}
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# git_repository_print_groups_and_users()
|
||||
#
|
||||
# Formats a print string for use in the repository table listing the groups and users
|
||||
# that are allowed access. Groups are printed in bold. When there are no groups or users
|
||||
# it returns Anonymous.
|
||||
|
||||
sub git_repository_print_groups_and_users
|
||||
{
|
||||
my ($self, $groups, $users) = @_;
|
||||
|
||||
unless( $groups || $users ) {
|
||||
return "<i>" . $self->localise( 'GIT_ANONYMOUS' ) . "</i>";
|
||||
}
|
||||
|
||||
my $print_groups = "";
|
||||
if( $groups ) {
|
||||
$print_groups = "<b>" . join("<br/>", split(FS, $groups)) . "</b><br/>";
|
||||
}
|
||||
|
||||
my $print_users = "";
|
||||
if( $users ) {
|
||||
$print_users = join("<br/>", split(FS, $users));
|
||||
}
|
||||
|
||||
return $print_groups . $print_users;
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# git_repository_validate_name_does_not_exist()
|
||||
# Check the proposed repository name for clashes with existing respositories.
|
||||
|
||||
sub git_repository_validate_name_does_not_exist
|
||||
{
|
||||
my( $self, $repositoryName ) = @_;
|
||||
my $repository = $git_db->get( $repositoryName );
|
||||
|
||||
if( defined $repository) {
|
||||
my $type = $repository->prop('type');
|
||||
if( $type eq "repository" ) {
|
||||
return $self->localise( 'GIT_ERROR_ALREADY_EXISTS', { repositoryName => $repositoryName } );
|
||||
}
|
||||
}
|
||||
# Repository does not exist yet.
|
||||
return 'OK';
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# git_repository_validate_name_length()
|
||||
#
|
||||
# Checks the length of a given repository name against the maximum set in the
|
||||
# maxAcctNameLength record of the configuration database. Defaults to a
|
||||
# maximum length of $self->{defaultMaxLength} if nothing is set in the
|
||||
# config db.
|
||||
sub git_repository_validate_name_length
|
||||
{
|
||||
my( $self, $data ) = @_;
|
||||
$config_db->reload();
|
||||
my $max;
|
||||
if( my $max_record = $config_db->get_prop( 'git', 'maxNameLength' ) ) {
|
||||
$max = $max_record;
|
||||
} else {
|
||||
$max = 31;
|
||||
}
|
||||
|
||||
if( length($data) <= $max ) {
|
||||
return "OK";
|
||||
} else {
|
||||
return $self->localise( "GIT_ERRROR_NAME_TOO_LONG",
|
||||
{ repositoryName => $data,
|
||||
maxRepositoryNameLength => $max } );
|
||||
}
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# git_repository_validate_description()
|
||||
#
|
||||
# Checks that the description supplied does not contain any unacceptable chars.
|
||||
# Returns OK on success or a localised error message otherwise.
|
||||
sub git_repository_validate_description
|
||||
{
|
||||
my( $self, $repositoryDescription ) = @_;
|
||||
unless( $repositoryDescription =~ /^([\w\s\_\.\-]*)$/ ) {
|
||||
return $self->localise('GIT_ERROR_DESCRIPTION_HAS_INVALID_CHARS',
|
||||
{ repositoryDescription => $repositoryDescription } );
|
||||
}
|
||||
return "OK";
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
# validate_radio()
|
||||
# Checks wether a value is checked for a radio button
|
||||
|
||||
sub validate_radio
|
||||
{
|
||||
my( $self, $acctName ) = @_;
|
||||
unless( $acctName ne '' ) {
|
||||
return $self->localise( 'GIT_ERROR_RADIO_VALUE_NOT_CHECKED',
|
||||
{ acctName => $acctName } );
|
||||
}
|
||||
return "OK";
|
||||
}
|
||||
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
1;
|
143
root/usr/share/perl5/vendor_perl/esmith/GitDB.pm
Executable file
143
root/usr/share/perl5/vendor_perl/esmith/GitDB.pm
Executable file
@@ -0,0 +1,143 @@
|
||||
#----------------------------------------------------------------------
|
||||
#
|
||||
# Copyright (C) 2012 - Marco Hess <marco.hess@through-ip.com>
|
||||
#
|
||||
# This file is part of the "Git Repositories" panel in the
|
||||
# SME Server server-manager panel to configure git repositories.
|
||||
#
|
||||
# This program is free software; you can redistribute it and/or modify
|
||||
# it under the terms of the GNU General Public License as published by
|
||||
# the Free Software Foundation; either version 2 of the License, or
|
||||
# (at your option) any later version.
|
||||
#
|
||||
# This program is distributed in the hope that it will be useful,
|
||||
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
# GNU General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with this program; if not, write to the Free Software
|
||||
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
#----------------------------------------------------------------------
|
||||
|
||||
package esmith::GitDB;
|
||||
|
||||
use strict;
|
||||
use warnings;
|
||||
use esmith::db;
|
||||
use esmith::AccountsDB;
|
||||
|
||||
use vars qw( $AUTOLOAD @ISA );
|
||||
|
||||
use esmith::DB::db;
|
||||
@ISA = qw(esmith::DB::db);
|
||||
|
||||
=head1 NAME
|
||||
|
||||
esmith::GitDB - interface to the Git respositories database
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
use esmith::GitDB;
|
||||
my $g = esmith::GitDB->open;
|
||||
|
||||
my @repos = $g->repositories();
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
This module provides an abstracted interface to the Git repositiries
|
||||
database. The Git repositories are maintained in a separate database
|
||||
so the Git repositories have their own name space and won't clash
|
||||
with the accounts database entries such as ibays, pseudonyms and users.
|
||||
|
||||
=cut
|
||||
|
||||
our $VERSION = sprintf '%d.%03d', q$Revision: 1.0 $ =~ /: (\d+).(\d+)/;
|
||||
|
||||
=head2 open()
|
||||
|
||||
Loads an existing git database and returns an esmith::GitDB
|
||||
object representing it.
|
||||
|
||||
=cut
|
||||
|
||||
sub open {
|
||||
my($class, $file) = @_;
|
||||
$file = $file || $ENV{ESMITH_GIT_DB} || "git";
|
||||
return $class->SUPER::open($file);
|
||||
}
|
||||
|
||||
sub open_ro {
|
||||
my($class, $file) = @_;
|
||||
$file = $file || $ENV{ESMITH_GIT_DB} || "git";
|
||||
return $class->SUPER::open_ro($file);
|
||||
}
|
||||
|
||||
sub AUTOLOAD {
|
||||
my $self = shift;
|
||||
my ($called_sub_name) = ($AUTOLOAD =~ m/([^:]*)$/);
|
||||
my @types = qw( repositories );
|
||||
if( grep /^$called_sub_name$/, @types ) {
|
||||
$called_sub_name =~ s/s$//g; # de-pluralize
|
||||
return $self->get_all_by_prop(type => qw( repository ));
|
||||
}
|
||||
}
|
||||
|
||||
sub effective_users_list_from {
|
||||
my($class,$groups1, $users1,$groups2, $users2) = @_;
|
||||
|
||||
### Generate effective list of users from the groups and individual users combined ###
|
||||
my @effective_users_list;
|
||||
|
||||
### Collect users listed for the named groups
|
||||
if( $groups1 || $groups2 ) {
|
||||
my @groups;
|
||||
if( $groups1 ) {
|
||||
push @groups, split ( /,/, $groups1 );
|
||||
}
|
||||
if( $groups2 ) {
|
||||
push @groups, split ( /,/, $groups2 );
|
||||
}
|
||||
my $accounts_db = esmith::AccountsDB->open_ro()
|
||||
or die( "Failed to open Accounts database : $!. The database file may not be readable by this user.\n" );
|
||||
foreach my $group (@groups) {
|
||||
if( $group eq 'admin' ) {
|
||||
push @effective_users_list, 'admin';
|
||||
} elsif( $group eq 'shared' ) {
|
||||
push @effective_users_list, $_->key foreach( $accounts_db->users() );
|
||||
} else {
|
||||
my $record = $accounts_db->get($group);
|
||||
if ($record) {
|
||||
my $members = $record->prop('Members') || "";
|
||||
if (length($members) > 0) {
|
||||
push @effective_users_list, split (/,/, $members);
|
||||
}
|
||||
}
|
||||
undef $record;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
### Combine individual users into the list generated so far
|
||||
if( $users1 ) {
|
||||
push @effective_users_list, split ( /,/, $users1 );
|
||||
}
|
||||
if( $users2 ) {
|
||||
push @effective_users_list, split ( /,/, $users2 );
|
||||
}
|
||||
|
||||
### When there is more than one entry, sort it
|
||||
if( @effective_users_list > 1 ) {
|
||||
@effective_users_list = sort(@effective_users_list);
|
||||
}
|
||||
|
||||
### Ensure we only have unique entries
|
||||
my $effective_users_list;
|
||||
my $prev = '';
|
||||
@effective_users_list = grep( $_ ne $prev && (($prev) = $_), @effective_users_list );
|
||||
$effective_users_list = join( " ", @effective_users_list ) || '';
|
||||
undef @effective_users_list;
|
||||
|
||||
return $effective_users_list;
|
||||
}
|
||||
|
Reference in New Issue
Block a user