Automatically close the registration when the admin is inactive

This commit is contained in:
Michael 2024-03-07 06:03:15 +00:00
parent 4834255acf
commit 4b695e361c
18 changed files with 49 additions and 35 deletions

View file

@ -251,7 +251,7 @@ class Nav
$nav['home'] = [$homelink, $this->l10n->t('Home'), '', $this->l10n->t('Home Page')]; $nav['home'] = [$homelink, $this->l10n->t('Home'), '', $this->l10n->t('Home Page')];
} }
if (intval($this->config->get('config', 'register_policy')) === \Friendica\Module\Register::OPEN && !$this->session->isAuthenticated()) { if (\Friendica\Module\Register::getPolicy() === \Friendica\Module\Register::OPEN && !$this->session->isAuthenticated()) {
$nav['register'] = ['register', $this->l10n->t('Register'), '', $this->l10n->t('Create an account')]; $nav['register'] = ['register', $this->l10n->t('Register'), '', $this->l10n->t('Create an account')];
} }

View file

@ -47,7 +47,7 @@ class Config extends BaseApi
'broughtby' => '', 'broughtby' => '',
'broughtbyurl' => '', 'broughtbyurl' => '',
'timezone' => DI::config()->get('system', 'default_timezone'), 'timezone' => DI::config()->get('system', 'default_timezone'),
'closed' => (DI::config()->get('config', 'register_policy') == Register::CLOSED), 'closed' => Register::getPolicy() === Register::CLOSED,
'inviteonly' => (bool)DI::config()->get('system', 'invitation_only'), 'inviteonly' => (bool)DI::config()->get('system', 'invitation_only'),
'private' => (bool)DI::config()->get('system', 'block_public'), 'private' => (bool)DI::config()->get('system', 'block_public'),
'textlimit' => (string) DI::config()->get('config', 'api_import_size', DI::config()->get('config', 'max_import_size')), 'textlimit' => (string) DI::config()->get('config', 'api_import_size', DI::config()->get('config', 'max_import_size')),

View file

@ -166,9 +166,9 @@ class InstanceV2 extends BaseApi
private function buildRegistrationsInfo(): InstanceEntity\Registrations private function buildRegistrationsInfo(): InstanceEntity\Registrations
{ {
$register_policy = intval($this->config->get('config', 'register_policy')); $register_policy = Register::getPolicy();
$enabled = ($register_policy != Register::CLOSED); $enabled = $register_policy !== Register::CLOSED;
$approval_required = ($register_policy == Register::APPROVE); $approval_required = $register_policy === Register::APPROVE;
return new InstanceEntity\Registrations($enabled, $approval_required); return new InstanceEntity\Registrations($enabled, $approval_required);
} }

View file

@ -42,7 +42,7 @@ class Bookmarklet extends BaseModule
if (!DI::userSession()->getLocalUserId()) { if (!DI::userSession()->getLocalUserId()) {
$output = '<h2>' . DI::l10n()->t('Login') . '</h2>'; $output = '<h2>' . DI::l10n()->t('Login') . '</h2>';
$output .= Login::form(DI::args()->getQueryString(), intval($config->get('config', 'register_policy')) === Register::CLOSED ? false : true); $output .= Login::form(DI::args()->getQueryString(), Register::getPolicy() !== Register::CLOSED);
return $output; return $output;
} }

View file

