File:
[LON-CAPA] /
loncom /
auth /
migrateuser.pm
Revision
1.27:
download - view:
text,
annotated -
select for diffs
Fri Mar 23 01:01:29 2018 UTC (6 years, 4 months ago) by
raeburn
Branches:
MAIN
CVS tags:
HEAD
- Bug 6754 LON-CAPA as LTI Provider
- Creation of new LON-CAPA user account available from an LTI Consumer.
- Creation of new LON-CAPA course available from an LTI Consumer.
- Self-enrollment in a LON-CAPA course available from an LTI Consumer.
1: # The LearningOnline Network
2: # Starts a user off based of an existing token.
3: #
4: # $Id: migrateuser.pm,v 1.27 2018/03/23 01:01:29 raeburn Exp $
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:
29: package Apache::migrateuser;
30:
31: use strict;
32: use LONCAPA qw(:DEFAULT :match);
33: use Apache::Constants qw(:common :http :methods);
34: use Apache::lonauth;
35: use Apache::lonnet;
36: use Apache::lonlocal;
37: use Apache::lonlogin();
38: use Apache::ltiauth;
39:
40: sub goto_login {
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: }
57: return OK;
58: }
59:
60: sub sso_check {
61: my ($data) = @_;
62: my %extra_env;
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: }
71: }
72: return \%extra_env;
73: }
74:
75: sub lti_check {
76: my ($data) = @_;
77: my %lti_env;
78: if (ref($data) eq 'HASH') {
79: if ($data->{'lti.login'}) {
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: }
90: }
91: if ($data->{'lti.passbackid'}) {
92: $lti_env{'request.lti.passbackid'} = $data->{'lti.passbackid'};
93: }
94: if ($data->{'lti.passbackurl'}) {
95: $lti_env{'request.lti.passbackurl'} = $data->{'lti.passbackurl'};
96: }
97: if ($data->{'lti.rosterid'}) {
98: $lti_env{'request.lti.rosterid'} = $data->{'lti.rosterid'};
99: }
100: if ($data->{'lti.rosterurl'}) {
101: $lti_env{'request.lti.rosterurl'} = $data->{'lti.rosterurl'};
102: }
103: }
104: return \%lti_env;
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;
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;
126: }
127: my ($result,$cached)=&Apache::lonnet::is_cached_new('loadbalancing',$dom_in_use);
128: unless (defined($cached)) {
129: my $cachetime = 60*60*24;
130: my %domconfig =
131: &Apache::lonnet::get_dom('configuration',['loadbalancing'],$dom_in_use);
132: if (ref($domconfig{'loadbalancing'}) eq 'HASH') {
133: $result = &Apache::lonnet::do_cache_new('loadbalancing',$dom_in_use,
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;
156: if ($rule_in_effect ne 'offloadedto') {
157: my $hosthere;
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: }
180: }
181: }
182: }
183: }
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: }
197: if ($hostname) {
198: my $protocol = $Apache::lonnet::protocol{$switchto};
199: $protocol = 'http' if ($protocol ne 'https');
200: $url = $protocol.'://'.$hostname;
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: }
208: }
209: }
210: }
211: if ($dataref->{'sso.login'}) {
212: $url .= '/adm/roles';
213: } else {
214: $url .= '/adm/login';
215: if ($udom) {
216: $url .= '?domain='.$udom;
217: }
218: $message .= '<br />'.&mt('You will need to provide your password one more time.');
219: }
220: my %info= (
221: 'domain' => $udom,
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') {
234: $url .= ($url =~ /\?/) ? '&' : '?';
235: $url .= 'iptoken='.$iptoken;
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);
245: }
246: return OK;
247: }
248:
249: sub handler {
250: my ($r) = @_;
251:
252: &Apache::loncommon::get_unprocessed_cgi($ENV{'QUERY_STRING'},['token']);
253: my %data = &Apache::lonnet::tmpget($env{'form.token'});
254: if (keys(%data) == 0) {
255: return &goto_login($r);
256: }
257: my $delete = &Apache::lonnet::tmpdel($env{'form.token'});
258:
259: &Apache::lonlocal::get_language_handle($r);
260:
261: if ($delete ne 'ok') {
262: return &goto_login($r,undef,\%data);
263: }
264:
265: if (!defined($data{'username'}) || !defined($data{'domain'})) {
266: return &goto_login($r,undef,\%data);
267: }
268: if ($data{'ip'} ne $ENV{'REMOTE_ADDR'}) {
269: &Apache::lonnet::logthis('IP change when session migration requested -- was: '.
270: $data{'ip'}.'; now: '.$ENV{'REMOTE_ADDR'}.' for '.$data{'username'}.':'.$data{'domain'});
271: return &ip_changed($r,$data{'domain'},$data{'server'},\%data);
272: }
273:
274: &Apache::lonnet::logthis("Allowing access for $data{'username'}:$data{'domain'} to $data{'role'}");
275: my $home=&Apache::lonnet::homeserver($data{'username'},$data{'domain'});
276: my $udom;
277: if (&Apache::lonnet::domain($data{'domain'})) {
278: $udom=$data{'domain'};
279: }
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);
284:
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: }
291:
292: my %form;
293: if ($data{'symb'} ne '') {
294: $form{'symb'} = $data{'symb'};
295: }
296: if ($data{'iptoken'} ne '') {
297: $form{'iptoken'} = $data{'iptoken'};
298: }
299: if ($data{'noloadbalance'} ne '') {
300: $form{'noloadbalance'} = $data{'noloadbalance'};
301: }
302:
303: if (!$data{'role'}) {
304: my $handle = &Apache::lonnet::check_for_valid_session($r);
305: if ($handle) {
306: &Apache::lonnet::transfer_profile_to_env($r->dir_config('lonIDsDir'),
307: $handle);
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 '') {
339: $r->internal_redirect($data{'origurl'});
340: } elsif ($env{'request.course.id'}) {
341: $r->internal_redirect('/adm/navmaps');
342: } else {
343: $r->internal_redirect('/adm/roles');
344: }
345: } else {
346: my $desturl = '/adm/roles';
347: if ($data{'origurl'} ne '') {
348: $desturl = $data{'origurl'};
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;
360: }
361: &Apache::lonauth::success($r,$data{'username'},$data{'domain'},
362: $home,$desturl,$extra_env,\%form,$skipcritical);
363: }
364: return OK;
365: }
366:
367: my $next_url='/adm/roles?selectrole=1&'.&escape($data{'role'}).'=1';
368: if ($data{'origurl'} ne '') {
369: $next_url .= '&orgurl='.&escape($data{'origurl'});
370: }
371: &Apache::lonauth::success($r,$data{'username'},$data{'domain'},$home,
372: $next_url,$extra_env,\%form);
373: return OK;
374: }
375:
376: 1;
377: __END__
FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>