initial commit of file from CVS for smeserver-git on Sat Sep 7 19:54:49 AEST 2024

This commit is contained in:
Trevor Batley
2024-09-07 19:54:49 +10:00
parent 46c8cfc0e8
commit 84e108d7e3
51 changed files with 9398 additions and 2 deletions

View 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 = '&nbsp;' . $q->a({href => "${href}GitCreateModify"},$modify) . '&nbsp;';
my $actionRemove = '&nbsp;' . $q->a({href => "${href}GitRemove"}, $remove) . '&nbsp';
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;

View 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;
}