	public static function login() {
		user::login(expString::escape(expString::sanitize($_POST['username'])),expString::escape(expString::sanitize($_POST['password'])));
		if (!isset($_SESSION[SYS_SESSION_KEY]['user'])) {  // didn't successfully log in
			flash('error', gt('Invalid Username / Password'));
			if (expSession::is_set('redirecturl_error')) {
				$url = expSession::get('redirecturl_error');
				expSession::un_set('redirecturl_error');
				header("Location: ".$url);
			} else {
				expHistory::back();
			}
		} else {  // we're logged in
			global $user;

            if (expSession::get('customer-login')) expSession::un_set('customer-login');
			if (!empty($_POST['username'])) flash('message', gt('Welcome back').' '.expString::sanitize($_POST['username']));
            if ($user->isAdmin()) {
                expHistory::back();
            } else {
                foreach ($user->groups as $g) {
                    if (!empty($g->redirect)) {
                        $url = URL_FULL.$g->redirect;
                        break;
                    }
                }
                if (isset($url)) {
                    header("Location: ".$url);
                } else {
                    expHistory::back();
                }
            }
		}
	}
The software constructs all or part of an SQL command using externally-influenced input from an upstream component, but it does not neutralize or incorrectly neutralizes special elements that could modify the intended SQL command when it is sent to a downstream component.