<commit_before><?php
/**
 * COmanage Registry CO Invite Model
 *
 * Portions licensed to the University Corporation for Advanced Internet
 * Development, Inc. ("UCAID") under one or more contributor license agreements.
 * See the NOTICE file distributed with this work for additional information
 * regarding copyright ownership.
 *
 * UCAID licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at:
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @link          http://www.internet2.edu/comanage COmanage Project
 * @package       registry
 * @since         COmanage Registry v0.1
 * @license       Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
 */

App::uses('CakeEmail', 'Network/Email');

class CoInvite extends AppModel {
  // Define class name for cake
  public $name = "CoInvite";
  
  // Current schema version for API
  public $version = "1.0";
  
  // Add behaviors
  public $actsAs = array('Containable',
                         'Changelog' => array('priority' => 5));
  
  // Association rules from this model to other models
  public $belongsTo = array("CoPerson",
                            "EmailAddress");
  
  public $hasOne = array("CoPetition");
  
  // Default display field for cake generated views
  public $displayField = "invitation";
  
  // Default ordering for find operations
  public $order = "expires";
  
  // Validation rules for table elements
  public $validate = array(
    'invitation' => array(
      'rule' => 'alphaNumeric',
      'required' => true
    ),
    'co_person_id' => array(
      'rule' => 'notBlank',
      'required' => true
    ),
    'mail' => array(
      'rule' => 'email',
      'required' => false,
      'allowEmpty' => true
    ),
    'email_address_id' => array(
      'rule' => 'numeric',
      'required' => false,
      'allowEmpty' => true
    ),
    'expires' => array(
      'rule' => '/.*/',  // The 'date' rule is too constraining
      'required' => false,
      'allowEmpty' => true
    )
  );
  
  /**
   * Process the reply to an invite.
   *
   * @since  COmanage Registry v0.7
   * @param  Integer CO Invite ID
   * @param  Boolean If true, confirm the invitation; if false, decline it
   * @param  String Login identifier, if authentication is needed for this invite
   * @throws InvalidArgumentException
   * @throws OutOfBoundsException
   * @throws RuntimeException
   */
  
