Dear all,
I’ve been fighting with this issue for a bit so thought i would post it here just in case.
I have been trying to build my integration between RequestTracker and MeshCentral, and when you go to a device in MeshCentral, the url is like:
https://meshurl.com/blah?gotonode=
So I figured, great, I will use the Custom Field on Assets Integration feature, “RT can make this custom field’s values into hyperlinks to another service.”. I hooked it up but it turns out that this field when made into a URL performs URL encoding which breaks my MeshCentral URL because some IDs have $ etc characters in them.
I tracked down this feature to /opt/rt6/lib/RT/ObjectCustomFieldValue.pm
{
my %placeholders = (
id => { value => sub { $_[0]->ObjectId }, escape => 1 },
CustomField => { value => sub { $_[0]->Content }, escape => 0 },
WebDomain => { value => sub { RT->Config->Get('WebDomain') } },
WebPort => { value => sub { RT->Config->Get('WebPort') } },
WebPath => { value => sub { RT->Config->Get('WebPath') } },
WebBaseURL => { value => sub { RT->Config->Get('WebBaseURL') } },
WebURL => { value => sub { RT->Config->Get('WebURL') } },
);
sub _FillInTemplateURL {
my $self = shift;
my $url = shift;
return undef unless defined $url && length $url;
# special case, whole value should be an URL
if ( $url =~ /^__CustomField__/ ) {
my $value = $self->Content;
$value //= '';
# protect from potentially malicious URLs
if ( $value =~ /^\s*(?:javascript|data):/i ) {
my $object = $self->Object;
$RT::Logger->error(
"Potentially dangerous URL type in custom field '". $self->CustomFieldObj->Name ."'"
." on ". ref($object) ." #". $object->id
);
return undef;
}
$url =~ s/^__CustomField__/$value/;
}
# default value, uri-escape
for my $key (keys %placeholders) {
$url =~ s{__${key}__}{
my $value = $placeholders{$key}{'value'}->( $self );
$value //= '';
RT::Interface::Web::EscapeURI(\$value) if $placeholders{$key}{'escape'};
$value
}gxe;
}
return $url;
} }
so I tried to override by placing a file /opt/rt6/local/lib/RT/ObjectCustomFieldValue_Local.pm
root@web0:~# cat /opt/rt6/local/lib/RT/ObjectCustomFieldValue_Local.pm
no warnings qw(redefine);
my %placeholders = (
id => { value => sub { $_[0]->ObjectId }, escape => 1 },
CustomField => { value => sub { $_[0]->Content } },
WebDomain => { value => sub { RT->Config->Get('WebDomain') } },
WebPort => { value => sub { RT->Config->Get('WebPort') } },
WebPath => { value => sub { RT->Config->Get('WebPath') } },
WebBaseURL => { value => sub { RT->Config->Get('WebBaseURL') } },
WebURL => { value => sub { RT->Config->Get('WebURL') } },
);
sub _FillInTemplateURL {
my $self = shift;
my $url = shift;
return undef unless defined $url && length $url;
# special case, whole value should be an URL
if ( $url =~ /^__CustomField__/ ) {
my $value = $self->Content;
$value //= '';
# protect from potentially malicious URLs
if ( $value =~ /^\s*(?:javascript|data):/i ) {
my $object = $self->Object;
$RT::Logger->error(
"Potentially dangerous URL type in custom field '". $self->CustomFieldObj->Name ."'"
." on ". ref($object) ." #". $object->id
);
return undef;
}
$url =~ s/^__CustomField__/$value/;
}
# default value, uri-escape
for my $key (keys %placeholders) {
$url =~ s{__${key}__}{
my $value = $placeholders{$key}{'value'}->( $self );
$value //= '';
RT::Interface::Web::EscapeURI(\$value) if $placeholders{$key}{'escape'};
$value
}gxe;
}
return $url;
}
1;
Howver it doesn’t seem to override. I tried manually changing /opt/rt6/lib/RT/ObjectCustomFieldValue.pm to suit my wishes, and my feature works, but i dont want my change to get overridden on update. Indeed i want to package my changes into a plugin in the future.
My question is, and my perl is not the best - is it not being overridden because of an error I made, or is it because the function is inside a scope block {} ? Could anyone shed any light here ![]()