1 #originally written by Koni
2 #edited by Evan, 1/10/07, to move to the form framework
9 use CXGN
::People
::Login
;
11 my $account_info_page = new SolPeopleAccountInfoPage
();
13 ##################################################################################################
15 package SolPeopleAccountInfoPage
;
16 use CXGN
::Page
::FormattingHelpers qw
/page_title_html/;
17 use base
qw(CXGN::Page::Form::SimpleFormPage);
23 my $self = $class->SUPER::new
(%params);
24 my (undef, undef, $this_script_filename) = File
::Spec
->splitpath($0); #$0 contains current filename with some path or other prepended
25 $self->set_script_name($this_script_filename);
32 # call set_object_id, set_object and set_primary_key here
33 my %args = $self->get_args();
34 $self->set_object_id($args{sp_person_id
});
35 $self->set_object(new CXGN
::People
::Login
($self->get_dbh(), $args{sp_person_id
}));
36 $self->set_primary_key("sp_person_id");
37 $self->set_owners($self->get_object()->get_sp_person_id());
40 #specified in SimpleFormPage
41 sub check_modify_privileges
{
44 # implement quite strict access controls by default
46 my $person_id = $self->get_login()->verify_session();
47 my $user = CXGN
::People
::Person
->new($self->get_dbh(), $person_id);
48 my $user_id = $user->get_sp_person_id();
49 if ($user->get_user_type() eq 'curator') {
53 # check the owner only if the action is not new
55 my @owners= $self->get_owners();
57 if ((@owners) && !(grep{/^$user_id$/} @owners ) )
59 $self->get_page()->message_page("You do not have rights to modify this database entry because you do not own it. [$user_id, @owners]");
66 # override to check privileges for edit, store, delete.
67 # return 0 for allow, 1 for not allow.
72 #specified in SimpleFormPage
73 sub validate_parameters_before_store
76 my $person = new CXGN
::People
::Person
($self->get_dbh(), $self->get_object_id());
77 my %args = $self->get_args();
78 my ($current_password, $change_username, $change_password, $change_email) = @args{qw(current_password change_username change_password change_email)};
80 # If this happens, there is something wrong with the validation logic or
81 # account creation step allowed someone to have an empty password.
82 if(!$person->get_password())
84 print STDERR
"Can't find password for sp_user \"" . $person->get_sp_person_id() . "\" when updating account\n";
85 $self->get_page()->error_page("User account could not be updated because it was not found.\n");
89 if(!$change_password && !$change_username && !$change_email)
91 $self->failed("No actions were requested. Please select which fields you would like to update by checking the appropriate checkbox(es) on the form and entering your new information.");
93 if($person->get_password() ne $current_password)
95 $self->failed("Your current password does not match SGN records.");
98 # Check for error conditions in all changes, before making any of them.
99 # Otherwise, we could end up making some changes and then failing on later
100 # ones. The user would then push the back button and their information may
101 # be different now but they will probably assume no changes were made. This
102 # is most troublesome if the current password changes.
103 if($change_username) {
104 #unless change_username is set, new_username won't be in the args hash because of the prestore test
105 my $new_username = $args{new_username
};
106 if(length($new_username) < 7) {
107 $self->failed("Username must be at least 7 characters long.");
110 my $other_user = CXGN
::People
::Login
->get_login($self->get_dbh(), $new_username);
111 if(defined $other_user->get_sp_person_id() && ($person -> get_sp_person_id
() != $other_user->get_sp_person_id())) {
112 $self->failed("Username \"$new_username\" is already in use. Please select a different username.");
116 $self->get_form()->get_field_obj_by_name("new_username")->set_store_enabled(0); #turn off storing username from form
118 if($change_password) {
119 #unless change_password is set, new_password won't be in the args hash because of the prestore test
120 my ($new_password, $confirm_password) = @args{qw(new_password confirm_password)};
121 if(length($new_password) < 7) {
122 $self->failed("Password must be at least 7 characters long.");
125 if($new_password !~ /^[a-zA-Z0-9~!@#$^&*_.=:;<>?]+$/) {
126 $self->failed("Password can't contain spaces or these symbols: <u><b>` ( ) [ ] { } - + ' \" / \\ , |</b></u>.");
128 if($new_password ne $confirm_password) {
129 $self->failed("New password entries do not match. You must enter your new password twice to verify accuracy.");
133 $self->get_form()->get_field_obj_by_name("new_password")->set_store_enabled(0); #turn off storing password from form
136 #unless change_email is set, private_email won't be in the args hash because of the prestore test
137 my ($private_email, $confirm_email) = @args{qw(private_email confirm_email)};
138 if($private_email !~ m/^[a-zA-Z0-9_.-]+@[a-zA-Z0-9_.-]+$/) {
139 $self->failed("E-mail address \"$private_email\" does not appear to be a valid e-mail address.");
141 if($private_email ne $confirm_email) {
142 $self->failed("New e-mail address entries do not match. You must enter your new e-mail address twice to verify accuracy.");
146 $self->get_form()->get_field_obj_by_name("private_email")->set_store_enabled(0); #turn off storing e-mail from form
149 #the confirm code needs to be part of a DBI object so it can be stored to the database
150 my $confirm_code = $self->get_page()->tempname();
151 $self->get_object()->set_confirm_code($confirm_code);
154 #display a 'failure; please try again' message
155 #argument: failure message
157 my ($self, $msg) = @_;
158 my $try_again = "<br />Please use your browser's back button to try again.\n";
159 $self->get_page()->message_page("Account Update Failed", $msg . $try_again);
163 #specified in SimpleFormPage
164 sub process_parameters_after_store
{
166 my %args = $self->get_args();
167 if($args{change_email
}) {
168 my $person = new CXGN
::People
::Person
($self->get_dbh(), $self->get_object_id());
169 $self->send_confirmation_email($person->get_username(), $person->get_private_email());
170 warn "sent e-mail change confirmation to " . $person->get_private_email() . "\n";
174 #e-mail the user after a successful change of private e-mail address
175 #arguments: (possibly new) username, new private e-mail address
176 sub send_confirmation_email
{
177 my ($self, $username, $private_email) = @_;
178 my $confirm_code = $self->get_object()->get_confirm_code();
179 my $host = $self->get_page()->get_hostname();
180 my $subject = "[SGN] E-mail Address Confirmation Request";
181 my $body = <<END_HEREDOC;
182 Please do *NOT* reply to this message. The return address is not valid.
183 Use sgn-feedback\@sgn.cornell.edu instead.
185 This message is sent to confirm the private e-mail address for community user
188 Please click (or cut and paste into your browser) the following link to
189 confirm your account and e-mail address:
191 http://$host/solpeople/account-confirm.pl?username=$username&confirm=$confirm_code
197 CXGN::Contact::send_email($subject, $body, $private_email);
202 my %args = $self->get_args();
203 my $login = $self->get_object();
204 my $person = new CXGN::People::Person($self->get_dbh(), $self->get_object_id());
207 my $form = $self->get_form();
208 if($form->is_editable()) {
209 $form->set_submit_method('post'); #passwords are sensitive data
212 my $default_field_length = 22;
213 if($form->is_editable()) {
214 $form->add_label(display_name => "",
215 field_name => "lbl1",
216 contents => "Please verify your current password to make changes. Select changes desired by checking the appropriate checkbox and entering"
217 . " the new information.");
218 $form->add_password_field(display_name => "Current password",
219 field_name => "current_password",
221 length => $default_field_length,
222 validate => "1"); #means it must have a value
223 $form->add_checkbox(display_name => "Change username",
224 field_name => "change_username",
227 my $username_change_checkbox = $form->get_field_obj_by_name("change_username");
228 $form->add_field(display_name => "New username",
229 field_name => "new_username",
230 contents => $login->get_username(),
231 length => $default_field_length,
233 getter => 'get_username',
234 setter => 'set_username');
235 $form->add_checkbox(display_name => "Change password",
236 field_name => "change_password",
239 my $password_change_checkbox = $form->get_field_obj_by_name("change_password");
240 $form->add_password_field(display_name => "New password",
241 field_name => "new_password",
243 length => $default_field_length,
245 getter => 'get_password',
246 setter => 'set_password');
247 $form->add_password_field(display_name => "Confirm new password",
248 field_name => "confirm_password",
250 length => $default_field_length);
253 $form->add_field(display_name => "Username",
254 field_name => "username",
255 contents => $login->get_username());
257 $form->add_label(display_name => "",
258 field_name => "lbl2",
259 contents => "Your private e-mail address is not publically displayed online. It is used only for SGN staff to contact you about changes to"
260 . " your record or for e-mailing your password to you. Changing your private e-mail address will trigger a confirmation message from"
261 . " SGN to verify the address is usable by SGN.");
262 if($form->is_editable()) {
263 $form->add_checkbox(display_name => "Change private e-mail address",
264 field_name => "change_email",
267 my $email_change_checkbox = $form->get_field_obj_by_name("change_email");
268 $form->add_field(display_name => "Private e-mail address",
269 field_name => "private_email",
270 contents => $login->get_private_email(),
271 length => $default_field_length,
273 getter => 'get_private_email',
274 setter => 'set_private_email');
275 $form->add_field(display_name => "Confirm e-mail address",
276 field_name => "confirm_email",
278 length => $default_field_length);
281 $form->add_field(display_name => "Private e-mail address",
282 field_name => "private_email",
283 contents => $login->get_private_email());
286 #for allowing the form to make changes
287 if($self->get_action() =~ /^edit$/) {
288 $form->add_hidden(display_name => "ID", field_name => "sp_person_id", contents => $person->get_sp_person_id());
289 $form->add_hidden(display_name => "Action", field_name => "action", contents => "store");
292 if($form->is_editable()) {
293 $form->set_reset_button_text("Clear Form");
294 $form->set_submit_button_text("Change Account Information");
297 if($self->get_action() =~ /^store$/) {
298 $form->from_request($self->get_args());
303 #return an HTML string for a toolbar with other possible actions for the form
304 sub get_actions_toolbar {
307 my $script_name = $self->get_script_name();
308 my $user_id= $self->get_user()->get_sp_person_id();
309 my @owners=$self->get_owners();
310 my $user_is_owner = (grep{/^$user_id$/} @owners);
311 my %args = $self->get_args();
312 my $sp_person_id = $args{sp_person_id};
314 my $home = qq(<a href="top-level.pl?sp_person_id=$sp_person_id">[Directory Update Home]</a> );
316 if($self->get_action() eq "edit") {
318 return $home . qq(<a href="$script_name?action=view&sp_person_id=$sp_person_id">[Cancel Edit]</a>);
321 return $home . qq(<span class="ghosted">[Cancel Edit]</span>);
324 elsif($self->get_action() eq "view") {
326 return $home . qq(<a href="$script_name?action=edit&sp_person_id=$sp_person_id">[Edit]</a>);
329 return $home . qq(<span class="ghosted">[Edit]</span>);
332 elsif($self->get_action() eq "store") {
339 #SimpleFormPage takes care of some unknown action strings, but we don't handle the full set of actions it supports
340 if($self->get_action() !~ /^view|edit|store$/) {
341 $self->get_page()->message_page("Illegal parameter: action '" . $self->get_action() . "' is not supported by " . $self->get_script_name());
344 my $page = $self->get_page();
345 my $person = new CXGN::People::Person($self->get_dbh(), $self->get_object_id());
347 $page->header("Sol People: account info");
348 print page_title_html("Account info for user <tt>" . $person->get_username() . "</tt>");
349 print $self->get_actions_toolbar() . "<hr />\n";
350 print $self->get_form()->as_table_string();