Annotation of loncom/auth/migrateuser.pm, revision 1.27
1.1 albertel 1: # The LearningOnline Network
2: # Starts a user off based of an existing token.
3: #
1.27 ! raeburn 4: # $Id: migrateuser.pm,v 1.26 2017/11/30 15:14:51 raeburn Exp $
1.1 albertel 5: #
6: # Copyright Michigan State University Board of Trustees
7: #
8: # This file is part of the LearningOnline Network with CAPA (LON-CAPA).
9: #
10: # LON-CAPA is free software; you can redistribute it and/or modify
11: # it under the terms of the GNU General Public License as published by
12: # the Free Software Foundation; either version 2 of the License, or
13: # (at your option) any later version.
14: #
15: # LON-CAPA is distributed in the hope that it will be useful,
16: # but WITHOUT ANY WARRANTY; without even the implied warranty of
17: # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18: # GNU General Public License for more details.
19: #
20: # You should have received a copy of the GNU General Public License
21: # along with LON-CAPA; if not, write to the Free Software
22: # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
23: #
24: # /home/httpd/html/adm/gpl.txt
25: #
26: # http://www.lon-capa.org/
27: #
28:
1.2 albertel 29: package Apache::migrateuser;
1.1 albertel 30:
31: use strict;
1.19 raeburn 32: use LONCAPA qw(:DEFAULT :match);
1.1 albertel 33: use Apache::Constants qw(:common :http :methods);
34: use Apache::lonauth;
35: use Apache::lonnet;
1.6 albertel 36: use Apache::lonlocal;
1.18 raeburn 37: use Apache::lonlogin();
1.27 ! raeburn 38: use Apache::ltiauth;
1.1 albertel 39:
40: sub goto_login {
1.27 ! raeburn 41: my ($r,$domain,$data) = @_;
! 42: if ((ref($data) eq 'HASH') && ($data->{'lti.login'})) {
! 43: &Apache::ltiauth::invalid_request($r,'22');
! 44: } else {
! 45: &Apache::loncommon::content_type($r,'text/html');
! 46: $r->send_http_header;
! 47: my $url = '/adm/login';
! 48: if ($domain) {
! 49: $url .= '?domain='.$domain;
! 50: }
! 51: $r->print(&Apache::loncommon::start_page('Going to login',undef,
! 52: {'redirect' => [0,$url],}).
! 53: '<h1>'.&mt('One moment please...').'</h1>'.
! 54: '<p>'.&mt('Transferring to login page.').'</p>'.
! 55: &Apache::loncommon::end_page());
! 56: }
1.2 albertel 57: return OK;
1.1 albertel 58: }
59:
1.27 ! raeburn 60: sub sso_check {
1.7 albertel 61: my ($data) = @_;
1.8 albertel 62: my %extra_env;
1.18 raeburn 63: if (ref($data) eq 'HASH') {
64: if ($data->{'sso.login'}) {
65: $extra_env{'request.sso.login'} = $data->{'sso.login'};
66: }
67: if ($data->{'sso.reloginserver'}) {
68: $extra_env{'request.sso.reloginserver'} =
69: $data->{'sso.reloginserver'};
70: }
1.27 ! raeburn 71: }
! 72: return \%extra_env;
! 73: }
! 74:
! 75: sub lti_check {
! 76: my ($data) = @_;
! 77: my %lti_env;
! 78: if (ref($data) eq 'HASH') {
1.26 raeburn 79: if ($data->{'lti.login'}) {
1.27 ! raeburn 80: $lti_env{'request.lti.login'} = $data->{'lti.login'};
! 81: if ($data->{'lti.reqcrs'}) {
! 82: $lti_env{'request.lti.reqcrs'} = $data->{'lti.reqcrs'};
! 83: }
! 84: if ($data->{'lti.reqrole'}) {
! 85: $lti_env{'request.lti.reqrole'} = $data->{'lti.reqrole'};
! 86: }
! 87: if ($data->{'lti.selfenrollrole'}) {
! 88: $lti_env{'request.lti.selfenrollrole'} = $data->{'lti.selfenrollrole'};
! 89: }
1.26 raeburn 90: }
91: if ($data->{'lti.passbackid'}) {
1.27 ! raeburn 92: $lti_env{'request.lti.passbackid'} = $data->{'lti.passbackid'};
1.26 raeburn 93: }
94: if ($data->{'lti.passbackurl'}) {
1.27 ! raeburn 95: $lti_env{'request.lti.passbackurl'} = $data->{'lti.passbackurl'};
1.26 raeburn 96: }
97: if ($data->{'lti.rosterid'}) {
1.27 ! raeburn 98: $lti_env{'request.lti.rosterid'} = $data->{'lti.rosterid'};
1.26 raeburn 99: }
100: if ($data->{'lti.rosterurl'}) {
1.27 ! raeburn 101: $lti_env{'request.lti.rosterurl'} = $data->{'lti.rosterurl'};
1.26 raeburn 102: }
1.7 albertel 103: }
1.27 ! raeburn 104: return \%lti_env;
1.18 raeburn 105: }
106:
107: sub ip_changed {
108: my ($r,$udom,$camefrom,$dataref) = @_;
109: &Apache::loncommon::content_type($r,'text/html');
110: $r->send_http_header;
111: if (ref($dataref) eq 'HASH') {
112: my $title = 'LON-CAPA Session redirected';
113: my $message = &mt('Your internet address has changed since you logged in.');
114: my $rule_in_effect;
1.22 raeburn 115: if ($dataref->{'balancer'}) {
116: my $baldom = &Apache::lonnet::host_domain($camefrom);
117: my $balprimaryid = &Apache::lonnet::domain($baldom,'primary');
118: my $balintdom = &Apache::lonnet::internet_dom($balprimaryid);
119: my $uprimaryid = &Apache::lonnet::domain($udom,'primary');
120: my $uintdom = &Apache::lonnet::internet_dom($uprimaryid);
121: my $dom_in_use;
122: if (($uintdom ne '') && ($uintdom eq $balintdom)) {
123: $dom_in_use = $udom;
124: } else {
125: $dom_in_use = $baldom;
1.21 raeburn 126: }
1.22 raeburn 127: my ($result,$cached)=&Apache::lonnet::is_cached_new('loadbalancing',$dom_in_use);
1.18 raeburn 128: unless (defined($cached)) {
129: my $cachetime = 60*60*24;
130: my %domconfig =
1.22 raeburn 131: &Apache::lonnet::get_dom('configuration',['loadbalancing'],$dom_in_use);
1.18 raeburn 132: if (ref($domconfig{'loadbalancing'}) eq 'HASH') {
1.22 raeburn 133: $result = &Apache::lonnet::do_cache_new('loadbalancing',$dom_in_use,
1.18 raeburn 134: $domconfig{'loadbalancing'},$cachetime);
135: }
136: }
137: if (ref($result) eq 'HASH') {
138: (undef,my $currtargets,my $currrules) =
139: &Apache::lonnet::check_balancer_result($result,$dataref->{'server'});
140: if (ref($currrules) eq 'HASH') {
141: if ($dataref->{'sso.login'}) {
142: if ($currrules->{'_LC_ipchangesso'} ne '') {
143: $rule_in_effect = $currrules->{'_LC_ipchangesso'};
144: }
145: } else {
146: if ($currrules->{'_LC_ipchange'} ne '') {
147: $rule_in_effect = $currrules->{'_LC_ipchange'};
148: }
149: }
150: }
151: }
152: }
153: my $url;
154: my $lonhost= $r->dir_config('lonHostID');
155: my $switchto = $lonhost;
1.23 raeburn 156: if ($rule_in_effect ne 'offloadedto') {
1.18 raeburn 157: my $hosthere;
1.23 raeburn 158: my @ids=&Apache::lonnet::current_machine_ids();
159: unless ($rule_in_effect eq 'balancer') {
160: if (grep(/^\Q$rule_in_effect\E$/,@ids)) {
161: $hosthere = 1;
162: }
163: }
164: unless ($hosthere) {
165: if ($dataref->{'role'}) {
166: my ($adom,$aname);
167: if ($dataref->{'role'} =~ m{^au\./($match_domain)/$}) {
168: $adom = $1;
169: $aname = $dataref->{'username'};
170: } elsif ($dataref->{'role'} =~ m{^(?:ca|aa)\./($match_domain)/($match_username)$}) {
171: $adom = $1;
172: $aname = $2;
173: }
174: if ($adom ne '' && $aname ne '') {
175: my $ahome = &Apache::lonnet::homeserver($aname,$adom);
176: unless ($ahome eq 'no_host') {
177: if ($ahome && grep(/^\Q$ahome\E$/,@ids)) {
178: $hosthere = 1;
179: }
1.18 raeburn 180: }
181: }
182: }
183: }
1.23 raeburn 184: unless ($hosthere) {
185: my $hostname;
186: if ($rule_in_effect eq 'balancer') {
187: $hostname = &Apache::lonnet::hostname($dataref->{'server'});
188: if ($hostname) {
189: $switchto = $dataref->{'server'};
190: }
191: } else {
192: $hostname = &Apache::lonnet::hostname($rule_in_effect);
193: if ($hostname) {
194: $switchto = $rule_in_effect;
195: }
196: }
1.18 raeburn 197: if ($hostname) {
198: my $protocol = $Apache::lonnet::protocol{$switchto};
199: $protocol = 'http' if ($protocol ne 'https');
200: $url = $protocol.'://'.$hostname;
1.23 raeburn 201: if ($rule_in_effect eq 'balancer') {
202: $message .= '<br />'.
203: &mt('As a result, your LON-CAPA session is being redirected to the server where you originally logged in.');
204: } else {
205: $message .= '<br />'.
206: &mt('As a result, your LON-CAPA session is being redirected.');
207: }
1.18 raeburn 208: }
209: }
210: }
211: if ($dataref->{'sso.login'}) {
1.21 raeburn 212: $url .= '/adm/roles';
1.18 raeburn 213: } else {
1.21 raeburn 214: $url .= '/adm/login';
1.24 raeburn 215: if ($udom) {
216: $url .= '?domain='.$udom;
217: }
1.20 raeburn 218: $message .= '<br />'.&mt('You will need to provide your password one more time.');
1.18 raeburn 219: }
220: my %info= (
1.24 raeburn 221: 'domain' => $udom,
1.18 raeburn 222: 'username' => $dataref->{'username'},
223: 'role' => $dataref->{'role'},
224: 'sessionserver' => $lonhost,
225: );
226: if ($dataref->{'origurl'}) {
227: $info{'origurl'} = $dataref->{'origurl'};
228: }
229: if ($dataref->{'symb'}) {
230: $info{'symb'} = $dataref->{'symb'};
231: }
232: my $iptoken = &Apache::lonnet::tmpput(\%info,$switchto);
233: unless ($iptoken eq 'conlost') {
1.24 raeburn 234: $url .= ($url =~ /\?/) ? '&' : '?';
235: $url .= 'iptoken='.$iptoken;
1.18 raeburn 236: }
237: $r->print(&Apache::loncommon::start_page($title,undef,
238: {'redirect' =>
239: [2,$url],}).
240: '<h1>'.&mt('One moment please...').'</h1>'.
241: '<p class="LC_warning">'.$message.'</p>'.
242: &Apache::loncommon::end_page());
243: } else {
244: return &goto_login($r);
1.10 raeburn 245: }
1.18 raeburn 246: return OK;
1.7 albertel 247: }
248:
1.1 albertel 249: sub handler {
250: my ($r) = @_;
251:
252: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['token']);
1.4 albertel 253: my %data = &Apache::lonnet::tmpget($env{'form.token'});
1.13 raeburn 254: if (keys(%data) == 0) {
255: return &goto_login($r);
256: }
1.4 albertel 257: my $delete = &Apache::lonnet::tmpdel($env{'form.token'});
258:
1.6 albertel 259: &Apache::lonlocal::get_language_handle($r);
260:
1.4 albertel 261: if ($delete ne 'ok') {
1.27 ! raeburn 262: return &goto_login($r,undef,\%data);
1.4 albertel 263: }
1.2 albertel 264:
1.18 raeburn 265: if (!defined($data{'username'}) || !defined($data{'domain'})) {
1.27 ! raeburn 266: return &goto_login($r,undef,\%data);
1.18 raeburn 267: }
268: if ($data{'ip'} ne $ENV{'REMOTE_ADDR'}) {
1.24 raeburn 269: &Apache::lonnet::logthis('IP change when session migration requested -- was: '.
270: $data{'ip'}.'; now: '.$ENV{'REMOTE_ADDR'}.' for '.$data{'username'}.':'.$data{'domain'});
1.18 raeburn 271: return &ip_changed($r,$data{'domain'},$data{'server'},\%data);
1.2 albertel 272: }
273:
1.17 raeburn 274: &Apache::lonnet::logthis("Allowing access for $data{'username'}:$data{'domain'} to $data{'role'}");
1.2 albertel 275: my $home=&Apache::lonnet::homeserver($data{'username'},$data{'domain'});
1.24 raeburn 276: my $udom;
277: if (&Apache::lonnet::domain($data{'domain'})) {
278: $udom=$data{'domain'};
279: }
1.27 ! raeburn 280: if ($home =~ /(con_lost|no_such_host)/) { return &goto_login($r,$udom,\%data); }
! 281:
! 282: my $sso_env = &sso_check(\%data);
! 283: my $lti_env = <i_check(\%data);
1.2 albertel 284:
1.27 ! raeburn 285: my $extra_env;
! 286: if ((ref($sso_env) eq 'HASH') && (keys(%{$sso_env}))) {
! 287: $extra_env = $sso_env;
! 288: } elsif ((ref($lti_env) eq 'HASH') && (keys(%{$lti_env}))) {
! 289: $extra_env = $lti_env;
! 290: }
1.8 albertel 291:
1.16 raeburn 292: my %form;
293: if ($data{'symb'} ne '') {
294: $form{'symb'} = $data{'symb'};
295: }
1.21 raeburn 296: if ($data{'iptoken'} ne '') {
297: $form{'iptoken'} = $data{'iptoken'};
298: }
1.25 raeburn 299: if ($data{'noloadbalance'} ne '') {
300: $form{'noloadbalance'} = $data{'noloadbalance'};
301: }
1.16 raeburn 302:
1.3 albertel 303: if (!$data{'role'}) {
1.12 albertel 304: my $handle = &Apache::lonnet::check_for_valid_session($r);
305: if ($handle) {
1.11 albertel 306: &Apache::lonnet::transfer_profile_to_env($r->dir_config('lonIDsDir'),
307: $handle);
1.27 ! raeburn 308: #FIXME if user is not currently logged in as an LTI log-in log them out.
! 309: if ($data{'lti.login'}) {
! 310: if (($data{'lti.reqcrs'}) && ($data{'lti.reqrole'} eq 'cc')) {
! 311: $form{'lti.reqcrs'} = $data{'lti.reqcrs'};
! 312: $form{'lti.reqrole'} = $data{'lti.reqrole'};
! 313: $form{'lti.sourcecrs'} = $data{'lti.sourcecrs'};
! 314: &Apache::loncommon::content_type($r,'text/html');
! 315: $r->send_http_header;
! 316: &Apache::ltiauth::lti_reqcrs($r,$data{'domain'},\%form,$data{'username'},$data{'domain'});
! 317: } elsif ($data{'lti.selfenrollrole'}) {
! 318: if (&Apache::ltiauth::lti_enroll($data{'username'},data{'domain'},
! 319: $data{'lti.selfenrollrole'}) eq 'ok') {
! 320: my $url = '/adm/roles?selectrole=1&'.
! 321: &escape($data{'lti.selfenrollrole'}).'=1';
! 322: if ($data{'origurl'} =~ m{/default_\d+\.sequence$}) {
! 323: $url .= '&orgurl='.$data{'origurl'}.'&navmap=1';
! 324: } elsif ($data{'origurl'} ne '') {
! 325: $url .= '&orgurl='.$data{'origurl'};
! 326: }
! 327: $r->internal_redirect($url);
! 328: } else {
! 329: &Apache::ltiauth::invalid_request($r,23);
! 330: }
! 331: } elsif ($data{'origurl'} ne '') {
! 332: my $url = $data{'origurl'};
! 333: if ($url =~ m{/default_\d+\.sequence$}) {
! 334: $url .= (($url =~/\?/)?'&':'?').'navmap=1';
! 335: }
! 336: $r->internal_redirect($url);
! 337: }
! 338: } elsif ($data{'origurl'} ne '') {
1.14 raeburn 339: $r->internal_redirect($data{'origurl'});
340: } elsif ($env{'request.course.id'}) {
341: $r->internal_redirect('/adm/navmaps');
1.11 albertel 342: } else {
343: $r->internal_redirect('/adm/roles');
344: }
345: } else {
1.14 raeburn 346: my $desturl = '/adm/roles';
347: if ($data{'origurl'} ne '') {
348: $desturl = $data{'origurl'};
1.27 ! raeburn 349: if ($data{'lti.login'}) {
! 350: $desturl = $data{'origurl'};
! 351: if ($desturl =~ m{/default_\d+\.sequence$}) {
! 352: $desturl .= (($desturl =~/\?/)?'&':'?').'navmap=1';
! 353: }
! 354: }
! 355: }
! 356: my $skipcritical;
! 357: if (($data{'lti.login'}) && ($data{'lti.reqcrs'}) &&
! 358: ($data{'lti.reqrole'} eq 'cc')) {
! 359: $skipcritical = 1;
1.14 raeburn 360: }
1.11 albertel 361: &Apache::lonauth::success($r,$data{'username'},$data{'domain'},
1.27 ! raeburn 362: $home,$desturl,$extra_env,\%form,$skipcritical);
1.11 albertel 363: }
1.1 albertel 364: return OK;
365: }
1.6 albertel 366:
367: my $next_url='/adm/roles?selectrole=1&'.&escape($data{'role'}).'=1';
1.15 raeburn 368: if ($data{'origurl'} ne '') {
369: $next_url .= '&orgurl='.&escape($data{'origurl'});
370: }
1.6 albertel 371: &Apache::lonauth::success($r,$data{'username'},$data{'domain'},$home,
1.16 raeburn 372: $next_url,$extra_env,\%form);
1.6 albertel 373: return OK;
1.1 albertel 374: }
375:
376: 1;
377: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>