@ -30,7 +30,6 @@ use Friendica\Core\KeyValueStorage\Capability\IManageKeyValuePairs;
use Friendica\Core\L10n; use Friendica\Core\L10n;
use Friendica\Core\Renderer; use Friendica\Core\Renderer;
use Friendica\Core\Session\Capability\IHandleUserSessions; use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Core\System;
use Friendica\Database\PostUpdate; use Friendica\Database\PostUpdate;
use Friendica\Model\User; use Friendica\Model\User;
use Friendica\Network\HTTPException; use Friendica\Network\HTTPException;
@ -154,7 +153,7 @@ class Friendica extends BaseModule
Register::OPEN => 'REGISTER_OPEN' Register::OPEN => 'REGISTER_OPEN'
]; ];
$register_policy_int = $this->config->get('config', 'register_policy'); $register_policy_int = Register::getPolicy();
if ($register_policy_int !== Register::CLOSED && $this->config->get('config', 'invitation_only')) { if ($register_policy_int !== Register::CLOSED && $this->config->get('config', 'invitation_only')) {
$register_policy = 'REGISTER_INVITATION'; $register_policy = 'REGISTER_INVITATION';
} else { } else {

View file

@ -73,7 +73,7 @@ class Home extends BaseModule
} }
} }
$login = Login::form(DI::args()->getQueryString(), $config->get('config', 'register_policy') === Register::CLOSED ? 0 : 1); $login = Login::form(DI::args()->getQueryString(), Register::getPolicy() !== Register::CLOSED);
$content = ''; $content = '';
Hook::callAll('home_content', $content); Hook::callAll('home_content', $content);

View file

