<?php
require_once(__DIR__ . '/user.inc.php');
require_once(__DIR__ . '/repo.inc.php');
require_once(__DIR__ . '/workers.inc.php');
/*
* Event functions
*/
$rg_admin_functions = array(
6000 => "rg_admin_invite",
6001 => "rg_admin_invite_one",
// new new style
'admin_invite' => 'rg_admin_invite',
'admin_invite_one' => 'rg_admin_invite_one',
'admin_mails_users' => 'rg_admin_mails_users',
'admin_mails_users_one' => 'rg_admin_mails_users_one',
);
rg_event_register_functions($rg_admin_functions);
/*
* Event for invites (one e-mail version)
*/
function rg_admin_invite_one($db, $event)
{
global $rg_admin_email, $rg_admin_name;
$admin_name = "=?UTF-8?B?"
. base64_encode($rg_admin_name) . "?=";
$rg = array();
$subject = str_replace('{NAME}', $event['name'], $event['subject']);
$subject = "=?UTF-8?B?" . base64_encode(trim($subject)) . "?=";
$header = rg_template("mail/common.head.txt", $rg, FALSE /*xss*/);
$header = trim($header);
$header .= "\nFrom: $admin_name <" . $rg_admin_email . ">";
rg_log_debug('header=' . $header);
$body = str_replace('{NAME}', $event['name'], $event['body']);
$r = mail($event['email'], $subject, $body, $header,
"-f $rg_admin_email");
if ($r === FALSE)
return FALSE;
return array();
}
/*
* Event for invites
*/
function rg_admin_invite($db, $event)
{
$ret = array();
rg_log_debug('event[list]=' . print_r($event['list'], TRUE));
foreach ($event['list'] as $line) {
$line = trim($line);
if (empty($line))
continue;
$t = explode('|', $line, 2);
$ret[] = array_merge($event,
array(
'category' => 'admin_invite_one',
'source' => 'admin_invite',
'prio' => 100,
'email' => trim($t[0]),
'name' => trim($t[1])
)
);
}
return $ret;
}
/*
* Event for mails/users (one e-mail version)
*/
function rg_admin_mails_users_one($db, $ev)
{
global $rg_admin_email, $rg_admin_name;
rg_log_debug('admin_mails_users_one: ev: ' . rg_array2string_short($ev));
$admin_name = '=?UTF-8?B?'
. base64_encode($rg_admin_name) . '?=';
$rg = array();
$subject = '=?UTF-8?B?' . base64_encode(trim($ev['subject'])) . '?=';
$header = rg_template('mail/common.head.txt', $rg, FALSE /*xss*/);
$header = trim($header);
$header .= "\n" . 'From: ' . $admin_name . ' <' . $rg_admin_email . '>';
rg_log_debug('header=' . $header);
$r = mail($ev['email'], $subject, $ev['body'], $header,
'-f ' . $rg_admin_email);
if ($r === FALSE)
return FALSE;
return array();
}
/*
* Event for mails/users
* TODO: add also the 'plan' field
* TODO: Make the filtering a generic function
*/
function rg_admin_mails_users($db, $ev)
{
$ret = array();
//rg_log_debug('admin_mails_users: ev: ' . rg_array2string_short($ev);
$sql = 'SELECT uid, username, email, disk_used_mb'
. ', git_mb, artifacts_mb, realname'
. ' FROM users'
. ' WHERE deleted = 0';
if ($ev['f']['conf'] == 0)
$sql .= ' AND confirmed > 0';
else if ($ev['f']['conf'] == 1)
$sql .= ' AND confirmed > 0';
if ($ev['f']['admin'] != 2)
$sql .= ' AND is_admin = ' . $ev['f']['admin'];
if ($ev['f']['suspended'] == 0)
$sql .= ' AND suspended = 0';
else if ($ev['f']['suspended'] == 1)
$sql .= ' AND suspended > 0';
if ($ev['f']['total_usage'] > 0)
$sql .= ' AND disk_used_mb >= ' . $ev['f']['total_usage'];
if ($ev['f']['artifact'] > 0)
$sql .= ' AND artifacts_mb >= ' . $ev['f']['artifact'];
if ($ev['f']['git'] > 0)
$sql .= ' AND git_mb <= ' . $ev['f']['git'];
$res = rg_sql_query($db, $sql);
if ($res === FALSE)
return FALSE;
$u = array();
while (($row = rg_sql_fetch_array($res))) {
if (!empty($ev['f']['username_filter'])
&& @preg_match('/' . $ev['f']['username_filter'] . '/uD', $row['username']) === 0)
continue;
if (!empty($ev['f']['email_filter'])
&& @preg_match('/' . $ev['f']['email_filter'] . '/uD', $row['email']) === 0)
continue;
$uid = $row['uid']; unset($row['uid']);
$row['no_of_repos'] = 0;
$row['no_of_webhooks'] = 0;
if (empty($row['realname']))
$row['realname'] = $row['username'];
$u[$uid] = $row;
}
rg_sql_free_result($res);
if ($ev['f']['repo'] == 1) {
$uids = array();
foreach ($u as $i)
$uids[] = $i['uid'];
$sql = 'SELECT uid FROM repos'
. ' WHERE uid IN (' . implode(',', $uids) . ')';
$res = rg_sql_query($db, $sql);
if ($res === FALSE)
return FALSE;
while (($row = rg_sql_fetch_array($res)))
$u[$row['uid']]['no_of_repos']++;
rg_sql_free_result($res);
foreach ($u as $uid => $i) {
if ($i['no_of_repos'] == 0)
unset($u[$uid]);
}
}
if ($ev['f']['webhook'] == 1) {
$uids = array();
foreach ($u as $i)
$uids[] = $i['uid'];
$sql = 'SELECT uid FROM webhooks'
. ' WHERE uid IN (' . implode(',', $uids) . ')';
$res = rg_sql_query($db, $sql);
if ($res === FALSE)
return FALSE;
while (($row = rg_sql_fetch_array($res)))
$u[$row['uid']]['no_of_webhooks']++;
rg_sql_free_result($res);
foreach ($u as $uid => $i) {
if ($i['no_of_webhooks'] == 0)
unset($u[$uid]);
}
}
$subject = $ev['f']['subject'];
$body = $ev['f']['body'];
unset($ev['f']);
foreach ($u as $uid => $i) {
$k = array(); $v = array();
foreach ($i as $_k => $_v) {
$k[] = '/@@' . $_k . '@@/uU';
$v[] = $_v;
}
$ev['subject'] = preg_replace($k, $v, $subject);
$ev['body'] = preg_replace($k, $v, $body);
$ret[] = array_merge($ev,
array(
'category' => 'admin_mails_users_one',
'source' => 'admin_mails_users',
'prio' => 500,
'email' => $i['email'],
'name' => $i['realname']
)
);
}
return $ret;
}
/*
* Deals with mails to the users
*/
function rg_admin_mails_users_high_level($db, $rg)
{
rg_log_enter('admin_mails_users_high_level');
$ret = '';
$f = array();
$f['email_filter'] = '';
$f['username_filter'] = '';
$f['conf'] = 1;
$f['admin'] = 2;
$f['suspended'] = 0;
$f['repo'] = 0;
$f['webhook'] = 0;
$f['total_usage'] = 0;
$f['git'] = 0;
$f['artifact'] = 0;
$f['subject'] = '';
$f['body'] = '';
$errmsg = array();
$show_form = TRUE;
while (1) {
if (rg_var_int('doit') == 0)
break;
$f['username_filter'] = rg_var_str_nocr('f::username_filter');
$f['email_filter'] = rg_var_str_nocr('f::email_filter');
$f['conf'] = rg_var_uint('f::conf');
$f['admin'] = rg_var_uint('f::admin');
$f['suspended'] = rg_var_uint('f::suspended');
$f['repo'] = rg_var_uint('f::repo');
$f['webhook'] = rg_var_uint('f::webhook');
$f['total_usage'] = rg_var_uint('f::total_usage');
$f['git'] = rg_var_uint('f::git');
$f['artifact'] = rg_var_uint('f::artifact');
$f['subject'] = rg_var_str_nocr('f::subject');
$f['body'] = trim(rg_var_str('f::body'));
if (!rg_valid_referer()) {
$errmsg[] = 'invalid referer; try again';
break;
}
if (!rg_token_valid($db, $rg, 'admin_mails_users_hl', FALSE)) {
$errmsg[] = 'invalid token; try again';
break;
}
if (empty($f['subject'])) {
$errmsg[] = 'subject is empty';
break;
}
if (empty($f['body'])) {
$errmsg[] = 'body is empty';
break;
}
if (!empty($errmsg))
break;
$ev = array(
'category' => 'admin_mails_users',
'source' => 'admin_mails_users_high_level',
'prio' => 50,
'f' => $f);
$r = rg_event_add($db, $ev);
if ($r !== TRUE) {
$errmsg[] = 'cannot add event (' . rg_event_error() . ')';
break;
}
rg_event_signal_daemon('', 0);
$ret .= rg_template('admin/mails/users/queued.html', $rg, TRUE /*xss*/);
$show_form = FALSE;
break;
}
if ($show_form) {
$rg['f'] = $f;
// hints
$hints = array();
$hints[]['HTML:hint'] = rg_template('hints/admin/mails_users.html',
$rg, TRUE /*xss*/);
$rg['HTML:hints'] = rg_template_table('hints/list', $hints, $rg);
$rg['HTML:errmsg'] = rg_template_errmsg($errmsg);
$rg['rg_form_token'] = rg_token_get($db, $rg, 'admin_mails_users_hl');
$ret .= rg_template('admin/mails/users/form.html', $rg, TRUE /*xss*/);
}
rg_log_exit();
return $ret;
}
/*
* Deals with invites
*/
function rg_admin_mails_invites_high_level($db, $rg)
{
rg_log_enter('admin_mails_invites_high_level');
$ret = "";
$inv = array();
$inv['list'] = "";
$inv['subject'] = "";
$inv['body'] = "";
$errmsg = array();
$show_form = TRUE;
while (1) {
if (rg_var_int("doit") == 0)
break;
$inv['list'] = rg_var_str('inv::list');
$inv['subject'] = rg_var_str_nocr('inv::subject');
$inv['body'] = rg_var_str('inv::body');
while (isset($_FILES['inv::file'])) {
if (empty($_FILES['inv::file']['tmp_name']))
break;
rg_log_debug('we have a file uploaded: ' . print_r($_FILES, TRUE));
if ($_FILES['inv::file']['error'] !== UPLOAD_ERR_OK) {
$errmsg[] = "error in upload (1); try again";
break;
}
if (!is_uploaded_file($_FILES['inv::file']['tmp_name'])) {
$errmsg[] = "error in upload (2); try again";
break;
}
$inv['body'] = @file_get_contents($_FILES['inv::file']['tmp_name']);
if ($inv['body'] === FALSE) {
$errmsg[] = "error in upload (3); try again";
break;
}
break;
}
if (!rg_valid_referer()) {
$errmsg[] = "invalid referer; try again";
break;
}
if (!rg_token_valid($db, $rg, 'admin_invites_hl', FALSE)) {
$errmsg[] = "invalid token; try again";
break;
}
if (empty($inv['list'])) {
$errmsg[] = "list is empty";
break;
}
if (empty($inv['subject'])) {
$errmsg[] = "subject is empty";
break;
}
if (empty($inv['body'])) {
$errmsg[] = "body is empty";
break;
}
$list = explode("\n", trim($inv['list']));
foreach ($list as $line) {
$line = trim($line);
if (empty($line))
continue;
$t = explode('|', $line, 2);
if (count($t) != 2) {
$errmsg[] = 'invalid line: ' . rg_xss_safe($line);
} else {
if (!strstr($t[0], '@'))
$errmsg[] = 'invalid e-mail in line: ' . rg_xss_safe($line);
}
}
if (!empty($errmsg))
break;
$event = array(
'category' => 'admin_invite',
'source' => 'admin_mails_invites_high_level',
'prio' => 50
);
$event = array_merge($event, $inv);
$event['list'] = $list;
$r = rg_event_add($db, $event);
if ($r !== TRUE) {
$errmsg[] = "cannot add event (" . rg_event_error() . ")";
break;
}
rg_event_signal_daemon('', 0);
$ret .= rg_template("admin/invites/sent.html", $rg, TRUE /* xss */);
$show_form = FALSE;
break;
}
if ($show_form) {
$rg['inv'] = $inv;
$rg['HTML:errmsg'] = rg_template_errmsg($errmsg);
$rg['rg_form_token'] = rg_token_get($db, $rg, 'admin_invites_hl');
$ret .= rg_template("admin/invites/invites.html", $rg, TRUE /* xss */);
}
rg_log_exit();
return $ret;
}
/*
* Prepares an instalation for first use
*/
function rg_init($db, $rg)
{
rg_prof_start("rg_init");
rg_log_enter('init');
$ret = '';
$doit = rg_var_uint('doit');
if ($doit == 0) {
$rg['init']['username'] = 'admin';
$rg['init']['realname'] = '';
$rg['init']['email'] = '';
$rg['init']['pass'] = '';
$rg['init']['pass2'] = '';
$rg['init']['session_time'] = 600;
}
$errmsg = array();
$load_form = TRUE;
while ($doit == 1) {
$rg['init'] = array();
$rg['init']['uid'] = 0;
$rg['init']['is_admin'] = 1;
$rg['init']['rights'] = rg_rights_all('user');
$rg['init']['confirm_token'] = '';
$rg['init']['plan_id'] = 1;
$rg['init']['username'] = rg_var_str('init::username');
$rg['init']['realname'] = rg_var_str('init::realname');
$rg['init']['email'] = rg_var_str('init::email');
$rg['init']['pass'] = rg_var_str('init::pass');
$rg['init']['pass2'] = rg_var_str('init::pass2');
$rg['init']['session_time'] = rg_var_uint('init::session_time');
$rg['init']['confirmed'] = time(); /* = no need to confirm */
$rg['init']['last_ip'] = rg_ip();
if (!rg_valid_referer()) {
$errmsg[] = "invalid referer; try again";
break;
}
if (!rg_token_valid($db, $rg, 'init', FALSE)) {
$errmsg[] = "invalid token; try again";
break;
}
if (!strstr($rg['init']['email'], '@')) {
$errmsg[] = 'invalid e-mail';
break;
}
$r = rg_user_edit($db, $rg['init']);
if ($r === FALSE) {
$errmsg[] = rg_user_error();
break;
}
rg_state_set($db, 'first_install', time());
// Makes no sense to confirm the admin account
$rg['rg_account_email_confirm'] = 0;
$ret .= rg_template('user/create_ok.html', $rg, TRUE /*xss*/);
$load_form = FALSE;
break;
}
if ($load_form) {
$rg['HTML:errmsg'] = rg_template_errmsg($errmsg);
$rg['rg_form_token'] = rg_token_get($db, $rg, 'init');
$ret .= rg_template("admin/init.html", $rg, TRUE /* xss */);
}
rg_log_exit();
rg_prof_end("rg_init");
return $ret;
}
function rg_admin_report_order_desc($a, $b)
{
if ($a == $b)
return 0;
if ($a < $b)
return 1;
return -1;
}
/*
* Generate reports from 'conns' table
*/
function rg_admin_report_conns($db, $from, $to)
{
$ret = array('ok' => 0);
while (1) {
// Yesterday
$yesterday_text = '';
$y_start = gmmktime(0, 0, 0, gmdate('m'), gmdate('d') - 1, gmdate('Y'));
$y_end = gmmktime(0, 0, 0, gmdate('m'), gmdate('d'), gmdate('Y')) - 1;
$sql = 'SELECT * FROM conns'
. ' WHERE itime >= ' . $y_start
. ' AND itime <= ' . $y_end;
$res = rg_sql_query($db, $sql);
if ($res === FALSE) {
$ret['errmsg'] = rg_sql_error();
break;
}
$url = rg_base_url($db, '', '');
$x = explode('://', $url, 2);
$url = $x[1];
$list = array('type' => array('top' => 0),
'uid' => array('top' => 20),
'repo_id' => array('top' => 20),
'url' => array('top' => 20),
'cmd' => array('top' => 0),
'referer' => array('top' => 0),
'ip' => array('top' => 20),
'ua' => array('top' => 0)
);
foreach ($list as $k => $junk)
$ret[$k] = array();
$ret['count'] = 0;
$ret['sum_elap'] = 0;
while (($row = rg_sql_fetch_array($res))) {
$ret['count']++;
$ret['sum_elap'] += $row['elap'];
foreach ($list as $k => $i) {
$v = $row[$k];
if (strcmp($k, 'uid') == 0) {
if ($v == 0)
continue;
} else if (strcmp($k, 'repo_id') == 0) {
if ($v == 0)
continue;
$v = $row['uid'] . '/' . $row[$k];
} else if (strcmp($k, 'referer') == 0) {
if (stristr($v, $url))
continue;
}
if (!isset($ret[$k][$v]))
$ret[$k][$v] = 1;
else
$ret[$k][$v]++;
}
}
rg_sql_free_result($res);
if ($ret['count'] == 0) {
$ret['avg_elap'] = 0;
unset($ret['sum_elap']);
$ret['ok'] = 1;
break;
}
$ret['avg_elap'] = intval($ret['sum_elap'] / $ret['count']);
unset($ret['sum_elap']);
foreach ($list as $k => $i) {
uasort($ret[$k], 'rg_admin_report_order_desc');
$ret[$k] = rg_array_top($ret[$k], $i['top']);
}
$ret['ok'] = 1;
break;
}
return $ret;
}
/*
* Helper for rg_admin_report1 - suggestion report
*/
function rg_admin_report1_suggestions($db, $from, $to)
{
$ret = '';
// Total
$sql = "SELECT COUNT(*) AS total FROM suggestions";
$res = rg_sql_query($db, $sql);
if ($res === FALSE)
return FALSE;
$row = rg_sql_fetch_array($res);
$total = $row['total'];
rg_sql_free_result($res);
// Yesterday
$yesterday_text = '';
$y_start = gmmktime(0, 0, 0, gmdate('m'), gmdate('d') - 1, gmdate('Y'));
$y_end = gmmktime(0, 0, 0, gmdate('m'), gmdate('d'), gmdate('Y')) - 1;
$sql = "SELECT uid, suggestion FROM suggestions"
. " WHERE itime >= $y_start"
. " AND itime <= $y_end";
$res = rg_sql_query($db, $sql);
if ($res === FALSE)
return FALSE;
$count = 0;
$list = '';
while (($row = rg_sql_fetch_array($res))) {
$count++;
$list .= sprintf("%8u %s\n", $row['uid'], $row['suggestion']);
}
rg_sql_free_result($res);
$yesterday = $count;
if ($count)
$yesterday_text = "\nYesterday suggestions:\n" . $list;
$ret .= 'Total suggestions: ' . $total;
$ret .= "\nYesterday suggestions: " . $yesterday;
$ret .= $yesterday_text;
return $ret;
}
/*
* Report biggest repos
*/
function rg_admin_report_big_repos($db)
{
$ret = 'Biggest repos (name, owner, total, git, artifacts; MiB):' . "\n";
while (1) {
$sql = 'SELECT uid, name, disk_used_mb, git_mb, artifacts_mb'
. ' FROM repos'
. ' ORDER BY disk_used_mb DESC LIMIT 20';
$res = rg_sql_query($db, $sql);
if ($res === FALSE)
return FALSE;
while (($row = rg_sql_fetch_array($res))) {
$ui = rg_user_nice($db, $row['uid']);
$ret .= ' ' . $row['name']
. ' ' . $ui
. ' ' . $row['disk_used_mb']
. ' ' . $row['git_mb']
. ' ' . $row['artifacts_mb']
. "\n";
}
rg_sql_free_result($res);
break;
}
return $ret . "\n";
}
/*
* Report biggest disk users
*/
function rg_admin_report_big_users($db)
{
$ret = 'Biggest users (total, git, artifacts; MiB):' . "\n";
while (1) {
$sql = 'SELECT username, disk_used_mb, git_mb, artifacts_mb'
. ' FROM users'
. ' WHERE deleted = 0'
. ' ORDER BY disk_used_mb DESC LIMIT 20';
$res = rg_sql_query($db, $sql);
if ($res === FALSE)
return FALSE;
while (($row = rg_sql_fetch_array($res))) {
$ret .= ' ' . $row['username']
. ' ' . $row['disk_used_mb']
. ' ' . $row['git_mb']
. ' ' . $row['artifacts_mb']
. "\n";
}
rg_sql_free_result($res);
break;
}
return $ret . "\n";
}
/*
* Send some daily statistics to the admin
*/
function rg_admin_report1($db, $rg)
{
global $rg_admin_email;
global $rg_state_dir;
$body = '';
$site = rg_base_url($db, '', '');
$y_start = gmmktime(0, 0, 0, gmdate("m"), gmdate("d") - 1);
$y_end = gmmktime(0, 0, 0, gmdate("m"), gmdate("d")) - 1;
$body .= "Report between " . gmdate('Y-m-d H:i:s', $y_start)
. " and " . gmdate('Y-m-d H:i:s', $y_end) . " UTC\n";
$body .= 'For site ' . $site . "\n";
$body .= "\n";
foreach (array($rg_state_dir, '/') as $dir) {
$free = disk_free_space($dir);
$total = disk_total_space($dir);
$body .= $dir . ': total=' . rg_1024($total)
. ' free=' . rg_1024($free) . "\n";
}
$body .= "\n";
$g = array();
$list = array(
'users' => 'users',
'repos' => 'repositories',
'bugs' => 'bugs',
'bug_notes' => 'bug notes',
'repo_history' => 'repo history',
'keys' => 'keys',
'login_tokens' => 'login tokens',
'scratch_codes' => 'scratch codes',
'merge_requests' => 'merge requests',
'webhooks' => 'webhooks',
'rights' => 'rights',
'events' => 'events',
'build_jobs' => 'build jobs',
'apikeys' => 'api keys',
'workers' => 'workers',
'conns' => 'connection stats');
$total_yesterday_changes = 0;
$body .= "\n" . 'Yesterday' . "\t" . 'Total' . "\t" . 'Category' . "\n";
foreach ($list as $table => $text) {
$g[$table] = array();
// Yesterday
$sql = "SELECT COUNT(*) AS count FROM " . $table
. " WHERE itime >= $y_start"
. " AND itime <= $y_end";
$res = rg_sql_query($db, $sql);
if ($res === FALSE)
return FALSE;
$row = rg_sql_fetch_array($res);
$yesterday = $row['count'];
$total_yesterday_changes += $row['count'];
$g[$table]['yesterday'] = $yesterday;
rg_sql_free_result($res);
// Total
$sql = "SELECT COUNT(*) AS total FROM " . $table;
$res = rg_sql_query($db, $sql);
if ($res === FALSE)
return FALSE;
$row = rg_sql_fetch_array($res);
$total = $row['total'];
$g[$table]['total'] = $total;
rg_sql_free_result($res);
$body .= $yesterday . "\t\t" . $total . "\t" . $text . "\n";
}
$body .= "\nYesterday users:";
$sql = 'SELECT username, realname, email, last_ip FROM users'
. ' WHERE itime >= ' . $y_start
. ' AND itime <= ' . $y_end;
$res = rg_sql_query($db, $sql);
if ($res === FALSE)
return FALSE;
$body .= "\n";
while (($row = rg_sql_fetch_array($res))) {
$body .= ' ' . $row['username']
. ' - ' . $row['realname']
. ' - ' . $row['email']
. ' [' . $row['last_ip'] . ']'
. "\n";
}
rg_sql_free_result($res);
$body .= "\nYesterday repos:";
$sql = 'SELECT name, uid, description, public FROM repos'
. ' WHERE itime >= ' . $y_start
. ' AND itime <= ' . $y_end;
$res = rg_sql_query($db, $sql);
if ($res === FALSE)
return FALSE;
$body .= "\n";
while (($row = rg_sql_fetch_array($res))) {
$u = rg_user_nice($db, $row['uid']);
$desc = mb_substr($row['description'], 0, 50) . '...';
$desc = preg_replace('/\s/', ' ', $desc);
$body .= ' ' . $row['name'] . ' - ' . $u . ' - ' . $desc
. ($row['public'] == 1 ? " (public)" : " (private)") . "\n";
}
rg_sql_free_result($res);
$sug = rg_admin_report1_suggestions($db, $y_start, $y_end);
if ($sug === FALSE)
return FALSE;
$body .= "\n" . $sug;
$body .= "\n\n";
$conns = rg_admin_report_conns($db, $y_start, $y_end);
if ($conns['ok'] != 1)
return FALSE;
unset($conns['ok']);
$body .= 'Number of conns entries: ' . $conns['count'] . "\n";
unset($conns['count']);
$body .= 'Average elap: ' . $conns['avg_elap'] . 'ms' . "\n\n";
unset($conns['avg_elap']);
//rg_log_debug('conns: ' . print_r($conns, TRUE));
foreach ($conns as $t => $i) {
$body .= 'Top for \'' . $t . '\':' . "\n";
foreach ($i as $k => $v) {
if (strcmp($t, 'repo_id') == 0) {
$q = explode('/', $k);
$k = rg_repo_nice($db, $q[1]) . ' (' . rg_user_nice($db, $q[0]) . ')';
} else if (strcmp($t, 'uid') == 0) {
$k = rg_user_nice($db, $k) . ' (' . $k . ')';
}
$k2 = !empty($k) ? $k : 'EMPTY';
$body .= ' ' . $v . ' ' . $k2 . "\n";
}
$body .= "\n";
}
$r = rg_admin_report_big_repos($db);
if ($r === FALSE)
return FALSE;
$body .= $r;
$r= rg_admin_report_big_users($db);
if ($r === FALSE)
return FALSE;
$body .= $r;
$rg['ui_login']['ignore_confirmed'] = 1;
$rg['ui_login']['email'] = $rg_admin_email;
$rg['mail'] = array();
$rg['mail']['subject'] = 'RocketGit report'
. ' [' . $g['users']['yesterday'] . 'u]'
. ' [' . $g['repos']['yesterday'] . 'r]'
. ' [' . $total_yesterday_changes . 'c]'
. ' (' . $site . ')';
$rg['mail']['body'] = $body;
$rg['ignore_debug'] = 1;
rg_mail_template("mail/admin/report1", $rg);
}
/*
* Function to clean the log files
* It is called by both crons (under apache and under rocketgit users)
*/
function rg_clean_logs($dir)
{
global $rg_logs_lifetime;
if ($rg_logs_lifetime == 0)
return;
$files = glob($dir . "/*.log");
if ($files === FALSE) {
rg_log("Cannot select logs for delete");
return FALSE;
}
$limit_ts = gmmktime(0, 0, 0, gmdate('m'), gmdate('d') - $rg_logs_lifetime);
$limit = gmdate("Ymd", $limit_ts);
//rg_log("limit_ts=$limit_ts limit=$limit");
foreach ($files as $file) {
$ymd = preg_replace('/.*-([0-9]*)\.log/', '$1', $file);
//rg_log("file=$file ymd=$ymd");
if ($ymd >= $limit)
continue;
//rg_log("Deleting old log file $file");
$r = unlink($file);
if ($r === FALSE)
rg_log("Cannot delete file $file!");
}
}
/*
* Admin ->Settings -> Web menu
*/
function rg_admin_settings_web($db, $rg)
{
rg_log_enter('admin_settings_web');
$ret = '';
$errmsg = array();
$hints = array();
while ($rg['doit'] == 1) {
if (!rg_valid_referer()) {
$errmsg[] = 'invalid referer; try again';
break;
}
if (!rg_token_valid($db, $rg, 'admin_settings_web', FALSE)) {
$errmsg[] = 'invalid token; try again';
break;
}
$hostname = rg_var_str('hostname');
$http_allow = rg_var_uint('http_allow');
$https_allow = rg_var_uint('https_allow');
if (($http_allow == 0) && ($https_allow == 0)) {
$errmsg[] = 'you must enable at least one of HTTP/HTTPS';
break;
}
$r = rg_state_set($db, 'hostname', $hostname);
if ($r === FALSE) {
$errmsg[] = 'cannot set state; try again';
break;
}
$r = rg_state_set($db, 'http_allow', $http_allow);
if ($r === FALSE) {
$errmsg[] = 'cannot set state; try again';
break;
}
$r = rg_state_set($db, 'https_allow', $https_allow);
if ($r === FALSE) {
$errmsg[] = 'cannot set state; try again';
break;
}
$rg['hostname'] = $hostname;
$rg['http_allow'] = $http_allow;
$rg['https_allow'] = $https_allow;
$ret .= rg_template('admin/settings/ok.html',
$rg, TRUE /*xss*/);
break;
}
// Load defaults
while (1) {
// Data is already in $rg
break;
}
$hints[]['HTML:hint'] = rg_template('admin/settings/web/hints.html',
$rg, TRUE /*xss*/);
$rg['HTML:hints'] = rg_template_table('hints/list', $hints, $rg);
$rg['HTML:errmsg'] = rg_template_errmsg($errmsg);
$rg['rg_form_token'] = rg_token_get($db, $rg, 'admin_settings_web');
$ret .= rg_template('admin/settings/web/main.html', $rg, TRUE /*xss*/);
rg_log_exit();
return $ret;
}
/*
* Admin ->Settings -> Limits menu
*/
function rg_admin_settings_limits($db, $rg)
{
rg_log_enter('admin_settings_limits');
$ret = '';
$errmsg = array();
$hints = array();
while ($rg['doit'] == 1) {
if (!rg_valid_referer()) {
$errmsg[] = 'invalid referer; try again';
break;
}
if (!rg_token_valid($db, $rg, 'admin_settings_limits', FALSE)) {
$errmsg[] = 'invalid token; try again';
break;
}
$rg['period'] = rg_var_uint('period');
$rg['max'] = rg_var_uint('max');
$r = rg_state_set($db, 'rate_limit_period', $rg['period']);
if ($r === FALSE) {
$errmsg[] = 'cannot set state; try again';
break;
}
$r = rg_state_set($db, 'rate_limit_max', $rg['max']);
if ($r === FALSE) {
$errmsg[] = 'cannot set state; try again';
break;
}
$ret .= rg_template('admin/settings/ok.html',
$rg, TRUE /*xss*/);
break;
}
// Load defaults
while (1) {
$rg['period'] = rg_state_get_uint($db, 'rate_limit_period');
$rg['max'] = rg_state_get_uint($db, 'rate_limit_max');
if (($rg['period'] === FALSE) || ($rg['max'] === FALSE)) {
$errmsg[] = 'cannot get state; try again';
break;
}
break;
}
$hints[]['HTML:hint'] = rg_template('admin/settings/limits/hints.html',
$rg, TRUE /*xss*/);
$rg['HTML:hints'] = rg_template_table('hints/list', $hints, $rg);
$rg['HTML:errmsg'] = rg_template_errmsg($errmsg);
$rg['rg_form_token'] = rg_token_get($db, $rg, 'admin_settings_limits');
$ret .= rg_template('admin/settings/limits/main.html', $rg, TRUE /*xss*/);
rg_log_exit();
return $ret;
}
/*
* Admin ->Settings -> SSH menu
*/
function rg_admin_settings_ssh($db, $rg)
{
global $rg_max_ssh_keys;
rg_log_enter('admin_settings_ssh');
$list = array('max_ssh_keys', 'ssh_key_min_bits_rsa',
'ssh_key_allow_dsa', 'ssh_key_min_bits_ecdsa',
'AuthorizedKeysCommand', 'fido2_security');
$ret = '';
$errmsg = array();
$hints = array();
while ($rg['doit'] == 1) {
if (!rg_valid_referer()) {
$errmsg[] = 'invalid referer; try again';
break;
}
if (!rg_token_valid($db, $rg, 'admin_settings_ssh', FALSE)) {
$errmsg[] = 'invalid token; try again';
break;
}
$err = FALSE;
foreach ($list as $k) {
$v = rg_var_uint($k);
$r = rg_state_set($db, $k, $v);
if ($r === FALSE) {
$err = TRUE;
break;
}
}
if ($err) {
$errmsg[] = 'cannot set state; try again';
break;
}
// Nobody will force the regeneration, so, do it here!
$ev = array(
'category' => 'rg_keys_event_regen',
'source' => 'admin_settings_ssh',
'prio' => 10,
'source' => 'admin_settings_ssh'
);
$r = rg_event_add($db, $ev);
if ($r !== TRUE) {
$errmsg[] = 'cannot add event';
break;
}
$ret .= rg_template('admin/settings/ok.html',
$rg, TRUE /*xss*/);
break;
}
// Load defaults
while (1) {
$err = FALSE;
foreach ($list as $k) {
$r = rg_state_get_uint($db, $k);
if ($r === FALSE) {
$err = TRUE;
break;
}
$rg[$k] = $r;
}
if ($err) {
$ret = rg_template('admin/settings/load_err.html',
$rg, TRUE /*xss*/);
break;
}
$hints[]['HTML:hint'] = rg_template('admin/settings/ssh/hints.html',
$rg, TRUE /*xss*/);
$rg['HTML:hints'] = rg_template_table('hints/list', $hints, $rg);
$rg['HTML:errmsg'] = rg_template_errmsg($errmsg);
$rg['rg_form_token'] = rg_token_get($db, $rg,
'admin_settings_ssh');
$ret .= rg_template('admin/settings/ssh/main.html',
$rg, TRUE /*xss*/);
break;
}
rg_log_exit();
return $ret;
}
/*
* Admin ->Settings -> Git menu
*/
function rg_admin_settings_git($db, $rg)
{
global $rg_git_patch_limit_default;
rg_log_enter('admin_settings_git');
$ret = '';
$errmsg = array();
$hints = array();
while ($rg['doit'] == 1) {
if (!rg_valid_referer()) {
$errmsg[] = 'invalid referer; try again';
break;
}
if (!rg_token_valid($db, $rg, 'admin_settings_git', FALSE)) {
$errmsg[] = 'invalid token; try again';
break;
}
$v = rg_var_uint('git_patch_limit');
$r = rg_state_set($db, 'git_patch_limit', $v);
if ($r === FALSE) {
$errmsg[] = 'cannot set state; try again';
break;
}
$ret .= rg_template('admin/settings/ok.html',
$rg, TRUE /*xss*/);
break;
}
// Load defaults
while (1) {
$r = rg_state_get_uint($db, 'git_patch_limit');
if ($r === FALSE) {
$ret = rg_template('admin/settings/load_err.html',
$rg, TRUE /*xss*/);
break;
}
if ($r == 0)
$r = $rg_git_patch_limit_default;
$rg['git_patch_limit'] = $r;
$hints[]['HTML:hint'] = rg_template('admin/settings/git/hints.html',
$rg, TRUE /*xss*/);
$rg['HTML:hints'] = rg_template_table('hints/list', $hints, $rg);
$rg['HTML:errmsg'] = rg_template_errmsg($errmsg);
$rg['rg_form_token'] = rg_token_get($db, $rg,
'admin_settings_git');
$ret .= rg_template('admin/settings/git/main.html',
$rg, TRUE /*xss*/);
break;
}
rg_log_exit();
return $ret;
}
/*
* Deals with Admin -> Settings menu
*/
function rg_admin_settings($db, &$rg, $paras)
{
rg_log_enter('admin_settings');
$ret = '';
$_op = empty($paras) ? 'web' : array_shift($paras);
$rg['url_up'] = $rg['url'];
$rg['url'] .= '/' . rawurlencode($_op);
$rg['admin_settings_menu'][$_op] = 1;
$rg['HTML:menu_level2'] = rg_template('admin/settings/menu.html',
$rg, TRUE /*xss*/);
switch ($_op) {
case 'web':
$ret .= rg_admin_settings_web($db, $rg);
break;
case 'limits':
$ret .= rg_admin_settings_limits($db, $rg);
break;
case 'ssh':
$ret .= rg_admin_settings_ssh($db, $rg);
break;
case 'git':
$ret .= rg_admin_settings_git($db, $rg);
break;
default:
$ret .= rg_template('invalid_menu.html', $rg, TRUE /*xss*/);
break;
}
rg_log_exit();
return $ret;
}
/*
* Admin ->Settings -> Payments -> squareup
*/
function rg_admin_pay_squareup_high_level($db, $rg)
{
rg_log_enter('rg_admin_pay_squareup_high_level');
$ret = '';
$errmsg = array();
$hints = array();
while ($rg['doit'] == 1) {
if (!rg_valid_referer()) {
$errmsg[] = 'invalid referer; try again';
break;
}
if (!rg_token_valid($db, $rg, 'admin_pay_squareup_high_level', FALSE)) {
$errmsg[] = 'invalid token; try again';
break;
}
$bearer = rg_var_str('bearer');
$location_id = rg_var_str('location_id');
$r = rg_state_set($db, 'pay-squareup-bearer', $bearer);
if ($r === FALSE) {
$errmsg[] = 'cannot set state; try again';
break;
}
$r = rg_state_set($db, 'pay-squareup-location_id', $location_id);
if ($r === FALSE) {
$errmsg[] = 'cannot set state; try again';
break;
}
$rg['pay-squareup-bearer'] = $bearer;
$rg['pay-squareup-location_id'] = $location_id;
$ret .= rg_template('admin/pay/ok.html',
$rg, TRUE /*xss*/);
break;
}
// Load defaults
while (1) {
$rg['pay-squareup-bearer'] = rg_state_get($db, 'pay-squareup-bearer');
$rg['pay-squareup-location_id'] = rg_state_get($db, 'pay-squareup-location_id');
break;
}
//$hints[]['HTML:hint'] = rg_template('admin/pay/squareup-hints.html',
// $rg, TRUE /*xss*/);
$rg['HTML:hints'] = rg_template_table('hints/list', $hints, $rg);
$rg['HTML:errmsg'] = rg_template_errmsg($errmsg);
$rg['rg_form_token'] = rg_token_get($db, $rg, 'admin_pay_squareup_high_level');
$ret .= rg_template('admin/pay/squareup.html', $rg, TRUE /*xss*/);
rg_log_exit();
return $ret;
}