Apache-Wyrd

 view release on metacpan or  search on metacpan

Wyrd/Services/Auth.pm  view on Meta::CPAN

				$challenge_failed = ($user->auth_error || 'Incorrect Username/Password.  Please log in again.');
			}
		} else {
			$debug && warn('challenge could not be decrypted, trying regular login again.');
			$challenge_failed = ($user->auth_error || 'Could not process the login because of system maintenance.  Please try again.');
		}
	}

	#no auth cookie or challenge.  Can the browser accept cookies?

	#if this req represents a cookie check, tell the user they must turn on cookies
	#if the test cookie is not present.
	if ($apr->param('check_cookie')) {
		unless ($cookie{'check_cookie'}) {
			my $no_cookie_url = $req->dir_config('NoCookieURL');
			$no_cookie_url = $scheme . '://' . $req->hostname . $port . $no_cookie_url unless ($no_cookie_url =~ /^http/i);
			$req->custom_response(REDIRECT, $no_cookie_url);
			return REDIRECT;
		}

	#if we have no knowledge of whether the browser can accept cookies at this point,
	#put it to the test by setting the cookie and forcing the browser to reload this page,
	#with the cookie_check variable set.
	} elsif($scheme ne 'https') {
		unless ($cookie{'check_cookie'}) {
			my $cookie = Apache::Wyrd::Cookie->new(
				$req,
				-name=>'check_cookie',
				-value=>'checking',
				-domain=>$req->hostname,
				-path=>($auth_path || '/')
			);
			$cookie->bake;
			my $query_char = '?';
			my $uri = $req->uri;
			$uri = Apache::URI->parse($uri);
			my $query_string = $uri->query;
			if ($query_string) {
				$query_char = '&';
				$query_string = '?' . $query_string;
			}
			my $scheme = $scheme;
			$req->custom_response(REDIRECT, $scheme . '://' . $req->hostname . $port . $req->uri . $query_string . $query_char . 'check_cookie=yes');
			return REDIRECT;
		}
	}
	
	#We have determined at this point that the user has no prior authorization, but that
	#cookies are enabled and they could be authorized.

	#require an SSL login server if this is an insecure port (currently always).
	#in future, 1 will be replaced with a test for SSL encryption.
	if (($ENV{'HTTPS'} ne 'on') or $force_login_server) {

		#Get an encryption key and a ticket number
		my ($key, $ticket) = $self->generate_ticket;

		#Send that pair to the Login Server
		$key_url = 'https://' . $req->hostname . $key_url unless ($key_url =~ /^https?:\/\//i);
		if ($key_url =~ /^https:\/\//i) {
			eval('use IO::Socket::SSL');
			die "LWP::UserAgent needs to support SSL to use a login server over https.  Install IO::Socket::SSL and make sure it works."
				if ($@);
		}
		my $ua = LWP::UserAgent->new;
		$ua->timeout(60);
		my $response = $ua->request(POST $key_url,
			[
				key		=>	$key,
				ticket	=>	$ticket
			]
		);
		my $status = $response->status_line;

		#If the key can't be saved on the login server, send regrets and close
		if ($status !~ /200|OK/) {
			if ($status =~ /Invalid argument/i) {
				$debug && warn ("You may need to Update IO::Socket::SSL");
			} else {
				$debug && warn ("Login Server status was $status");
			}
			my $failed_url = $req->dir_config('LSDownURL');
			$failed_url = $scheme . '://' . $req->hostname . $port . $failed_url unless ($failed_url =~ /^http/i);
			if ($failed_url) {
				$req->custom_response(REDIRECT, $failed_url);
				return REDIRECT;
			} else {
				return HTTP_SERVICE_UNAVAILABLE;
			}

		#Send the encrypted data as a lookup key to the login form to add
		#to its hidden fields.  If a challenge failed earlier in the script
		#and ReturnError is defined, use it.
		} else {
			my $use_error = $req->dir_config('ReturnError');
			my $login_url = $req->dir_config('LoginFormURL');
			$login_url = $scheme . '://' . $req->hostname . $port . $login_url unless ($login_url =~ /^http/i);
			my $ls_url = $req->dir_config('LSLoginURL');
			$ls_url = $scheme . '://' . $req->hostname . $port . $ls_url unless ($ls_url =~ /^http/i);
			if ($login_url) {
				my $uri = $req->uri;
				$uri = Apache::URI->parse($uri);
				my $query_string = $uri->query;
				$query_string =~ s/\&?check_cookie=yes\&?//;
				$query_string =~ s/challenge=[0123456789abcdefABCDEF:]+\&?//g;
				$query_string = '?' . $query_string if ($query_string);
				my $on_success = Apache::Util::escape_uri(encode_base64($scheme . '://' . $req->hostname . $port . $req->uri . $query_string));
				my $redirect = $login_url .
					'?ls=' . $ls_url .
					'&ticket=' . $ticket .
					'&on_success=' . $on_success .
					'&use_error=' . $use_error .
					($challenge_failed ? '&'. $use_error . '=' . $challenge_failed : '');
				$debug && warn('Need a login, with redirect going to ' . $redirect);
				$req->custom_response(REDIRECT, $redirect);
				return REDIRECT;
			} else {
				die "Must define LoginFormURL in Apache Config to use Apache::Wyrd::Services::Auth";
			}
		}

	#Since we are using SSL, we can accept login information as normal CGI params.
	} else {
		my $username = $apr->param('username');
		my $password = $apr->param('password');
		my $login_failed = '';
		if ($username) {
			my $user = $self->initialize({username => $username, password => $password});
			if ($user->login_ok) {
				$self->authorize_user($req, $user);
				my $uri = $req->uri;
				$uri = Apache::URI->parse($uri);
				my $redirect = $scheme . '://' . $req->hostname . $port . $req->uri . '?check_cookie=yes';
				$debug && warn('Setting a cookie, with redirect going to ' . $redirect);
				$req->custom_response(REDIRECT, $redirect);
				return REDIRECT;
			}
			$login_failed = 'Login failed.  Please check your username and password.';



( run in 1.924 second using v1.01-cache-2.11-cpan-98e64b0badf )