From Request Tracker Wiki
Jump to navigation Jump to search

Offer Password Reset on Login Page

The code below was adapted from

I installed from Debian apt-get packages and the "local" directory is found at: /usr/local/share/request-tracker3.8 while the real source directory is at: /usr/share/request-tracker3.8

So, to hook into the Callback offered in the Login form called "AfterForm", I had to create the directory: /usr/local/share/request-tracker3.8/html/Callbacks/Default/Elements/Login and in there put a file called "AfterForm" The content of that file is:

%# taken from
        %# Add template named 'Password Change', with description
        %#   Automatically generate password for external users who have forgotten their password
        <div style="margin: -20px auto 10px auto; text-align: center;">
            <b>Forgot Your Password?</b>
            <div style="color: green; font-weight: bold;"><%$forgotSuccess%></div>
            <form method="get" style="display: <%$forgotFormDisplay%>;"
            <!-- if you are using RT4, you need this: -->
            <!-- end for RT4 -->
            <!-- if you are using RT4, you need this next line -->
             <input type="hidden" name="next" value="<%$next%>" />
            <!-- END LINE FOR rt4 -->
        % if($forgotFail) {
        <div class="error" style="text-align: left;">
            <div class="titlebox error">
                <div class="titlebox-title">
                    <span class="left">Error</span><span class="right-empty"> </span>
                <div class="titlebox-content">
                    <%$forgotFail%><hr class="clear" />
        % }
                <%$forgotPrompt%> <input type="text" name="email"> <input type="submit" value='Send New Password'>
        my $forgotPrompt = "Enter your email address: ";
        my $forgotFail = '';
        my $forgotFormDisplay = 'block';
        my $forgotSuccess = '';
        my $mailfrom = 'Ticket System <YOU@YOURDOMAIN>';
        if ($email)
            $email =~ s/^\s+|\s+$//g;
            my $UserObj = RT::User->new($RT::SystemUser);
            if (defined($UserObj->Id))
                my ($val, $str) = ResetPassword($UserObj, $mailfrom);
                if($val > 0)
                    $forgotFormDisplay = 'none';
                    $forgotSuccess = $str;
                    $forgotFail = $str;
                $forgotFail = "Sorry, no account in the ticket system has the email address: $email";
                $forgotPrompt = "Please enter the email used in one of your existing tickets:";
        sub ResetPassword {
            my $self = shift;
            my $mailfrom = shift;
            my $email = $self->EmailAddress;
            unless ( $self->CurrentUserCanModify('Password') ) {
                return ( 0, $self->loc("You don't have permission to change your password.") );
            unless ( ($self->Name =~ m/\@/) ) {
                return ( 0, $self->loc("Only external users can reset their passwords this way.") );
            my ( $status, $pass ) = $self->SetRandomPassword();
            unless ($status) {
                return ( 0, "$pass" );
            my $template = RT::Template->new( $self->CurrentUser );
            my $parsed;
            # This test do not work.  I'm not sure how to detect if the template loading failed [pere 2006-08-16]
            if ($template->LoadGlobalTemplate('PasswordChange')) {
                $T::RealName = $self->RealName;
                $T::Username = $self->Name;
                $T::Password = $pass;
                $parsed = $template->_ParseContent();
        # hardcoded default text body in case 'Password Change' template is missing.
                $parsed = <<EOF;
        This message was automatically sent in response to a Reset Password request in
        the web based ticket system.
        You may now login using the following:
                Username: $self->Name
                Password: $pass
        Support Team
            my $entity = MIME::Entity->build(
                                              From    => $mailfrom,
                                              To      => $email,
                                              Subject => loc("CF Ticket Password Changed"),
                                              'X-RT-Loop-Prevention' => $RT::rtname,
                                              Type    => "text/plain",
                                              Charset => "UTF-8",
                                              Data    => [$parsed]
            open (MAIL, "|$RT::SendmailPath $RT::SendmailArguments -t") || return(0, "Failed to open mailpipe");
            print MAIL $entity->as_string;
            return (1, "SUCCESS! A new password was sent to your email address.");
        $email => undef
  # if you are using RT4, you need this next line:
        $next => undef
  # end for RT4

For RT4.0.6 (maybe earlier?)

We had to do a few changes to make it work under RT4.0.6, we hope the following will make it easier for others.

First, for non Debian distrbutions the file AfterForm should be created under [RT4 base dir]/local/html/Callbacks/Default/Elements/Login/

Copy pasting the code from here will break things, so make sure you do the following after you pasted it into the file:

Merge the following lines, as keeping it this way will break the HTML code, just remove the comments and put it all on one line (lines ~12-16):

<form method="get" style="display: <%$forgotFormDisplay%>;"


<form method="get" style="display: <%$forgotFormDisplay%>;" action="NoAuth/Login.html">

Next, SetRandomPassword function when invoked change the password, but won't include it in the email sent to the user. Change the function to ResetPassword (line ~83):

my ( $status, $pass ) = $self->SetRandomPassword();


my ( $status, $pass ) = $self->ResetPassword();

Last thing, make sure the closing "EOF" (line ~120) is at the start of a line by itself, else it will die with an error.