예제 #1
0
 /**
  * Returns the logged in user, or default user if not logged in
  *
  * @param TBGRequest $request
  * @param TBGAction  $action
  *
  * @return TBGUser
  */
 public static function loginCheck(TBGRequest $request, TBGAction $action)
 {
     try {
         $authentication_method = $action->getAuthenticationMethodForAction(TBGContext::getRouting()->getCurrentRouteAction());
         $user = null;
         $external = false;
         switch ($authentication_method) {
             case TBGAction::AUTHENTICATION_METHOD_ELEVATED:
             case TBGAction::AUTHENTICATION_METHOD_CORE:
                 $username = $request['tbg3_username'];
                 $password = $request['tbg3_password'];
                 if ($authentication_method == TBGAction::AUTHENTICATION_METHOD_ELEVATED) {
                     $elevated_password = $request['tbg3_elevated_password'];
                 }
                 $raw = true;
                 // If no username and password specified, check if we have a session that exists already
                 if ($username === null && $password === null) {
                     if (TBGContext::getRequest()->hasCookie('tbg3_username') && TBGContext::getRequest()->hasCookie('tbg3_password')) {
                         $username = TBGContext::getRequest()->getCookie('tbg3_username');
                         $password = TBGContext::getRequest()->getCookie('tbg3_password');
                         $user = TBGUsersTable::getTable()->getByUsername($username);
                         if ($authentication_method == TBGAction::AUTHENTICATION_METHOD_ELEVATED) {
                             $elevated_password = TBGContext::getRequest()->getCookie('tbg3_elevated_password');
                             if ($user instanceof TBGUser && !$user->hasPasswordHash($password)) {
                                 $user = null;
                             } else {
                                 if ($user instanceof TBGUser && !$user->hasPasswordHash($elevated_password)) {
                                     TBGContext::setUser($user);
                                     TBGContext::getRouting()->setCurrentRouteName('elevated_login_page');
                                     throw new TBGElevatedLoginException('reenter');
                                 }
                             }
                         } else {
                             if ($user instanceof TBGUser && !$user->hasPasswordHash($password)) {
                                 $user = null;
                             }
                         }
                         $raw = false;
                         if (!$user instanceof TBGUser) {
                             TBGContext::logout();
                             throw new Exception('No such login');
                         }
                     }
                 }
                 // If we have authentication details, validate them
                 if (TBGSettings::isUsingExternalAuthenticationBackend() && $username !== null && $password !== null) {
                     $external = true;
                     TBGLogging::log('Authenticating with backend: ' . TBGSettings::getAuthenticationBackend(), 'auth', TBGLogging::LEVEL_INFO);
                     try {
                         $mod = TBGContext::getModule(TBGSettings::getAuthenticationBackend());
                         if ($mod->getType() !== TBGModule::MODULE_AUTH) {
                             TBGLogging::log('Auth module is not the right type', 'auth', TBGLogging::LEVEL_FATAL);
                         }
                         if (TBGContext::getRequest()->hasCookie('tbg3_username') && TBGContext::getRequest()->hasCookie('tbg3_password')) {
                             $user = $mod->verifyLogin($username, $password);
                         } else {
                             $user = $mod->doLogin($username, $password);
                         }
                         if (!$user instanceof TBGUser) {
                             // Invalid
                             TBGContext::logout();
                             throw new Exception('No such login');
                             //TBGContext::getResponse()->headerRedirect(TBGContext::getRouting()->generate('login'));
                         }
                     } catch (Exception $e) {
                         throw $e;
                     }
                 } elseif (TBGSettings::isUsingExternalAuthenticationBackend()) {
                     $external = true;
                     TBGLogging::log('Authenticating without credentials with backend: ' . TBGSettings::getAuthenticationBackend(), 'auth', TBGLogging::LEVEL_INFO);
                     try {
                         $mod = TBGContext::getModule(TBGSettings::getAuthenticationBackend());
                         if ($mod->getType() !== TBGModule::MODULE_AUTH) {
                             TBGLogging::log('Auth module is not the right type', 'auth', TBGLogging::LEVEL_FATAL);
                         }
                         $user = $mod->doAutoLogin();
                         if ($user == false) {
                             // Invalid
                             TBGContext::logout();
                             throw new Exception('No such login');
                             //TBGContext::getResponse()->headerRedirect(TBGContext::getRouting()->generate('login'));
                         }
                     } catch (Exception $e) {
                         throw $e;
                     }
                 } elseif ($username !== null && $password !== null && !$user instanceof TBGUser) {
                     $external = false;
                     TBGLogging::log('Using internal authentication', 'auth', TBGLogging::LEVEL_INFO);
                     $user = TBGUsersTable::getTable()->getByUsername($username);
                     if (!$user->hasPassword($password)) {
                         $user = null;
                     }
                     if (!$user instanceof TBGUser) {
                         TBGContext::logout();
                     }
                 }
                 break;
             case TBGAction::AUTHENTICATION_METHOD_DUMMY:
                 $user = TBGUsersTable::getTable()->getByUserID(TBGSettings::getDefaultUserID());
                 break;
             case TBGAction::AUTHENTICATION_METHOD_CLI:
                 $user = TBGUsersTable::getTable()->getByUsername(TBGContext::getCurrentCLIusername());
                 break;
             case TBGAction::AUTHENTICATION_METHOD_RSS_KEY:
                 $user = TBGUsersTable::getTable()->getByRssKey($request['rsskey']);
                 break;
             case TBGAction::AUTHENTICATION_METHOD_APPLICATION_PASSWORD:
                 $user = TBGUsersTable::getTable()->getByUsername($request['api_username']);
                 if (!$user->authenticateApplicationPassword($request['api_token'])) {
                     $user = null;
                 }
                 break;
             default:
                 if (!TBGSettings::isLoginRequired()) {
                     $user = TBGUsersTable::getTable()->getByUserID(TBGSettings::getDefaultUserID());
                 }
         }
         if ($user instanceof TBGUser) {
             if (!$user->isActivated()) {
                 throw new Exception('This account has not been activated yet');
             } elseif (!$user->isEnabled()) {
                 throw new Exception('This account has been suspended');
             } elseif (!$user->isConfirmedMemberOfScope(TBGContext::getScope())) {
                 if (!TBGSettings::isRegistrationAllowed()) {
                     throw new Exception('This account does not have access to this scope');
                 }
             }
             if ($external == false && $authentication_method == TBGAction::AUTHENTICATION_METHOD_CORE) {
                 $password = $user->getHashPassword();
                 if (!$request->hasCookie('tbg3_username')) {
                     if ($request->getParameter('tbg3_rememberme')) {
                         TBGContext::getResponse()->setCookie('tbg3_username', $user->getUsername());
                         TBGContext::getResponse()->setCookie('tbg3_password', $user->getPassword());
                     } else {
                         TBGContext::getResponse()->setSessionCookie('tbg3_username', $user->getUsername());
                         TBGContext::getResponse()->setSessionCookie('tbg3_password', $user->getPassword());
                     }
                 }
             }
         } elseif (TBGSettings::isLoginRequired()) {
             throw new Exception('Login required');
         } else {
             throw new Exception('No such login');
         }
     } catch (Exception $e) {
         throw $e;
     }
     return $user;
 }
 public static function processCommit(TBGProject $project, $commit_msg, $old_rev, $new_rev, $date = null, $changed, $author, $branch = null)
 {
     $output = '';
     TBGContext::setCurrentProject($project);
     if ($project->isArchived()) {
         return;
     }
     try {
         TBGContext::getI18n();
     } catch (Exception $e) {
         TBGContext::reinitializeI18n(null);
     }
     // Is VCS Integration enabled?
     if (TBGSettings::get('vcs_mode_' . $project->getID(), 'vcs_integration') == TBGVCSIntegration::MODE_DISABLED) {
         $output .= '[VCS ' . $project->getKey() . '] This project does not use VCS Integration' . "\n";
         return $output;
     }
     // Parse the commit message, and obtain the issues and transitions for issues.
     $parsed_commit = TBGIssue::getIssuesFromTextByRegex($commit_msg);
     $issues = $parsed_commit["issues"];
     $transitions = $parsed_commit["transitions"];
     // If no issues exist, we may not be able to continue
     //			if (count($issues) == 0)
     //			{
     //				$output .= '[VCS '.$project->getKey().'] This project only accepts commits which affect issues' . "\n";
     //				return $output;
     //			}
     // Build list of affected files
     $file_lines = preg_split('/[\\n\\r]+/', $changed);
     $files = array();
     foreach ($file_lines as $aline) {
         $action = mb_substr($aline, 0, 1);
         if ($action == "A" || $action == "U" || $action == "D" || $action == "M") {
             $theline = trim(mb_substr($aline, 1));
             $files[] = array($action, $theline);
         }
     }
     // Find author of commit, fallback is guest
     /*
      * Some VCSes use a different format of storing the committer's name. Systems like bzr, git and hg use the format
      * Joe Bloggs <*****@*****.**>, instead of a classic username. Therefore a user will be found via 4 queries:
      * a) First we extract the email if there is one, and find a user with that email
      * b) If one is not found - or if no email was specified, then instead test against the real name (using the name part if there was an email)
      * c) the username or full name is checked against the friendly name field
      * d) and if we still havent found one, then we check against the username
      * e) and if we STILL havent found one, we use the guest user
      */
     if (preg_match("/(?<=<)(.*)(?=>)/", $author, $matches)) {
         $email = $matches[0];
         // a)
         $user = TBGUsersTable::getTable()->getByEmail($email);
         if (!$user instanceof TBGUser) {
             // Not found by email
             preg_match("/(?<=^)(.*)(?= <)/", $author, $matches);
             $author = $matches[0];
         }
     }
     // b)
     if (!$user instanceof TBGUser) {
         $user = TBGUsersTable::getTable()->getByRealname($author);
     }
     // c)
     if (!$user instanceof TBGUser) {
         $user = TBGUsersTable::getTable()->getByBuddyname($author);
     }
     // d)
     if (!$user instanceof TBGUser) {
         $user = TBGUsersTable::getTable()->getByUsername($author);
     }
     // e)
     if (!$user instanceof TBGUser) {
         $user = TBGSettings::getDefaultUser();
     }
     TBGContext::setUser($user);
     TBGSettings::forceSettingsReload();
     TBGContext::cacheAllPermissions();
     $output .= '[VCS ' . $project->getKey() . '] Commit to be logged by user ' . $user->getName() . "\n";
     if ($date == null) {
         $date = NOW;
     }
     // Create the commit data
     $commit = new TBGVCSIntegrationCommit();
     $commit->setAuthor($user);
     $commit->setDate($date);
     $commit->setLog($commit_msg);
     $commit->setPreviousRevision($old_rev);
     $commit->setRevision($new_rev);
     $commit->setProject($project);
     if ($branch !== null) {
         $data = 'branch:' . $branch;
         $commit->setMiscData($data);
     }
     $commit->save();
     $output .= '[VCS ' . $project->getKey() . '] Commit logged with revision ' . $commit->getRevision() . "\n";
     // Iterate over affected issues and update them.
     foreach ($issues as $issue) {
         $inst = new TBGVCSIntegrationIssueLink();
         $inst->setIssue($issue);
         $inst->setCommit($commit);
         $inst->save();
         // Process all commit-message transitions for an issue.
         foreach ($transitions[$issue->getFormattedIssueNo()] as $transition) {
             if (TBGSettings::get('vcs_workflow_' . $project->getID(), 'vcs_integration') == TBGVCSIntegration::WORKFLOW_ENABLED) {
                 TBGContext::setUser($user);
                 TBGSettings::forceSettingsReload();
                 TBGContext::cacheAllPermissions();
                 if ($issue->isWorkflowTransitionsAvailable()) {
                     // Go through the list of possible transitions for an issue. Only
                     // process transitions that are applicable to issue's workflow.
                     foreach ($issue->getAvailableWorkflowTransitions() as $possible_transition) {
                         if (mb_strtolower($possible_transition->getName()) == mb_strtolower($transition[0])) {
                             $output .= '[VCS ' . $project->getKey() . '] Running transition ' . $transition[0] . ' on issue ' . $issue->getFormattedIssueNo() . "\n";
                             // String representation of parameters. Used for log message.
                             $parameters_string = "";
                             // Iterate over the list of this transition's parameters, and
                             // set them.
                             foreach ($transition[1] as $parameter => $value) {
                                 $parameters_string .= "{$parameter}={$value} ";
                                 switch ($parameter) {
                                     case 'resolution':
                                         if (($resolution = TBGResolution::getResolutionByKeyish($value)) instanceof TBGResolution) {
                                             TBGContext::getRequest()->setParameter('resolution_id', $resolution->getID());
                                         }
                                         break;
                                     case 'status':
                                         if (($status = TBGStatus::getStatusByKeyish($value)) instanceof TBGStatus) {
                                             TBGContext::getRequest()->setParameter('status_id', $status->getID());
                                         }
                                         break;
                                 }
                             }
                             // Run the transition.
                             $possible_transition->transitionIssueToOutgoingStepWithoutRequest($issue);
                             // Log an informative message about the transition.
                             $output .= '[VCS ' . $project->getKey() . '] Ran transition ' . $possible_transition->getName() . ' with parameters \'' . $parameters_string . '\' on issue ' . $issue->getFormattedIssueNo() . "\n";
                         }
                     }
                 }
             }
         }
         $issue->addSystemComment(TBGContext::getI18n()->__('This issue has been updated with the latest changes from the code repository.<source>%commit_msg</source>', array('%commit_msg' => $commit_msg)), $user->getID());
         $output .= '[VCS ' . $project->getKey() . '] Updated issue ' . $issue->getFormattedIssueNo() . "\n";
     }
     // Create file links
     foreach ($files as $afile) {
         // index 0 is action, index 1 is file
         $inst = new TBGVCSIntegrationFile();
         $inst->setAction($afile[0]);
         $inst->setFile($afile[1]);
         $inst->setCommit($commit);
         $inst->save();
         $output .= '[VCS ' . $project->getKey() . '] Added with action ' . $afile[0] . ' file ' . $afile[1] . "\n";
     }
     TBGEvent::createNew('vcs_integration', 'new_commit')->trigger(array('commit' => $commit));
     return $output;
 }
