Skip to content

Commit

Permalink
Add option to not display sensitive data for text ConfigObjects.
Browse files Browse the repository at this point in the history
Used to keep the system (or default) LTI keys hidden from users
when configuring them via the instructor course configuration page.
This is done by replacing any output with a SECRET_STRING, set
to '*****', that is displayed to the user. Currently this option
only works for 'text' configuration objects.
  • Loading branch information
somiaj committed Aug 1, 2024
1 parent 0490840 commit 16c2f57
Show file tree
Hide file tree
Showing 10 changed files with 55 additions and 42 deletions.
9 changes: 5 additions & 4 deletions lib/WeBWorK/ConfigObject.pm
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ package WeBWorK::ConfigObject;
use Mojo::Base -signatures;

# Base object class for all config objects
use constant SECRET_STRING => '*****';

sub new ($class, $data, $c) {
return bless {
Expand All @@ -13,7 +14,7 @@ sub new ($class, $data, $c) {

# Only input is a value to display, and should produce an html string.
sub display_value ($self, $val) {
return $val;
return $self->{secret} ? SECRET_STRING : $val;
}

# This should return the value to compare to the new value. This is *not* what is displayed.
Expand Down Expand Up @@ -47,16 +48,16 @@ sub convert_newval_source ($self, $use_current) {
# will be the value of the perl variable, and newval will be whatever an entry widget produces.
sub save_string ($self, $oldval, $use_current = 0) {
my $newval = $self->convert_newval_source($use_current);
return '' if $self->comparison_value($oldval) eq $newval;
return '' if $self->comparison_value($oldval) eq $newval || ($self->{secret} && $newval eq SECRET_STRING);

$newval =~ s/['"`]//g;
return "\$$self->{var} = '$newval';\n";
}

# A widget to interact with the user
sub entry_widget ($self, $default) {
sub entry_widget ($self, $default, $is_secret) {
return $self->{c}->text_field(
$self->{name} => $default,
$self->{name} => $is_secret ? SECRET_STRING : $default,
id => $self->{name},
size => $self->{width} || 15,
class => 'form-control form-control-sm'
Expand Down
2 changes: 1 addition & 1 deletion lib/WeBWorK/ConfigObject/boolean.pm
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ sub save_string ($self, $oldval, $use_current = 0) {
return "\$$self->{var} = $newval;\n";
}

sub entry_widget ($self, $default) {
sub entry_widget ($self, $default, $is_secret) {
return $self->{c}->select_field(
$self->{name} => [
[ $self->{c}->maketext('True') => 1, $default == 1 ? (selected => undef) : () ],
Expand Down
2 changes: 1 addition & 1 deletion lib/WeBWorK/ConfigObject/checkboxlist.pm
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ sub comparison_value ($self, $val) {
return join(',', @{ $val // [] });
}

sub entry_widget ($self, $default) {
sub entry_widget ($self, $default, $is_secret) {
my $c = $self->{c};
return $c->c(
map {
Expand Down
2 changes: 1 addition & 1 deletion lib/WeBWorK/ConfigObject/list.pm
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ sub save_string ($self, $oldval, $use_current = 0) {
return "\$$self->{var} = [" . join(',', map {"'$_'"} map { $_ =~ s/['"`]//gr } split(',', $newval)) . "];\n";
}

sub entry_widget ($self, $default) {
sub entry_widget ($self, $default, $is_secret) {
my $str = join(', ', @{ $default // [] });
return $self->{c}->text_area(
$self->{name} => $str =~ /\S/ ? $str : '',
Expand Down
2 changes: 1 addition & 1 deletion lib/WeBWorK/ConfigObject/lms_context_id.pm
Original file line number Diff line number Diff line change
Expand Up @@ -101,7 +101,7 @@ sub save_string ($self, $oldval, $use_current = 0) {

# This ensures that the input for this setting always shows what is in the database. If the form is submitted, and the
# requested context id is rejected above, then that rejected value should not be shown when the page reloads.
sub entry_widget ($self, $default) {
sub entry_widget ($self, $default, $is_secret) {
$self->{c}->param($self->{name}, $default);
return $self->SUPER::entry_widget($default);
}
Expand Down
2 changes: 1 addition & 1 deletion lib/WeBWorK/ConfigObject/permission.pm
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ sub save_string ($self, $oldval, $use_current = 0) {
return "\$$self->{var} = '$newval';\n";
}

sub entry_widget ($self, $default) {
sub entry_widget ($self, $default, $is_secret) {
my $c = $self->{c};

# The value of a permission can be undefined (for nobody), a standard permission number, or some other number
Expand Down
2 changes: 1 addition & 1 deletion lib/WeBWorK/ConfigObject/permission_checkboxlist.pm
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,7 @@ sub comparison_value ($self, $val) {
return join(',', @{ $val // [] });
}

sub entry_widget ($self, $default) {
sub entry_widget ($self, $default, $is_secret) {
my $c = $self->{c};
$default = role_and_above($self->{c}->ce->{userRoles}, $default) unless ref($default) eq 'ARRAY';
return $c->c(
Expand Down
2 changes: 1 addition & 1 deletion lib/WeBWorK/ConfigObject/popuplist.pm
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ sub save_string ($self, $oldval, $use_current = 0) {
return ("\$$self->{var} = '$newval';\n");
}

sub entry_widget ($self, $default) {
sub entry_widget ($self, $default, $is_secret) {
my $c = $self->{c};
return $c->select_field(
$self->{name} => [
Expand Down
68 changes: 38 additions & 30 deletions lib/WeBWorK/ConfigValues.pm
Original file line number Diff line number Diff line change
Expand Up @@ -98,7 +98,7 @@ sub getConfigValues ($ce) {
'The name of course information file (located in the templates directory). '
. 'Its contents are displayed in the right panel next to the list of homework sets.'
),
type => 'text'
type => 'text',
},
{
var => 'defaultTheme',
Expand Down Expand Up @@ -928,49 +928,57 @@ sub getConfigValues ($ce) {
'This secret word is used to validate logins from an LMS using LTI 1.1. '
. 'This secret word must match the word configured in the LMS.'
),
type => 'text'
type => 'text',
secret => 1
},
'LTI{v1p3}{PlatfromID}' => {
var => 'LTI{v1p3}{PlatformID}',
doc => x('LMS platform ID for LTI 1.3'),
doc2 => x('LMS platform ID used to validate logins from an LMS using LTI 1.3.'),
type => 'text'
var => 'LTI{v1p3}{PlatformID}',
doc => x('LMS platform ID for LTI 1.3'),
doc2 => x('LMS platform ID used to validate logins from an LMS using LTI 1.3.'),
type => 'text',
secret => 1
},
'LTI{v1p3}{ClientID}' => {
var => 'LTI{v1p3}{ClientID}',
doc => x('LMS client ID for LTI 1.3'),
doc2 => x('LMS client ID used to validate logins from an LMS using LTI 1.3.'),
type => 'text',
var => 'LTI{v1p3}{ClientID}',
doc => x('LMS client ID for LTI 1.3'),
doc2 => x('LMS client ID used to validate logins from an LMS using LTI 1.3.'),
type => 'text',
secret => 1
},
'LTI{v1p3}{DeploymentID}' => {
var => 'LTI{v1p3}{DeploymentID}',
doc => x('LMS deployment ID for LTI 1.3'),
doc2 => x('LMS deployment ID used to validate logins from an LMS using LTI 1.3.'),
type => 'text',
var => 'LTI{v1p3}{DeploymentID}',
doc => x('LMS deployment ID for LTI 1.3'),
doc2 => x('LMS deployment ID used to validate logins from an LMS using LTI 1.3.'),
type => 'text',
secret => 1
},
'LTI{v1p3}{PublicKeysetURL}' => {
var => 'LTI{v1p3}{PublicKeysetURL}',
doc => x('LMS public keyset URL for LTI 1.3'),
doc2 => x('LMS public keyset URL used to validate logins from an LMS using LTI 1.3.'),
type => 'text',
var => 'LTI{v1p3}{PublicKeysetURL}',
doc => x('LMS public keyset URL for LTI 1.3'),
doc2 => x('LMS public keyset URL used to validate logins from an LMS using LTI 1.3.'),
type => 'text',
secret => 1
},
'LTI{v1p3}{AccessTokenURL}' => {
var => 'LTI{v1p3}{AccessTokenURL}',
doc => x('LMS access token URL for LTI 1.3'),
doc2 => x('LMS access token URL used to validate logins from an LMS using LTI 1.3.'),
type => 'text',
var => 'LTI{v1p3}{AccessTokenURL}',
doc => x('LMS access token URL for LTI 1.3'),
doc2 => x('LMS access token URL used to validate logins from an LMS using LTI 1.3.'),
type => 'text',
secret => 1
},
'LTI{v1p3}{AccessTokenAUD}' => {
var => 'LTI{v1p3}{AccessTokenAUD}',
doc => x('LMS access token AUD for LTI 1.3'),
doc2 => x('LMS access token AUD used to validate logins from an LMS using LTI 1.3.'),
type => 'text',
var => 'LTI{v1p3}{AccessTokenAUD}',
doc => x('LMS access token AUD for LTI 1.3'),
doc2 => x('LMS access token AUD used to validate logins from an LMS using LTI 1.3.'),
type => 'text',
secret => 1
},
'LTI{v1p3}{AuthReqURL}' => {
var => 'LTI{v1p3}{AuthReqURL}',
doc => x('LMS authorization request URL for LTI 1.3'),
doc2 => x('LMS authorization request URL used to validate logins from an LMS using LTI 1.3.'),
type => 'text',
var => 'LTI{v1p3}{AuthReqURL}',
doc => x('LMS authorization request URL for LTI 1.3'),
doc2 => x('LMS authorization request URL used to validate logins from an LMS using LTI 1.3.'),
type => 'text',
secret => 1
},
debug_lti_parameters => {
var => 'debug_lti_parameters',
Expand Down
6 changes: 5 additions & 1 deletion templates/ContentGenerator/Instructor/Config.html.ep
Original file line number Diff line number Diff line change
Expand Up @@ -56,12 +56,16 @@
% defined $ce->{permissionLevels}{"change_config_$conobject->{var}"}
% && !$authz->hasPermissions(param('user'), "change_config_$conobject->{var}")
% );
% # Hide sensitive variables from being displayed.
% my $default_value = $conobject->get_value($default_ce);
% my $current_value = $conobject->get_value($ce3);
% my $is_secret = $conobject->{secret} && $default_value eq $current_value ? 1 : 0;
<tr>
<td><%= $conobject->what_string %></td>
<td class="text-center">
<%= $conobject->display_value($conobject->get_value($default_ce)) %>
</td>
<td><%= $conobject->entry_widget($conobject->get_value($ce3)) =%></td>
<td><%= $conobject->entry_widget($conobject->get_value($ce3), $is_secret) =%></td>
</tr>
% }
</table>
Expand Down

0 comments on commit 16c2f57

Please sign in to comment.