@ -146,14 +146,14 @@ class Invite extends BaseModule
$dirLocation = Search::getGlobalDirectory(); $dirLocation = Search::getGlobalDirectory();
if (strlen($dirLocation)) { if (strlen($dirLocation)) {
if ($config->get('config', 'register_policy') === Register::CLOSED) { if (Register::getPolicy() === Register::CLOSED) {
$linkTxt = DI::l10n()->t('Visit %s for a list of public sites that you can join. Friendica members on other sites can all connect with each other, as well as with members of many other social networks.', $dirLocation . '/servers'); $linkTxt = DI::l10n()->t('Visit %s for a list of public sites that you can join. Friendica members on other sites can all connect with each other, as well as with members of many other social networks.', $dirLocation . '/servers');
} else { } else {
$linkTxt = DI::l10n()->t('To accept this invitation, please visit and register at %s or any other public Friendica website.', DI::baseUrl() . '/register') $linkTxt = DI::l10n()->t('To accept this invitation, please visit and register at %s or any other public Friendica website.', DI::baseUrl() . '/register')
. "\r\n" . "\r\n" . DI::l10n()->t('Friendica sites all inter-connect to create a huge privacy-enhanced social web that is owned and controlled by its members. They can also connect with many traditional social networks. See %s for a list of alternate Friendica sites you can join.', $dirLocation . '/servers'); . "\r\n" . "\r\n" . DI::l10n()->t('Friendica sites all inter-connect to create a huge privacy-enhanced social web that is owned and controlled by its members. They can also connect with many traditional social networks. See %s for a list of alternate Friendica sites you can join.', $dirLocation . '/servers');
} }
} else { // there is no global directory URL defined } else { // there is no global directory URL defined
if ($config->get('config', 'register_policy') === Register::CLOSED) { if (Register::getPolicy() === Register::CLOSED) {
return DI::l10n()->t('Our apologies. This system is not currently configured to connect with other public sites or invite members.'); return DI::l10n()->t('Our apologies. This system is not currently configured to connect with other public sites or invite members.');
} else { } else {
$linkTxt = DI::l10n()->t('To accept this invitation, please visit and register at %s.', DI::baseUrl() . '/register' $linkTxt = DI::l10n()->t('To accept this invitation, please visit and register at %s.', DI::baseUrl() . '/register'

View file

@ -24,7 +24,6 @@ namespace Friendica\Module;
use Friendica\App; use Friendica\App;
use Friendica\BaseModule; use Friendica\BaseModule;
use Friendica\Capabilities\ICanCreateResponses; use Friendica\Capabilities\ICanCreateResponses;
use Friendica\Core\Addon;
use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\L10n; use Friendica\Core\L10n;
use Friendica\Model\Nodeinfo; use Friendica\Model\Nodeinfo;
@ -65,7 +64,7 @@ class NodeInfo110 extends BaseModule
], ],
'services' => Nodeinfo::getServices(), 'services' => Nodeinfo::getServices(),
'usage' => Nodeinfo::getUsage(), 'usage' => Nodeinfo::getUsage(),
'openRegistrations' => intval($this->config->get('config', 'register_policy')) !== Register::CLOSED, 'openRegistrations' => Register::getPolicy() !== Register::CLOSED,
'metadata' => [ 'metadata' => [
'nodeName' => $this->config->get('config', 'sitename'), 'nodeName' => $this->config->get('config', 'sitename'),
], ],

View file

@ -24,7 +24,6 @@ namespace Friendica\Module;
use Friendica\App; use Friendica\App;
use Friendica\BaseModule; use Friendica\BaseModule;
use Friendica\Capabilities\ICanCreateResponses; use Friendica\Capabilities\ICanCreateResponses;
use Friendica\Core\Addon;
use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\L10n; use Friendica\Core\L10n;
use Friendica\Model\Nodeinfo; use Friendica\Model\Nodeinfo;
@ -58,7 +57,7 @@ class NodeInfo120 extends BaseModule
'protocols' => ['dfrn', 'activitypub'], 'protocols' => ['dfrn', 'activitypub'],
'services' => Nodeinfo::getServices(), 'services' => Nodeinfo::getServices(),
'usage' => Nodeinfo::getUsage(), 'usage' => Nodeinfo::getUsage(),
'openRegistrations' => intval($this->config->get('config', 'register_policy')) !== Register::CLOSED, 'openRegistrations' => Register::getPolicy() !== Register::CLOSED,
'metadata' => [ 'metadata' => [
'nodeName' => $this->config->get('config', 'sitename'), 'nodeName' => $this->config->get('config', 'sitename'),
], ],

View file

@ -24,7 +24,6 @@ namespace Friendica\Module;
use Friendica\App; use Friendica\App;
use Friendica\BaseModule; use Friendica\BaseModule;
use Friendica\Capabilities\ICanCreateResponses; use Friendica\Capabilities\ICanCreateResponses;
use Friendica\Core\Addon;
use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\L10n; use Friendica\Core\L10n;
use Friendica\Model\Nodeinfo; use Friendica\Model\Nodeinfo;
@ -59,7 +58,7 @@ class NodeInfo210 extends BaseModule
'organization' => Nodeinfo::getOrganization($this->config), 'organization' => Nodeinfo::getOrganization($this->config),
'protocols' => ['dfrn', 'activitypub'], 'protocols' => ['dfrn', 'activitypub'],
'services' => Nodeinfo::getServices(), 'services' => Nodeinfo::getServices(),
'openRegistrations' => intval($this->config->get('config', 'register_policy')) !== Register::CLOSED, 'openRegistrations' => Register::getPolicy() !== Register::CLOSED,
'usage' => Nodeinfo::getUsage(true), 'usage' => Nodeinfo::getUsage(true),
]; ];

View file

@ -32,7 +32,6 @@ use Friendica\Core\Hook;
use Friendica\Core\L10n; use Friendica\Core\L10n;
use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues; use Friendica\Core\PConfig\Capability\IManagePersonalConfigValues;
use Friendica\Core\Session\Capability\IHandleUserSessions; use Friendica\Core\Session\Capability\IHandleUserSessions;
use Friendica\Core\System;
use Friendica\Database\Database; use Friendica\Database\Database;
use Friendica\Database\DBA; use Friendica\Database\DBA;
use Friendica\Model\Circle; use Friendica\Model\Circle;
@ -175,7 +174,7 @@ class Ping extends BaseModule
$myurl = $this->session->getMyUrl(); $myurl = $this->session->getMyUrl();
$mail_count = $this->database->count('mail', ["`uid` = ? AND NOT `seen` AND `from-url` != ?", $this->session->getLocalUserId(), $myurl]); $mail_count = $this->database->count('mail', ["`uid` = ? AND NOT `seen` AND `from-url` != ?", $this->session->getLocalUserId(), $myurl]);
if (intval($this->config->get('config', 'register_policy')) === Register::APPROVE && $this->session->isSiteAdmin()) { if (Register::getPolicy() === Register::APPROVE && $this->session->isSiteAdmin()) {
$registrations = \Friendica\Model\Register::getPending(); $registrations = \Friendica\Model\Register::getPending();
$register_count = count($registrations); $register_count = count($registrations);
} }

View file

@ -34,6 +34,7 @@ use Friendica\Database\DBA;
use Friendica\DI; use Friendica\DI;
use Friendica\Model; use Friendica\Model;
use Friendica\Model\User; use Friendica\Model\User;
use Friendica\Util\DateTimeFormat;
use Friendica\Util\Profiler; use Friendica\Util\Profiler;
use Friendica\Util\Proxy; use Friendica\Util\Proxy;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
@ -86,7 +87,7 @@ class Register extends BaseModule
} }
} }
if (!DI::userSession()->getLocalUserId() && (intval(DI::config()->get('config', 'register_policy')) === self::CLOSED)) { if (!DI::userSession()->getLocalUserId() && self::getPolicy() === self::CLOSED) {
DI::sysmsg()->addNotice(DI::l10n()->t('Permission denied.')); DI::sysmsg()->addNotice(DI::l10n()->t('Permission denied.'));
return ''; return '';
} }
@ -144,7 +145,7 @@ class Register extends BaseModule
$o = Renderer::replaceMacros($tpl, [ $o = Renderer::replaceMacros($tpl, [
'$invitations' => DI::config()->get('system', 'invitation_only'), '$invitations' => DI::config()->get('system', 'invitation_only'),
'$permonly' => intval(DI::config()->get('config', 'register_policy')) === self::APPROVE, '$permonly' => self::getPolicy() === self::APPROVE,
'$permonlybox' => ['permonlybox', DI::l10n()->t('Note for the admin'), '', DI::l10n()->t('Leave a message for the admin, why you want to join this node'), DI::l10n()->t('Required')], '$permonlybox' => ['permonlybox', DI::l10n()->t('Note for the admin'), '', DI::l10n()->t('Leave a message for the admin, why you want to join this node'), DI::l10n()->t('Required')],
'$invite_desc' => DI::l10n()->t('Membership on this site is by invitation only.'), '$invite_desc' => DI::l10n()->t('Membership on this site is by invitation only.'),
'$invite_label' => DI::l10n()->t('Your invitation code: '), '$invite_label' => DI::l10n()->t('Your invitation code: '),
@ -228,7 +229,7 @@ class Register extends BaseModule
} }
} }
switch (DI::config()->get('config', 'register_policy')) { switch (self::getPolicy()) {
case self::OPEN: case self::OPEN:
$blocked = 0; $blocked = 0;
$verified = 1; $verified = 1;
@ -312,7 +313,7 @@ class Register extends BaseModule
$base_url = (string)DI::baseUrl(); $base_url = (string)DI::baseUrl();
if ($netpublish && intval(DI::config()->get('config', 'register_policy')) !== self::APPROVE) { if ($netpublish && self::getPolicy() !== self::APPROVE) {
$url = $base_url . '/profile/' . $user['nickname']; $url = $base_url . '/profile/' . $user['nickname'];
Worker::add(Worker::PRIORITY_LOW, 'Directory', $url); Worker::add(Worker::PRIORITY_LOW, 'Directory', $url);
} }
@ -327,7 +328,7 @@ class Register extends BaseModule
$num_invites = DI::config()->get('system', 'number_invites'); $num_invites = DI::config()->get('system', 'number_invites');
$invite_id = (!empty($_POST['invite_id']) ? trim($_POST['invite_id']) : ''); $invite_id = (!empty($_POST['invite_id']) ? trim($_POST['invite_id']) : '');
if (intval(DI::config()->get('config', 'register_policy')) === self::OPEN) { if (self::getPolicy() === self::OPEN) {
if ($using_invites && $invite_id) { if ($using_invites && $invite_id) {
Model\Register::deleteByHash($invite_id); Model\Register::deleteByHash($invite_id);
DI::pConfig()->set($user['uid'], 'system', 'invites_remaining', $num_invites); DI::pConfig()->set($user['uid'], 'system', 'invites_remaining', $num_invites);
@ -363,7 +364,7 @@ class Register extends BaseModule
} }
DI::baseUrl()->redirect(); DI::baseUrl()->redirect();
} }
} elseif (intval(DI::config()->get('config', 'register_policy')) === self::APPROVE) { } elseif (self::getPolicy() === self::APPROVE) {
if (!User::getAdminEmailList()) { if (!User::getAdminEmailList()) {
$this->logger->critical('Registration policy is set to APPROVE but no admin email address has been set in config.admin_email'); $this->logger->critical('Registration policy is set to APPROVE but no admin email address has been set in config.admin_email');
DI::sysmsg()->addNotice(DI::l10n()->t('Your registration can not be processed.')); DI::sysmsg()->addNotice(DI::l10n()->t('Your registration can not be processed.'));
@ -426,4 +427,19 @@ class Register extends BaseModule
]); ]);
} }
} }
public static function getPolicy(): int
{
$days = DI::config()->get('system', 'admin_inactivity_limit');
if ($days == 0) {
return intval(DI::config()->get('config', 'register_policy'));
}
$inactive_since = DateTimeFormat::utc('now - ' . $days . ' day');
foreach (User::getAdminList(['login_date']) as $admin) {
if (strtotime($admin['login_date']) > strtotime($inactive_since)) {
return intval(DI::config()->get('config', 'register_policy'));
}
}
return self::CLOSED;
}
} }