  public function processReply($inviteId, $confirm, $loginIdentifier=null) {
    // Start a transaction
    $dbc = $this->getDataSource();
    $dbc->begin();
    
    $args = array();
    $args['conditions']['CoInvite.invitation'] = $inviteId;
    $args['contain'] = array('CoPerson', 'CoPetition', 'EmailAddress');
    
    $invite = $this->find('first', $args);
    
    if(!empty($invite)) {
      $verifyEmail = !empty($invite['CoInvite']['email_address_id']);
      
      // Check invite validity
      
      if(time() < strtotime($invite['CoInvite']['expires'])) {
        if($verifyEmail) {
          // Verifying an email address
          
          try {
            // XXX Note we're passing a bunch of stuff just so verify() can create a history record,
            // which we do below anyway. Refactor as part of CO-753.
            $this->CoPerson->EmailAddress->verify($invite['EmailAddress']['org_identity_id'],
                                                  $invite['EmailAddress']['co_person_id'],
                                                  $invite['CoInvite']['mail'],
                                                  $invite['EmailAddress']['co_person_id']);
          }
          catch(Exception $e) {
            $dbc->rollback();
            throw new RuntimeException($e->getMessage());
          }
        } elseif(isset($invite['CoPetition']['id'])) {
          // Before we can delete the invitation, we need to unlink it from the petition
          
          $this->CoPetition->id = $invite['CoPetition']['id'];
          $this->CoPetition->saveField('co_invite_id', null);
        } else {
          // Default (ie: non-enrollment flow) behavior: update CO Person
          
          $this->CoPerson->id = $invite['CoPerson']['id'];
          
          if(!$this->CoPerson->saveField('status', $confirm ? StatusEnum::Active : StatusEnum::Declined)) {
            $dbc->rollback();
            throw new RuntimeException(_txt('er.cop.nf', array($invite['CoPerson']['id'])));
          }
        }
        
        // Mark the email address associated with this invite as verified.
        
        if($confirm) {
          // For historical reasons, we don't attach the email_address_id to the invite
          // when we're in a petition context. (That's how we distinguish petition
          // vs not, above.) This all needs to get rewritten (currently scheduled
          // for v4.0.0), but in the mean time we have to check both Org Identity
          // and CO Person attached Email Addresses, since we might have confirmed
          // either one.
          
          $orgId = null;
          
          if(isset($invite['CoPetition']['enrollee_org_identity_id'])) {
            $orgId = $invite['CoPetition']['enrollee_org_identity_id'];
          } elseif(empty($invite['CoPetition'])) {
            // Try to find the org identity associated with this invite
            
            $args = array();
            $args['conditions']['CoOrgIdentityLink.co_person_id'] = $invite['CoPerson']['co_person_id'];
            $args['conditions']['EmailAddress.mail'] = $invite['CoInvite']['mail'];
            $args['joins'][0]['table'] = 'cm_email_addresses';
            $args['joins'][0]['alias'] = 'EmailAddress';
            $args['joins'][0]['type'] = 'INNER';<commit_msg>Fix incorrect array element (NOJIRA)<commit_after><?php
/**
 * COmanage Registry CO Invite Model
 *
 * Portions licensed to the University Corporation for Advanced Internet
 * Development, Inc. ("UCAID") under one or more contributor license agreements.
 * See the NOTICE file distributed with this work for additional information
 * regarding copyright ownership.
 *
 * UCAID licenses this file to you under the Apache License, Version 2.0
 * (the "License"); you may not use this file except in compliance with the
 * License. You may obtain a copy of the License at:
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 * @link          http://www.internet2.edu/comanage COmanage Project
 * @package       registry
 * @since         COmanage Registry v0.1
 * @license       Apache License, Version 2.0 (http://www.apache.org/licenses/LICENSE-2.0)
 */

App::uses('CakeEmail', 'Network/Email');

class CoInvite extends AppModel {
  // Define class name for cake
  public $name = "CoInvite";
  
  // Current schema version for API
  public $version = "1.0";
  
  // Add behaviors
  public $actsAs = array('Containable',
                         'Changelog' => array('priority' => 5));
  
  // Association rules from this model to other models
  public $belongsTo = array("CoPerson",
                            "EmailAddress");
  
  public $hasOne = array("CoPetition");
  
  // Default display field for cake generated views
  public $displayField = "invitation";
  
  // Default ordering for find operations
  public $order = "expires";
  
  // Validation rules for table elements
  public $validate = array(
    'invitation' => array(
      'rule' => 'alphaNumeric',
      'required' => true
    ),
    'co_person_id' => array(
      'rule' => 'notBlank',
      'required' => true
    ),
    'mail' => array(
      'rule' => 'email',
      'required' => false,
      'allowEmpty' => true
    ),
    'email_address_id' => array(
      'rule' => 'numeric',
      'required' => false,
      'allowEmpty' => true
    ),
    'expires' => array(
      'rule' => '/.*/',  // The 'date' rule is too constraining
      'required' => false,
      'allowEmpty' => true
    )
  );
  
  /**
   * Process the reply to an invite.
   *
   * @since  COmanage Registry v0.7
   * @param  Integer CO Invite ID
   * @param  Boolean If true, confirm the invitation; if false, decline it
   * @param  String Login identifier, if authentication is needed for this invite
   * @throws InvalidArgumentException
   * @throws OutOfBoundsException
   * @throws RuntimeException
   */
  
  public function processReply($inviteId, $confirm, $loginIdentifier=null) {
    // Start a transaction
    $dbc = $this->getDataSource();
    $dbc->begin();
    
    $args = array();
    $args['conditions']['CoInvite.invitation'] = $inviteId;
    $args['contain'] = array('CoPerson', 'CoPetition', 'EmailAddress');
    
    $invite = $this->find('first', $args);
    
    if(!empty($invite)) {
      $verifyEmail = !empty($invite['CoInvite']['email_address_id']);
      
      // Check invite validity
      
      if(time() < strtotime($invite['CoInvite']['expires'])) {
        if($verifyEmail) {
          // Verifying an email address
          
          try {
            // XXX Note we're passing a bunch of stuff just so verify() can create a history record,
            // which we do below anyway. Refactor as part of CO-753.
            $this->CoPerson->EmailAddress->verify($invite['EmailAddress']['org_identity_id'],
                                                  $invite['EmailAddress']['co_person_id'],
                                                  $invite['CoInvite']['mail'],
                                                  $invite['EmailAddress']['co_person_id']);
          }
          catch(Exception $e) {
            $dbc->rollback();
            throw new RuntimeException($e->getMessage());
          }
        } elseif(isset($invite['CoPetition']['id'])) {
          // Before we can delete the invitation, we need to unlink it from the petition
          
          $this->CoPetition->id = $invite['CoPetition']['id'];
          $this->CoPetition->saveField('co_invite_id', null);
        } else {
          // Default (ie: non-enrollment flow) behavior: update CO Person
          
          $this->CoPerson->id = $invite['CoPerson']['id'];
          
          if(!$this->CoPerson->saveField('status', $confirm ? StatusEnum::Active : StatusEnum::Declined)) {
            $dbc->rollback();
            throw new RuntimeException(_txt('er.cop.nf', array($invite['CoPerson']['id'])));
          }
        }
        
        // Mark the email address associated with this invite as verified.
        
        if($confirm) {
          // For historical reasons, we don't attach the email_address_id to the invite
          // when we're in a petition context. (That's how we distinguish petition
          // vs not, above.) This all needs to get rewritten (currently scheduled
          // for v4.0.0), but in the mean time we have to check both Org Identity
          // and CO Person attached Email Addresses, since we might have confirmed
          // either one.
          
          $orgId = null;
          
          if(isset($invite['CoPetition']['enrollee_org_identity_id'])) {
            $orgId = $invite['CoPetition']['enrollee_org_identity_id'];
          } elseif(empty($invite['CoPetition'])) {
            // Try to find the org identity associated with this invite
            
            $args = array();
            $args['conditions']['CoOrgIdentityLink.co_person_id'] = $invite['CoPerson']['id'];
            $args['conditions']['EmailAddress.mail'] = $invite['CoInvite']['mail'];
            $args['joins'][0]['table'] = 'cm_email_addresses';
            $args['joins'][0]['alias'] = 'EmailAddress';
            $args['joins'][0]['type'] = 'INNER';
{'fraction_non_alphanumeric': 0.13034689091938223, 'fraction_numerical': 0.004043017708417563, 'mean_word_length': 2.352670100298184, 'pattern_counts': {'":': 0, '<': 7, '<?xml version=': 0, '>': 77, 'https://': 0, 'lorem ipsum': 0, 'www.': 6, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 14, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '5862833', 'n_tokens_mistral': 3368, 'n_tokens_neox': 3320, 'n_words': 1009}