예제 #3
0
 /**
  * Do login (AJAX call)
  *  
  * @param TBGRequest $request
  */
 public function runDoLogin(TBGRequest $request)
 {
     $i18n = TBGContext::getI18n();
     $options = $request->getParameters();
     $forward_url = TBGContext::getRouting()->generate('home');
     if ($request->hasParameter('persona') && $request['persona'] == 'true') {
         $url = 'https://verifier.login.persona.org/verify';
         $assert = filter_input(INPUT_POST, 'assertion', FILTER_UNSAFE_RAW, FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH);
         //Use the $_POST superglobal array for PHP < 5.2 and write your own filter
         $params = 'assertion=' . urlencode($assert) . '&audience=' . urlencode(TBGContext::getURLhost() . ':80');
         $ch = curl_init();
         $options = array(CURLOPT_URL => $url, CURLOPT_RETURNTRANSFER => TRUE, CURLOPT_POST => 2, CURLOPT_POSTFIELDS => $params);
         curl_setopt_array($ch, $options);
         $result = curl_exec($ch);
         curl_close($ch);
         $details = json_decode($result);
         $user = null;
         if ($details->status == 'okay') {
             $user = TBGUser::getByEmail($details->email);
             if ($user instanceof TBGUser) {
                 TBGContext::getResponse()->setCookie('tbg3_password', $user->getPassword());
                 TBGContext::getResponse()->setCookie('tbg3_username', $user->getUsername());
                 TBGContext::getResponse()->setCookie('tbg3_persona_session', true);
                 return $this->renderJSON(array('status' => 'login ok', 'redirect' => in_array($request['referrer_route'], array('home', 'login'))));
             }
         }
         if (!$user instanceof TBGUser) {
             $this->getResponse()->setHttpStatus(401);
             $this->renderJSON(array('message' => $this->getI18n()->__('Invalid login')));
         }
         return;
     }
     if (TBGSettings::isOpenIDavailable()) {
         $openid = new LightOpenID(TBGContext::getRouting()->generate('login_page', array(), false));
     }
     if (TBGSettings::isOpenIDavailable() && !$openid->mode && $request->isPost() && $request->hasParameter('openid_identifier')) {
         $openid->identity = $request->getRawParameter('openid_identifier');
         $openid->required = array('contact/email');
         $openid->optional = array('namePerson/first', 'namePerson/friendly');
         return $this->forward($openid->authUrl());
     } elseif (TBGSettings::isOpenIDavailable() && $openid->mode == 'cancel') {
         $this->error = TBGContext::getI18n()->__("OpenID authentication cancelled");
     } elseif (TBGSettings::isOpenIDavailable() && $openid->mode) {
         try {
             if ($openid->validate()) {
                 if ($this->getUser()->isAuthenticated() && !$this->getUser()->isGuest()) {
                     if (TBGOpenIdAccountsTable::getTable()->getUserIDfromIdentity($openid->identity)) {
                         TBGContext::setMessage('openid_used', true);
                         throw new Exception('OpenID already in use');
                     }
                     $user = $this->getUser();
                 } else {
                     $user = TBGUser::getByOpenID($openid->identity);
                 }
                 if ($user instanceof TBGUser) {
                     $attributes = $openid->getAttributes();
                     $email = array_key_exists('contact/email', $attributes) ? $attributes['contact/email'] : null;
                     if (!$user->getEmail()) {
                         if (array_key_exists('contact/email', $attributes)) {
                             $user->setEmail($attributes['contact/email']);
                         }
                         if (array_key_exists('namePerson/first', $attributes)) {
                             $user->setRealname($attributes['namePerson/first']);
                         }
                         if (array_key_exists('namePerson/friendly', $attributes)) {
                             $user->setBuddyname($attributes['namePerson/friendly']);
                         }
                         if (!$user->getNickname() || $user->isOpenIdLocked()) {
                             $user->setBuddyname($user->getEmail());
                         }
                         if (!$user->getRealname()) {
                             $user->setRealname($user->getBuddyname());
                         }
                         $user->save();
                     }
                     if (!$user->hasOpenIDIdentity($openid->identity)) {
                         TBGOpenIdAccountsTable::getTable()->addIdentity($openid->identity, $email, $user->getID());
                     }
                     TBGContext::getResponse()->setCookie('tbg3_password', $user->getPassword());
                     TBGContext::getResponse()->setCookie('tbg3_username', $user->getUsername());
                     if ($this->checkScopeMembership($user)) {
                         return true;
                     }
                     return $this->forward(TBGContext::getRouting()->generate(TBGSettings::get('returnfromlogin')));
                 } else {
                     $this->error = TBGContext::getI18n()->__("Didn't recognize this OpenID. Please log in using your username and password, associate it with your user account in your account settings and try again.");
                 }
             } else {
                 $this->error = TBGContext::getI18n()->__("Could not validate against the OpenID provider");
             }
         } catch (Exception $e) {
             $this->error = TBGContext::getI18n()->__("Could not validate against the OpenID provider: %message", array('%message' => htmlentities($e->getMessage(), ENT_COMPAT, TBGContext::getI18n()->getCharset())));
         }
     } elseif ($request->getMethod() == TBGRequest::POST) {
         try {
             if ($request->hasParameter('tbg3_username') && $request->hasParameter('tbg3_password') && $request['tbg3_username'] != '' && $request['tbg3_password'] != '') {
                 $user = TBGUser::loginCheck($request, $this);
                 TBGContext::setUser($user);
                 if ($this->checkScopeMembership($user)) {
                     return true;
                 }
                 if ($request->hasParameter('return_to')) {
                     $forward_url = $request['return_to'];
                 } else {
                     if (TBGSettings::get('returnfromlogin') == 'referer') {
                         $forward_url = $request->getParameter('tbg3_referer', TBGContext::getRouting()->generate('dashboard'));
                     } else {
                         $forward_url = TBGContext::getRouting()->generate(TBGSettings::get('returnfromlogin'));
                     }
                 }
                 $forward_url = htmlentities($forward_url, ENT_COMPAT, TBGContext::getI18n()->getCharset());
             } else {
                 throw new Exception('Please enter a username and password');
             }
         } catch (Exception $e) {
             if ($request->isAjaxCall()) {
                 $this->getResponse()->setHttpStatus(401);
                 TBGLogging::log($e->getMessage(), 'openid', TBGLogging::LEVEL_WARNING_RISK);
                 return $this->renderJSON(array("error" => $i18n->__("Invalid login details")));
             } else {
                 $this->forward403($e->getMessage());
             }
         }
     } else {
         if ($request->isAjaxCall()) {
             $this->getResponse()->setHttpStatus(401);
             return $this->renderJSON(array("error" => $i18n->__('Please enter a username and password')));
         } else {
             $this->forward403($i18n->__('Please enter a username and password'));
         }
     }
     if ($this->checkScopeMembership($user)) {
         return true;
     }
     if ($request->isAjaxCall()) {
         return $this->renderJSON(array('forward' => $forward_url));
     } else {
         $this->forward($this->getRouting()->generate('account'));
     }
 }