View file

@ -66,7 +66,7 @@ class Login extends BaseModule
$this->baseUrl->redirect($return_path); $this->baseUrl->redirect($return_path);
} }
return self::form($return_path, intval($this->config->get('config', 'register_policy')) !== \Friendica\Module\Register::CLOSED); return self::form($return_path, \Friendica\Module\Register::getPolicy() !== \Friendica\Module\Register::CLOSED);
} }
protected function post(array $request = []) protected function post(array $request = [])
@ -118,7 +118,7 @@ class Login extends BaseModule
} }
$reg = false; $reg = false;
if ($register && intval(DI::config()->get('config', 'register_policy')) !== Register::CLOSED) { if ($register && Register::getPolicy() !== Register::CLOSED) {
$reg = [ $reg = [
'title' => DI::l10n()->t('Create a New Account'), 'title' => DI::l10n()->t('Create a New Account'),
'desc' => DI::l10n()->t('Register'), 'desc' => DI::l10n()->t('Register'),

View file

@ -86,7 +86,7 @@ class OpenID extends BaseModule
$open_id_obj->identity = $authId; $open_id_obj->identity = $authId;
$session->set('openid_server', $open_id_obj->discover($open_id_obj->identity)); $session->set('openid_server', $open_id_obj->discover($open_id_obj->identity));
if (intval(DI::config()->get('config', 'register_policy')) === \Friendica\Module\Register::CLOSED) { if (\Friendica\Module\Register::getPolicy() === \Friendica\Module\Register::CLOSED) {
DI::sysmsg()->addNotice($l10n->t('Account not found. Please login to your existing account to add the OpenID to it.')); DI::sysmsg()->addNotice($l10n->t('Account not found. Please login to your existing account to add the OpenID to it.'));
} else { } else {
DI::sysmsg()->addNotice($l10n->t('Account not found. Please register a new account or login to your existing account to add the OpenID to it.')); DI::sysmsg()->addNotice($l10n->t('Account not found. Please register a new account or login to your existing account to add the OpenID to it.'));

View file

@ -27,7 +27,6 @@ use Friendica\Core\Addon;
use Friendica\Core\Config\Capability\IManageConfigValues; use Friendica\Core\Config\Capability\IManageConfigValues;
use Friendica\Core\KeyValueStorage\Capability\IManageKeyValuePairs; use Friendica\Core\KeyValueStorage\Capability\IManageKeyValuePairs;
use Friendica\Core\L10n; use Friendica\Core\L10n;
use Friendica\Core\System;
use Friendica\Network\HTTPException\NotFoundException; use Friendica\Network\HTTPException\NotFoundException;
use Friendica\Util\Profiler; use Friendica\Util\Profiler;
use Psr\Log\LoggerInterface; use Psr\Log\LoggerInterface;
@ -53,7 +52,7 @@ class Statistics extends BaseModule
protected function rawContent(array $request = []) protected function rawContent(array $request = [])
{ {
$registration_open = $registration_open =
intval($this->config->get('config', 'register_policy')) !== Register::CLOSED Register::getPolicy() !== Register::CLOSED
&& !$this->config->get('config', 'invitation_only'); && !$this->config->get('config', 'invitation_only');
/// @todo mark the "service" addons and load them dynamically here /// @todo mark the "service" addons and load them dynamically here

View file

@ -80,7 +80,7 @@ class Import extends \Friendica\BaseModule
protected function post(array $request = []) protected function post(array $request = [])
{ {
if ($this->config->get('config', 'register_policy') != \Friendica\Module\Register::OPEN && !$this->app->isSiteAdmin()) { if (\Friendica\Module\Register::getPolicy() !== \Friendica\Module\Register::OPEN && !$this->app->isSiteAdmin()) {
throw new HttpException\ForbiddenException($this->t('Permission denied.')); throw new HttpException\ForbiddenException($this->t('Permission denied.'));
} }
@ -99,7 +99,7 @@ class Import extends \Friendica\BaseModule
protected function content(array $request = []): string protected function content(array $request = []): string
{ {
if (($this->config->get('config', 'register_policy') != \Friendica\Module\Register::OPEN) && !$this->app->isSiteAdmin()) { if ((\Friendica\Module\Register::getPolicy() !== \Friendica\Module\Register::OPEN) && !$this->app->isSiteAdmin()) {
$this->systemMessages->addNotice($this->t('User imports on closed servers can only be done by an administrator.')); $this->systemMessages->addNotice($this->t('User imports on closed servers can only be done by an administrator.'));
} }

View file

@ -75,7 +75,7 @@ class Instance extends BaseDataTransferObject
public function __construct(IManageConfigValues $config, BaseURL $baseUrl, Database $database, Configuration $configuration, ?Account $contact_account, array $rules) public function __construct(IManageConfigValues $config, BaseURL $baseUrl, Database $database, Configuration $configuration, ?Account $contact_account, array $rules)
{ {
$register_policy = intval($config->get('config', 'register_policy')); $register_policy = Register::getPolicy();
$this->uri = $baseUrl->getHost(); $this->uri = $baseUrl->getHost();
$this->title = $config->get('config', 'sitename'); $this->title = $config->get('config', 'sitename');
@ -87,8 +87,8 @@ class Instance extends BaseDataTransferObject
$this->thumbnail = $baseUrl . (new Header($config))->getMastodonBannerPath(); $this->thumbnail = $baseUrl . (new Header($config))->getMastodonBannerPath();
$this->languages = [$config->get('system', 'language')]; $this->languages = [$config->get('system', 'language')];
$this->max_toot_chars = (int)$config->get('config', 'api_import_size', $config->get('config', 'max_import_size')); $this->max_toot_chars = (int)$config->get('config', 'api_import_size', $config->get('config', 'max_import_size'));
$this->registrations = ($register_policy != Register::CLOSED); $this->registrations = ($register_policy !== Register::CLOSED);
$this->approval_required = ($register_policy == Register::APPROVE); $this->approval_required = ($register_policy === Register::APPROVE);
$this->invites_enabled = false; $this->invites_enabled = false;
$this->configuration = $configuration; $this->configuration = $configuration;
$this->contact_account = $contact_account ?? []; $this->contact_account = $contact_account ?? [];

View file

@ -97,6 +97,10 @@ return [
// Checks for missing entries in "post", "post-thread" or "post-thread-user" and creates them // Checks for missing entries in "post", "post-thread" or "post-thread-user" and creates them
'add_missing_posts' => false, 'add_missing_posts' => false,
// admin_inactivity_limit (Integer)
// Days of inactivity after which an admin is considered inactive. "0" means that there will be no check for inactivity.
'admin_inactivity_limit' => 30,
// allowed_link_protocols (Array) // allowed_link_protocols (Array)
// Allowed protocols in links URLs, add at your own risk. http(s) is always allowed. // Allowed protocols in links URLs, add at your own risk. http(s) is always allowed.
'allowed_link_protocols' => ['ftp://', 'ftps://', 'mailto:', 'cid:', 'gopher://'], 'allowed_link_protocols' => ['ftp://', 'ftps://', 'mailto:', 'cid:', 'gopher://'],