#!/usr/local/cpanel/3rdparty/bin/perl
# cpanel - base/backend/ajax_maketext_syntax_util.pl
# Copyright 2022 cPanel, L.L.C.
# All rights reserved.
# copyright@cpanel.net http://cpanel.net
# This code is subject to the cPanel license. Unauthorized copying is prohibited
use strict;
use warnings;
use CGI ();
use Cpanel::JSON ();
use Cpanel::Locale ();
use MIME::Base64 ();
use Cpanel::Locale::Utils::Custom ();
use Cpanel::PwCache ();
use Cpanel::SafeRun::Errors ();
use Cpanel::StringFunc::SplitBreak ();
use Cpanel::Config::LoadCpUserFile ();
use Whostmgr::ACLS ();
no bytes; # brings in bytes::functions && keeps bytes symantics as-is
_check_acls();
_check_application();
my $cgi = CGI->new();
my $rendered = '';
my $key = $cgi->param('key');
my $charset = $cgi->param('charset') || 'utf-8';
my $locale_tag = $cgi->param('locale_tag') || '';
my $from_locale = 0;
# Disable cpsrvd's cpanel-mode flag to prevent Cpanel::Locale::get_handle from panicking
local $ENV{'CPANEL'};
if ( !defined $cgi->param('key') || $cgi->param('key') =~ m/^\s*$/ ) {
$@ = "no key given";
}
else {
my $lh = Cpanel::Locale->new;
eval { $rendered = $lh->_compile($key); };
if ( !$@ ) {
if ( ref $rendered eq 'SCALAR' ) {
$rendered = ${$rendered};
}
elsif ( ref $rendered eq 'CODE' ) {
my @args = $cgi->multi_param('args');
eval { $rendered = $lh->$rendered(@args); };
if ( !$@ && $locale_tag ) {
$from_locale = $locale_tag;
# only do this if it's a coderef:
# so the phrase is ok and we have a $locale_tag == render under locale to get it's nuances (e.g. think numf())
$rendered = Cpanel::Locale->get_handle($locale_tag)->makevar( $key, @args ); # since this is coming from the lex we don't have to worry about it being marked in order to find it to put it into the lex
}
}
else {
$@ = "invalid response from compiler"; # this should never happen
}
}
}
my $error = '';
my $saved = 0;
if ($@) {
$error = $@;
$error =~ s{, as used .*}{}s; # cleanup Locale::MakeText::_die_pointing()'s error message
}
else {
if ( $cgi->param('save') ) {
my $orig_key = $cgi->param('orig_key') || '';
my $theme = $cgi->param('theme') || '';
if ( !$orig_key || !$locale_tag || !$theme ) {
$error = 'not enough data sent in order to save';
}
else {
$theme = '' if $theme eq '/';
my $extra = '';
if ( $> == 0 ) {
$saved = 1 if Cpanel::Locale::Utils::Custom::update_key( $orig_key, $key, $locale_tag, $theme, 1 );
}
else {
my $user = Cpanel::PwCache::getpwuid($>);
my $new_value_safe = MIME::Base64::encode_base64( $key, '' );
my $orig_key_safe = MIME::Base64::encode_base64( $orig_key, '' );
if ( !$new_value_safe ) {
$extra = 'Could not save the new value, it was corrupted in passing.'; # We should never get here but just in case
}
else {
my @new_value_safe = Cpanel::StringFunc::SplitBreak::_word_split( $new_value_safe, 256 );
$extra = Cpanel::SafeRun::Errors::saferunallerrors( '/usr/local/cpanel/bin/langwrap', 'SAVEKEY', $locale_tag, $theme, $orig_key_safe, @new_value_safe );
$saved = 1 if $? == 0;
}
}
if ( !$saved ) {
$error = 'Could not save key: ' . $extra;
}
}
}
}
my $json = Cpanel::JSON::Dump(
{
'status' => $error ? 0 : 1,
'text' => $error ? $error : $rendered,
'saved' => $saved,
'from_locale' => $from_locale,
}
);
print $cgi->header( '-type' => 'text/plain', '-charset' => $charset, '-Content_length' => bytes::length($json) );
print $json;
sub _check_acls {
if ( $> == 0 ) {
Whostmgr::ACLS::init_acls();
if ( !Whostmgr::ACLS::checkacl('locale-edit') ) {
_denied('Permission denied');
}
}
else {
if ( Cpanel::Config::LoadCpUserFile::loadcpuserfile( $ENV{'REMOTE_USER'} )->{'DEMO'} ) {
_denied("Access Denied: $ENV{REMOTE_USER} is a demo account.");
}
}
return;
}
sub _check_application {
if ( $ENV{'WEBMAIL'} ) {
warn "$ENV{REMOTE_ADDR} $ENV{REMOTE_USER} running $0 under webmail (denied)\n";
_denied('Wrong application');
}
return;
}
sub _denied {
my $msg = shift;
print "Status: 403\r\nContent-type: text/plain\r\n\r\n";
print Cpanel::JSON::Dump( { 'status' => 0, 'text' => $msg } );
exit();
}