예제 #4
0
 /**
  * Login (AJAX call)
  *  
  * @param TBGRequest $request
  */
 public function runLogin(TBGRequest $request)
 {
     $i18n = TBGContext::getI18n();
     $this->login_referer = array_key_exists('HTTP_REFERER', $_SERVER) && isset($_SERVER['HTTP_REFERER']) ? $_SERVER['HTTP_REFERER'] : '';
     $options = $request->getParameters();
     $forward_url = TBGContext::getRouting()->generate('home');
     try {
         if ($request->getMethod() == TBGRequest::POST) {
             if ($request->hasParameter('tbg3_username') && $request->hasParameter('tbg3_password')) {
                 $username = $request->getParameter('tbg3_username');
                 $password = $request->getParameter('tbg3_password');
                 $user = TBGUser::loginCheck($username, $password, true);
                 $this->getResponse()->setCookie('tbg3_username', $username);
                 $this->getResponse()->setCookie('tbg3_password', TBGUser::hashPassword($password));
                 TBGContext::setUser($user);
                 if ($request->hasParameter('return_to')) {
                     $forward_url = $request->getParameter('return_to');
                 } else {
                     if (TBGSettings::get('returnfromlogin') == 'referer') {
                         if ($request->getParameter('tbg3_referer')) {
                             $forward_url = $request->getParameter('tbg3_referer');
                         } else {
                             $forward_url = TBGContext::getRouting()->generate('dashboard');
                         }
                     } else {
                         $forward_url = TBGContext::getRouting()->generate(TBGSettings::get('returnfromlogin'));
                     }
                 }
             } else {
                 throw new Exception($i18n->__('Please enter a username and password'));
             }
         } elseif (TBGSettings::isLoginRequired()) {
             throw new Exception($i18n->__('You need to log in to access this site'));
         } elseif (!TBGContext::getUser()->isAuthenticated()) {
             throw new Exception($i18n->__('Please log in'));
         } elseif (TBGContext::hasMessage('forward')) {
             throw new Exception($i18n->__(TBGContext::getMessageAndClear('forward')));
         }
     } catch (Exception $e) {
         if (TBGContext::getRequest()->isAjaxCall() || TBGContext::getRequest()->getRequestedFormat() == 'json') {
             return $this->renderJSON(array('failed' => true, "error" => $i18n->__($e->getMessage()), 'referer' => $request->getParameter('tbg3_referer')));
         } else {
             $options['error'] = $e->getMessage();
         }
     }
     if (TBGContext::getRequest()->isAjaxCall() || TBGContext::getRequest()->getRequestedFormat() == 'json') {
         return $this->renderJSON(array('forward' => $forward_url));
     } elseif ($forward_url !== null && $request->getParameter('continue') != true) {
         $this->forward($forward_url);
     }
     $this->options = $options;
 }