[smarcet] - initial commit
This commit is contained in:
commit
c09eca8cc4
46
.gitignore
vendored
Normal file
46
.gitignore
vendored
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
#assets
|
||||||
|
!assets/error-404.html
|
||||||
|
!assets/error-500.html
|
||||||
|
assets/*
|
||||||
|
|
||||||
|
sortablegridfield
|
||||||
|
framework
|
||||||
|
colorpicker
|
||||||
|
cms
|
||||||
|
translatable
|
||||||
|
vendor/
|
||||||
|
|
||||||
|
/openstack-marketing-portal/*
|
||||||
|
/blog/*
|
||||||
|
/cache/*
|
||||||
|
.htaccess
|
||||||
|
debug.log
|
||||||
|
openstack/_live-config.php
|
||||||
|
_ss_environment.php
|
||||||
|
simplepie/cache/*
|
||||||
|
silverstripe-cache/*
|
||||||
|
silverstripe-cache/
|
||||||
|
silverstripe-cache
|
||||||
|
/.buildpath
|
||||||
|
/.project
|
||||||
|
|
||||||
|
# PDT-specific
|
||||||
|
.buildpath
|
||||||
|
|
||||||
|
# Locally stored "Eclipse launch configurations"
|
||||||
|
*.launch
|
||||||
|
.settings/
|
||||||
|
|
||||||
|
.idea/
|
||||||
|
|
||||||
|
|
||||||
|
#composer
|
||||||
|
composer.lock
|
||||||
|
composer.phar
|
||||||
|
backup_scripts/cron-backup-config.php
|
||||||
|
logs
|
||||||
|
feeds/cache
|
||||||
|
logs/*
|
||||||
|
sapphire/thirdparty/htmlpurifier-4.4.0/library/HTMLPurifier/DefinitionCache/Serializer/HTML/
|
||||||
|
elections/input
|
||||||
|
blog
|
31
ICLA/_config.php
Normal file
31
ICLA/_config.php
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
//decorators
|
||||||
|
Object::add_extension('Member', 'ICLAMemberDecorator');
|
||||||
|
Object::add_extension('Company', 'ICLACompanyDecorator');
|
||||||
|
Object::add_extension('SangriaPage_Controller', 'SangriaPageICLACompaniesExtension');
|
||||||
|
Object::add_extension('EditProfilePage_Controller', 'EditProfilePageICLAExtension');
|
||||||
|
|
||||||
|
PublisherSubscriberManager::getInstance()->subscribe('new_user_registered', function($member_id){
|
||||||
|
//check if user has pending invitations
|
||||||
|
$team_manager = new CCLATeamManager(new SapphireTeamInvitationRepository,
|
||||||
|
new SapphireCLAMemberRepository,
|
||||||
|
new TeamInvitationFactory,
|
||||||
|
new TeamFactory,
|
||||||
|
new CCLAValidatorFactory,
|
||||||
|
new SapphireTeamRepository,
|
||||||
|
SapphireTransactionManager::getInstance());
|
||||||
|
|
||||||
|
$team_manager->verifyInvitations($member_id, new TeamInvitationEmailSender(new SapphireTeamInvitationRepository));
|
||||||
|
});
|
8
ICLA/_config/routes.yml
Normal file
8
ICLA/_config/routes.yml
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
---
|
||||||
|
Name: iclaroutes
|
||||||
|
After: 'framework/routes#coreroutes'
|
||||||
|
---
|
||||||
|
Director:
|
||||||
|
rules:
|
||||||
|
'api/v1/ccla': 'ICLARestfulAPI'
|
||||||
|
'team-invitations': 'TeamInvitationConfirmation_Controller'
|
105
ICLA/code/infrastructure/active_records/BatchTask.php
Normal file
105
ICLA/code/infrastructure/active_records/BatchTask.php
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class BatchTask
|
||||||
|
*/
|
||||||
|
final class BatchTask
|
||||||
|
extends DataObject
|
||||||
|
implements IBatchTask {
|
||||||
|
|
||||||
|
static $create_table_options = array('MySQLDatabase' => 'ENGINE=InnoDB');
|
||||||
|
|
||||||
|
static $db = array(
|
||||||
|
'Name' => 'Text',
|
||||||
|
'LastResponse' => 'Text',
|
||||||
|
'LastRecordIndex' => 'Int',
|
||||||
|
'LastResponseDate' => 'SS_Datetime',
|
||||||
|
'TotalRecords' => 'Int',
|
||||||
|
);
|
||||||
|
|
||||||
|
/***
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function name()
|
||||||
|
{
|
||||||
|
return (string)$this->getField('Name');
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function lastRecordProcessed()
|
||||||
|
{
|
||||||
|
return (int)$this->getField('LastRecordIndex');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function lastResponse()
|
||||||
|
{
|
||||||
|
return (string)$this->getField('LastResponse');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return DateTime
|
||||||
|
*/
|
||||||
|
public function lastResponseDate()
|
||||||
|
{
|
||||||
|
return new DateTime($this->getField('LastResponseDate'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function totalRecords()
|
||||||
|
{
|
||||||
|
return (int)$this->getField('TotalRecords');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $response
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function updateResponse($response)
|
||||||
|
{
|
||||||
|
$this->setField('LastResponse', $response);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function updateLastRecord()
|
||||||
|
{
|
||||||
|
$last = $this->lastRecordProcessed();
|
||||||
|
$this->setField('LastRecordIndex', $last+1 );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getIdentifier()
|
||||||
|
{
|
||||||
|
return (int)$this->getField('ID');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $total_qty
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function initialize($total_qty){
|
||||||
|
$this->setField('LastRecordIndex', 0 );
|
||||||
|
$this->setField('TotalRecords', $total_qty );
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,94 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class ICLACompanyDecorator
|
||||||
|
*/
|
||||||
|
class ICLACompanyDecorator
|
||||||
|
extends DataExtension
|
||||||
|
{
|
||||||
|
//Add extra database fields
|
||||||
|
|
||||||
|
private static $db = array(
|
||||||
|
'CCLASigned' => 'Boolean',
|
||||||
|
'CCLADate' => 'SS_Datetime',
|
||||||
|
);
|
||||||
|
|
||||||
|
private static $defaults = array(
|
||||||
|
'CCLASigned' => FALSE,
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
private static $has_many = array(
|
||||||
|
'Teams' => 'Team'
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function signICLA()
|
||||||
|
{
|
||||||
|
$this->owner->setField('CCLASigned',true);
|
||||||
|
$this->owner->setField('CCLADate', SS_Datetime::now()->Rfc2822());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function unsignICLA()
|
||||||
|
{
|
||||||
|
$this->owner->setField('CCLASigned',false);
|
||||||
|
$this->owner->setField('CCLADate', null);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isICLASigned()
|
||||||
|
{
|
||||||
|
return (bool)$this->owner->getField('CCLASigned');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return Datetime
|
||||||
|
*/
|
||||||
|
public function ICLASignedDate()
|
||||||
|
{
|
||||||
|
$ss_datetime = $this->owner->getField('CCLADate');
|
||||||
|
return new DateTime($ss_datetime);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getIdentifier()
|
||||||
|
{
|
||||||
|
return (int)$this->owner->getField('ID');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ITeam[]
|
||||||
|
*/
|
||||||
|
public function Teams()
|
||||||
|
{
|
||||||
|
return AssociationFactory::getInstance()->getOne2ManyAssociation($this->owner , 'Teams', new QueryObject)->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function addTeam(ITeam $team)
|
||||||
|
{
|
||||||
|
AssociationFactory::getInstance()->getOne2ManyAssociation($this->owner , 'Teams', new QueryObject)->add($team);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
158
ICLA/code/infrastructure/active_records/ICLAMemberDecorator.php
Normal file
158
ICLA/code/infrastructure/active_records/ICLAMemberDecorator.php
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class ICLAMemberDecorator
|
||||||
|
*/
|
||||||
|
final class ICLAMemberDecorator
|
||||||
|
extends DataExtension
|
||||||
|
implements ICLAMember, PermissionProvider
|
||||||
|
|
||||||
|
{
|
||||||
|
|
||||||
|
//Add extra database fields
|
||||||
|
|
||||||
|
|
||||||
|
private static $db = array(
|
||||||
|
'CLASigned' => 'Boolean',
|
||||||
|
'LastCodeCommit' => 'SS_Datetime',
|
||||||
|
'GerritID' => 'Text',
|
||||||
|
);
|
||||||
|
|
||||||
|
private static $defaults = array(
|
||||||
|
'CLASigned' => FALSE,
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
private static $belongs_many_many = array(
|
||||||
|
'Teams' => 'Team'
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getGerritId()
|
||||||
|
{
|
||||||
|
return (string)$this->owner->getField('GerritID');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return DateTime
|
||||||
|
*/
|
||||||
|
public function getLastCommitedDate()
|
||||||
|
{
|
||||||
|
return new DateTime($this->owner->getField('LastCodeCommit'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $gerrit_id
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function signICLA($gerrit_id)
|
||||||
|
{
|
||||||
|
$this->owner->setField('GerritID',$gerrit_id);
|
||||||
|
$this->owner->setField('CLASigned',true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getIdentifier()
|
||||||
|
{
|
||||||
|
return (int)$this->owner->getField('ID');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param DateTime $date
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function updateLastCommitedDate(DateTime $date)
|
||||||
|
{
|
||||||
|
$this->owner->setField('LastCodeCommit', $date->getTimestamp() );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function getAdminPermissionSet(array &$res){
|
||||||
|
|
||||||
|
$companyId = $_REQUEST["CompanyId"];
|
||||||
|
|
||||||
|
if(isset($companyId) && is_numeric($companyId) && $companyId > 0){
|
||||||
|
// user could be ccla admin of only one company and company must have at least one team set
|
||||||
|
$ccla_group = Group::get()->filter('Code',ICLAMember::CCLAGroupSlug)->first();
|
||||||
|
if(!$ccla_group) return;
|
||||||
|
$query_groups = new SQLQuery();
|
||||||
|
$query_groups->addSelect("GroupID");
|
||||||
|
$query_groups->addFrom("Company_Administrators");
|
||||||
|
$query_groups->addWhere("MemberID = {$this->owner->ID} AND CompanyID <> {$companyId} AND GroupID = {$ccla_group->ID} ");
|
||||||
|
|
||||||
|
$groups = $query_groups->execute()->keyedColumn();
|
||||||
|
|
||||||
|
$company = Company::get()->byID($companyId);
|
||||||
|
if(count($groups) === 0 && $company->isICLASigned())
|
||||||
|
array_push($res, 'CCLA_ADMIN');
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
function providePermissions() {
|
||||||
|
return array(
|
||||||
|
ICLAMember::CCLAPermissionSlug => array(
|
||||||
|
'name' => 'CCLA Company Admin',
|
||||||
|
'category' => 'Company Management',
|
||||||
|
'help' => 'Allows to manage CCLA Company Members and Teams',
|
||||||
|
'sort' => 0
|
||||||
|
),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
function isCCLAAdmin(){
|
||||||
|
$managed_companies = $this->owner->ManagedCompanies();
|
||||||
|
foreach($managed_companies as $company){
|
||||||
|
$groups = $company->getAdminGroupsByMember($this->getIdentifier());
|
||||||
|
if(is_null($groups) || count($groups)==0) continue;
|
||||||
|
if( array_key_exists(ICLAMember::CCLAGroupSlug , $groups)){
|
||||||
|
$company = $this->getManagedCCLACompany();
|
||||||
|
if(!$company) return false;
|
||||||
|
return $company->isICLASigned();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ICLACompany
|
||||||
|
*/
|
||||||
|
function getManagedCCLACompany(){
|
||||||
|
$managed_companies = $this->owner->ManagedCompanies();
|
||||||
|
foreach($managed_companies as $company){
|
||||||
|
$groups = $company->getAdminGroupsByMember($this->getIdentifier());
|
||||||
|
if(is_null($groups) || count($groups)==0) continue;
|
||||||
|
if( array_key_exists(ICLAMember::CCLAGroupSlug, $groups)){
|
||||||
|
return $company;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function hasSignedCLA()
|
||||||
|
{
|
||||||
|
return (bool)$this->owner->getField('CLASigned');
|
||||||
|
}
|
||||||
|
}
|
166
ICLA/code/infrastructure/active_records/Team.php
Normal file
166
ICLA/code/infrastructure/active_records/Team.php
Normal file
@ -0,0 +1,166 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class Team
|
||||||
|
*/
|
||||||
|
final class Team
|
||||||
|
extends DataObject
|
||||||
|
implements ITeam
|
||||||
|
{
|
||||||
|
|
||||||
|
static $create_table_options = array('MySQLDatabase' => 'ENGINE=InnoDB');
|
||||||
|
|
||||||
|
static $db = array(
|
||||||
|
'Name' => 'Text',
|
||||||
|
);
|
||||||
|
|
||||||
|
static $has_one = array(
|
||||||
|
'Company' => 'Company',
|
||||||
|
);
|
||||||
|
|
||||||
|
static $has_many = array(
|
||||||
|
'Invitations' => 'TeamInvitation',
|
||||||
|
);
|
||||||
|
|
||||||
|
static $many_many = array(
|
||||||
|
'Members' => 'Member',
|
||||||
|
);
|
||||||
|
|
||||||
|
//Administrators Security Groups
|
||||||
|
static $many_many_extraFields = array(
|
||||||
|
'Members' => array(
|
||||||
|
'DateAdded' => "SS_DateTime",
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
|
public static $defaults = array(
|
||||||
|
"DateAdded" => 'now()',
|
||||||
|
);
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getIdentifier()
|
||||||
|
{
|
||||||
|
return (int)$this->getField('ID');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getName()
|
||||||
|
{
|
||||||
|
return (string)$this->getField('Name');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ICLAMember[]
|
||||||
|
*/
|
||||||
|
public function getMembers()
|
||||||
|
{
|
||||||
|
return AssociationFactory::getInstance()->getMany2ManyAssociation($this , 'Members')->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ICLAMember $member
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function addMember(ICLAMember $member)
|
||||||
|
{
|
||||||
|
AssociationFactory::getInstance()->getMany2ManyAssociation($this , 'Members')->add($member, array('DateAdded'=> SS_Datetime::now()->Rfc2822()));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ICLAMember $member
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function removeMember(ICLAMember $member)
|
||||||
|
{
|
||||||
|
AssociationFactory::getInstance()->getMany2ManyAssociation($this , 'Members')->remove($member);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ITeamInvitation[]
|
||||||
|
*/
|
||||||
|
public function getInvitations(){
|
||||||
|
return AssociationFactory::getInstance()->getOne2ManyAssociation($this, 'Invitations')->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ITeamInvitation[]
|
||||||
|
*/
|
||||||
|
public function getUnconfirmedInvitations()
|
||||||
|
{
|
||||||
|
$query = new QueryObject();
|
||||||
|
$query->addAddCondition(QueryCriteria::equal('IsConfirmed', 0));
|
||||||
|
return AssociationFactory::getInstance()->getOne2ManyAssociation($this, 'Invitations' , $query)->toArray();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ICLACompany
|
||||||
|
*/
|
||||||
|
public function getCompany()
|
||||||
|
{
|
||||||
|
return AssociationFactory::getInstance()->getMany2OneAssociation($this, 'Company')->getTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ICLAMember $member
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isInvite(ICLAMember $member)
|
||||||
|
{
|
||||||
|
$member_id = $member->getIdentifier();
|
||||||
|
$res = $this->Invitations(" MemberID = {$member_id} ");
|
||||||
|
return $res->Count() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ICLAMember $member
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isMember(ICLAMember $member)
|
||||||
|
{
|
||||||
|
$member_id = $member->getIdentifier();
|
||||||
|
$res = $this->Members(" MemberID = {$member_id} ");
|
||||||
|
return $res->Count() > 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ITeamInvitation $invitation
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function removeInvitation(ITeamInvitation $invitation){
|
||||||
|
AssociationFactory::getInstance()->getOne2ManyAssociation($this , 'Invitations')->remove($invitation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $name
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function updateName($name)
|
||||||
|
{
|
||||||
|
$this->setField('Name', $name);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function clearMembers(){
|
||||||
|
AssociationFactory::getInstance()->getMany2ManyAssociation($this , 'Members')->removeAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function clearInvitations(){
|
||||||
|
AssociationFactory::getInstance()->getOne2ManyAssociation($this , 'Invitations')->removeAll();
|
||||||
|
}
|
||||||
|
}
|
124
ICLA/code/infrastructure/active_records/TeamInvitation.php
Normal file
124
ICLA/code/infrastructure/active_records/TeamInvitation.php
Normal file
@ -0,0 +1,124 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class TeamInvitation
|
||||||
|
*/
|
||||||
|
final class TeamInvitation
|
||||||
|
extends DataObject
|
||||||
|
implements ITeamInvitation
|
||||||
|
{
|
||||||
|
|
||||||
|
static $create_table_options = array('MySQLDatabase' => 'ENGINE=InnoDB');
|
||||||
|
|
||||||
|
static $db = array(
|
||||||
|
'Email' => 'Text',
|
||||||
|
'FirstName' => 'Text',
|
||||||
|
'LastName' => 'Text',
|
||||||
|
'ConfirmationHash' => 'Text',
|
||||||
|
'IsConfirmed' => 'Boolean',
|
||||||
|
'ConfirmationDate' => 'SS_Datetime',
|
||||||
|
);
|
||||||
|
|
||||||
|
static $has_one = array(
|
||||||
|
'Team' => 'Team',
|
||||||
|
'Member' => 'Member',
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getIdentifier()
|
||||||
|
{
|
||||||
|
return (int)$this->getField('ID');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return InviteInfoDTO
|
||||||
|
*/
|
||||||
|
public function getInviteInfo() {
|
||||||
|
return new InviteInfoDTO((string)$this->getField('FirstName'), (string)$this->getField('LastName'), (string)$this->getField('Email'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isInviteRegisteredAsUser()
|
||||||
|
{
|
||||||
|
$member = $this->getMember();
|
||||||
|
return $member && $member->getIdentifier() > 0 ;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ITeam
|
||||||
|
*/
|
||||||
|
public function getTeam()
|
||||||
|
{
|
||||||
|
return AssociationFactory::getInstance()->getMany2OneAssociation($this, 'Team')->getTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setTeam(ITeam $team){
|
||||||
|
AssociationFactory::getInstance()->getMany2OneAssociation($this, 'Team')->setTarget($team);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ICLAMember
|
||||||
|
*/
|
||||||
|
public function getMember()
|
||||||
|
{
|
||||||
|
return AssociationFactory::getInstance()->getMany2OneAssociation($this, 'Member')->getTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setMember(ICLAMember $member){
|
||||||
|
AssociationFactory::getInstance()->getMany2OneAssociation($this, 'Member')->setTarget($member);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function generateConfirmationToken() {
|
||||||
|
$generator = new RandomGenerator();
|
||||||
|
$token = $generator->randomToken();
|
||||||
|
$hash = self::HashConfirmationToken($token);
|
||||||
|
$this->setField('ConfirmationHash',$hash);
|
||||||
|
return $token;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $token
|
||||||
|
* @return bool
|
||||||
|
* @throws InvalidHashInvitationException
|
||||||
|
* @throws InvitationAlreadyConfirmedException
|
||||||
|
*/
|
||||||
|
public function doConfirmation($token)
|
||||||
|
{
|
||||||
|
$original_hash = $this->getField('ConfirmationHash');
|
||||||
|
if($this->IsConfirmed) throw new InvitationAlreadyConfirmedException;
|
||||||
|
if(self::HashConfirmationToken($token) === $original_hash){
|
||||||
|
$this->IsConfirmed = true;
|
||||||
|
$this->ConfirmationDate = SS_Datetime::now()->Rfc2822();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
throw new InvalidHashInvitationException;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function HashConfirmationToken($token){
|
||||||
|
return md5($token);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateInvite(ICLAMember $invite)
|
||||||
|
{
|
||||||
|
$this->setMember($invite);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class UnauthorizedRestfullAPIException
|
||||||
|
*/
|
||||||
|
final class UnauthorizedRestfullAPIException extends Exception {
|
||||||
|
|
||||||
|
public function __construct($message){
|
||||||
|
parent::__construct($message);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
30
ICLA/code/infrastructure/factories/BatchTaskFactory.php
Normal file
30
ICLA/code/infrastructure/factories/BatchTaskFactory.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class BatchTaskFactory
|
||||||
|
*/
|
||||||
|
final class BatchTaskFactory implements IBatchTaskFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $task_name
|
||||||
|
* @param int $total_record_qty
|
||||||
|
* @return IBatchTask
|
||||||
|
*/
|
||||||
|
public function buildBatchTask($task_name, $total_record_qty) {
|
||||||
|
$task = new BatchTask();
|
||||||
|
$task->Name = $task_name;
|
||||||
|
$task->initialize($total_record_qty);
|
||||||
|
return $task;
|
||||||
|
}
|
||||||
|
}
|
66
ICLA/code/infrastructure/factories/CCLAValidatorFactory.php
Normal file
66
ICLA/code/infrastructure/factories/CCLAValidatorFactory.php
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class CCLAValidatorFactory
|
||||||
|
*/
|
||||||
|
final class CCLAValidatorFactory implements ICCLAValidatorFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
* @return IValidator
|
||||||
|
*/
|
||||||
|
public function buildValidatorForTeamInvitation(array $data)
|
||||||
|
{
|
||||||
|
$rules = array(
|
||||||
|
'first_name' => 'required|text',
|
||||||
|
'last_name' => 'required|text',
|
||||||
|
'email' => 'required|email',
|
||||||
|
'team_id' => 'required|integer',
|
||||||
|
'member_id' => 'sometimes|integer',
|
||||||
|
);
|
||||||
|
|
||||||
|
$messages = array(
|
||||||
|
'first_name.required' => ':attribute is required',
|
||||||
|
'first_name.text' => ':attribute should be valid text.',
|
||||||
|
'last_name.required' => ':attribute is required',
|
||||||
|
'email.email' => ':attribute should be valid email.',
|
||||||
|
'email.required' => ':attribute is required',
|
||||||
|
'team_id.required' => ':attribute is required',
|
||||||
|
'team_id.integer ' => ':attribute should be valid integer.',
|
||||||
|
'member_id.integer' => ':attribute should be valid integer.',
|
||||||
|
);
|
||||||
|
|
||||||
|
return ValidatorService::make($data, $rules, $messages);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
* @return ValidatorService
|
||||||
|
*/
|
||||||
|
public function buildValidatorForTeam(array $data){
|
||||||
|
$rules = array(
|
||||||
|
'name' => 'required|text',
|
||||||
|
'company_id' => 'required|integer',
|
||||||
|
);
|
||||||
|
|
||||||
|
$messages = array(
|
||||||
|
'name.required' => ':attribute is required',
|
||||||
|
'name.text' => ':attribute should be valid text.',
|
||||||
|
'company_id.required' => ':attribute is required',
|
||||||
|
'company_id.integer' => ':attribute should be valid integer.',
|
||||||
|
);
|
||||||
|
|
||||||
|
return ValidatorService::make($data, $rules, $messages);
|
||||||
|
}
|
||||||
|
}
|
32
ICLA/code/infrastructure/factories/TeamFactory.php
Normal file
32
ICLA/code/infrastructure/factories/TeamFactory.php
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class TeamFactory
|
||||||
|
*/
|
||||||
|
final class TeamFactory implements ITeamFactory {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $team_data
|
||||||
|
* @return ITeam
|
||||||
|
*/
|
||||||
|
public function buildTeam(array $team_data)
|
||||||
|
{
|
||||||
|
$team = new Team();
|
||||||
|
$team->Name = $team_data['name'];
|
||||||
|
$team->CompanyID = (int)$team_data['company_id'];
|
||||||
|
$team->Company = new Company() ;
|
||||||
|
$team->Company->ID = (int)$team_data['company_id'];
|
||||||
|
return $team;
|
||||||
|
}
|
||||||
|
}
|
37
ICLA/code/infrastructure/factories/TeamInvitationFactory.php
Normal file
37
ICLA/code/infrastructure/factories/TeamInvitationFactory.php
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class TeamInvitationFactory
|
||||||
|
*/
|
||||||
|
final class TeamInvitationFactory implements ITeamInvitationFactory{
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param InvitationDTO $invitation_dto
|
||||||
|
* @return ITeamInvitation
|
||||||
|
*/
|
||||||
|
public function buildInvitation(InvitationDTO $invitation_dto)
|
||||||
|
{
|
||||||
|
$invitation = new TeamInvitation();
|
||||||
|
|
||||||
|
$invitation->FirstName = $invitation_dto->getFirstName();
|
||||||
|
$invitation->LastName = $invitation_dto->getLastName();
|
||||||
|
$invitation->Email = $invitation_dto->getEmail();
|
||||||
|
$invitation->setTeam($invitation_dto->getTeam());
|
||||||
|
$member = $invitation_dto->getMember();
|
||||||
|
if($member){
|
||||||
|
$invitation->setMember($member);
|
||||||
|
}
|
||||||
|
return $invitation;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,32 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
final class SapphireBatchTaskRepository
|
||||||
|
extends SapphireRepository
|
||||||
|
implements IBatchTaskRepository{
|
||||||
|
|
||||||
|
public function __construct(){
|
||||||
|
parent::__construct(new BatchTask());
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* @param string $name
|
||||||
|
* @return IBatchTask
|
||||||
|
*/
|
||||||
|
public function findByName($name)
|
||||||
|
{
|
||||||
|
$query = new QueryObject;
|
||||||
|
$query->addAddCondition(QueryCriteria::equal('Name',$name));
|
||||||
|
return $this->getBy($query);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,103 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class SapphireCLAMemberRepository
|
||||||
|
*/
|
||||||
|
final class SapphireCLAMemberRepository
|
||||||
|
extends SapphireRepository
|
||||||
|
implements ICLAMemberRepository {
|
||||||
|
|
||||||
|
public function __construct(){
|
||||||
|
$entity = new ICLAMemberDecorator;
|
||||||
|
$entity->setOwner(new Member);
|
||||||
|
parent::__construct($entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
* @return int[]
|
||||||
|
*/
|
||||||
|
function getAllGerritIds() {
|
||||||
|
$gerrit_ids = DB::query('SELECT GerritID FROM Member WHERE GerritID IS NOT NULL;');
|
||||||
|
$res = array();
|
||||||
|
foreach ($gerrit_ids as $id) {
|
||||||
|
$gerrit_id = (string) $id['GerritID'];
|
||||||
|
$res[$gerrit_id] = $gerrit_id;
|
||||||
|
}
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $offset
|
||||||
|
* @param int $limit
|
||||||
|
* @return ICLAMember[]
|
||||||
|
*/
|
||||||
|
function getAllICLAMembers($offset, $limit)
|
||||||
|
{
|
||||||
|
$query = new QueryObject;
|
||||||
|
$query->addAddCondition(QueryCriteria::equal('CLASigned',true));
|
||||||
|
return $this->getAll($query, $offset, $limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $email
|
||||||
|
* @return ICLAMember
|
||||||
|
*/
|
||||||
|
public function findByEmail($email){
|
||||||
|
$query = new QueryObject;
|
||||||
|
$query->addAddCondition(QueryCriteria::equal('Email',$email));
|
||||||
|
return $this->getBy($query);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $email
|
||||||
|
* @param int $offset
|
||||||
|
* @param int $limit
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function getAllIClaMembersByEmail($email, $offset, $limit)
|
||||||
|
{
|
||||||
|
$query = new QueryObject;
|
||||||
|
$query->addAddCondition(QueryCriteria::equal('CLASigned',true));
|
||||||
|
$query->addAddCondition(QueryCriteria::like('Email',$email));
|
||||||
|
return $this->getAll($query, $offset, $limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $first_name
|
||||||
|
* @param int $offset
|
||||||
|
* @param int $limit
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function getAllIClaMembersByFirstName($first_name, $offset, $limit)
|
||||||
|
{
|
||||||
|
$query = new QueryObject;
|
||||||
|
$query->addAddCondition(QueryCriteria::equal('CLASigned',true));
|
||||||
|
$query->addAddCondition(QueryCriteria::like('FirstName',$first_name));
|
||||||
|
return $this->getAll($query, $offset, $limit);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $last_name
|
||||||
|
* @param int $offset
|
||||||
|
* @param int $limit
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function getAllIClaMembersByLastName($last_name, $offset, $limit)
|
||||||
|
{
|
||||||
|
$query = new QueryObject;
|
||||||
|
$query->addAddCondition(QueryCriteria::equal('CLASigned',true));
|
||||||
|
$query->addAddCondition(QueryCriteria::like('Surname',$last_name));
|
||||||
|
return $this->getAll($query, $offset, $limit);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class SapphireICLACompanyRepository
|
||||||
|
*/
|
||||||
|
final class SapphireICLACompanyRepository
|
||||||
|
extends SapphireRepository
|
||||||
|
implements ICLACompanyRepository {
|
||||||
|
|
||||||
|
public function __construct(){
|
||||||
|
$entity = new ICLACompanyDecorator;
|
||||||
|
$entity->setOwner(new Company);
|
||||||
|
parent::__construct($entity);
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,75 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class SapphireTeamInvitationRepository
|
||||||
|
*/
|
||||||
|
final class SapphireTeamInvitationRepository
|
||||||
|
extends SapphireRepository
|
||||||
|
implements ITeamInvitationRepository
|
||||||
|
{
|
||||||
|
|
||||||
|
public function __construct(){
|
||||||
|
parent::__construct(new TeamInvitation);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $token
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function existsConfirmationToken($token)
|
||||||
|
{
|
||||||
|
$query = new QueryObject;
|
||||||
|
$query->addAddCondition(QueryCriteria::equal('ConfirmationHash',TeamInvitation::HashConfirmationToken($token)));
|
||||||
|
return !is_null( $this->getBy($query));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $token
|
||||||
|
* @return ITeamInvitation
|
||||||
|
*/
|
||||||
|
public function findByConfirmationToken($token)
|
||||||
|
{
|
||||||
|
$query = new QueryObject;
|
||||||
|
$query->addAddCondition(QueryCriteria::equal('ConfirmationHash',TeamInvitation::HashConfirmationToken($token)));
|
||||||
|
return $this->getBy($query);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $email
|
||||||
|
* @param bool $all
|
||||||
|
* @return ITeamInvitation[]
|
||||||
|
*/
|
||||||
|
public function findByInviteEmail($email, $all = false)
|
||||||
|
{
|
||||||
|
$query = new QueryObject;
|
||||||
|
$query->addAddCondition(QueryCriteria::equal('Email',$email));
|
||||||
|
if(!$all)
|
||||||
|
$query->addAddCondition(QueryCriteria::isNull('ConfirmationHash'));
|
||||||
|
list($res, $size) = $this->getAll($query,0,1000);
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $email
|
||||||
|
* @param ITeam $team
|
||||||
|
* @return ITeamInvitation
|
||||||
|
*/
|
||||||
|
public function findByInviteEmailAndTeam($email, ITeam $team){
|
||||||
|
|
||||||
|
$query = new QueryObject;
|
||||||
|
$query->addAddCondition(QueryCriteria::equal('Email',$email));
|
||||||
|
$query->addAddCondition(QueryCriteria::equal('TeamID',$team->getIdentifier()));
|
||||||
|
return $this->getBy($query);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/***
|
||||||
|
* Class SapphireTeamRepository
|
||||||
|
*/
|
||||||
|
final class SapphireTeamRepository extends SapphireRepository
|
||||||
|
implements ITeamRepository
|
||||||
|
{
|
||||||
|
public function __construct(){
|
||||||
|
parent::__construct(new Team);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $company_id
|
||||||
|
* @return ITeam[]
|
||||||
|
*/
|
||||||
|
public function getByCompany($company_id) {
|
||||||
|
$query = new QueryObject(new Team);
|
||||||
|
$query->addAddCondition(QueryCriteria::equal('CompanyID', $company_id));
|
||||||
|
list($list, $size) = $this->getAll($query, 0, 1000);
|
||||||
|
return $list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $name
|
||||||
|
* @param int $company_id
|
||||||
|
* @return ITeam
|
||||||
|
*/
|
||||||
|
public function getByNameAndCompany($name, $company_id)
|
||||||
|
{
|
||||||
|
$query = new QueryObject(new Team);
|
||||||
|
|
||||||
|
$query->addAddCondition(QueryCriteria::equal('CompanyID', $company_id));
|
||||||
|
$query->addAddCondition(QueryCriteria::equal('Name', $name));
|
||||||
|
|
||||||
|
return $this->getBy($query);
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,39 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class AbstractRestfulServiceRequestor
|
||||||
|
*/
|
||||||
|
abstract class AbstractRestfulServiceRequestor {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $url
|
||||||
|
* @param null|string $user
|
||||||
|
* @param null|string $password
|
||||||
|
* @return mixed
|
||||||
|
*/
|
||||||
|
protected function doRequest($url, $user = null, $password = null){
|
||||||
|
$ch = curl_init();
|
||||||
|
curl_setopt($ch, CURLOPT_URL, $url);
|
||||||
|
if(!empty($user) && !empty($password)){
|
||||||
|
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_DIGEST);
|
||||||
|
curl_setopt($ch, CURLOPT_USERPWD, sprintf("%s:%s", $user, $password));
|
||||||
|
}
|
||||||
|
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
|
||||||
|
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
|
||||||
|
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
|
||||||
|
$response = curl_exec($ch);
|
||||||
|
curl_close($ch);
|
||||||
|
return $response;
|
||||||
|
}
|
||||||
|
}
|
84
ICLA/code/infrastructure/services/GerritAPI.php
Normal file
84
ICLA/code/infrastructure/services/GerritAPI.php
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class GerritAPI
|
||||||
|
*/
|
||||||
|
final class GerritAPI
|
||||||
|
extends AbstractRestfulServiceRequestor
|
||||||
|
implements IGerritAPI {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $user;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $password;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $domain;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $domain
|
||||||
|
* @param string $user
|
||||||
|
* @param string $password
|
||||||
|
*/
|
||||||
|
public function __construct($domain, $user, $password){
|
||||||
|
$this->domain = $domain;
|
||||||
|
$this->user = $user;
|
||||||
|
$this->password = $password;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $group_id
|
||||||
|
* @return array|mixed
|
||||||
|
* @throws UnauthorizedRestfullAPIException
|
||||||
|
*/
|
||||||
|
public function listAllMembersFromGroup($group_id){
|
||||||
|
$url = sprintf("%s/a/groups/%s/members", $this->domain, $group_id);
|
||||||
|
$json = $this->fixGerritJsonResponse($this->doRequest($url, $this->user, $this->password));
|
||||||
|
if(strtolower($json)==='unauthorized')
|
||||||
|
throw new UnauthorizedRestfullAPIException($json);
|
||||||
|
|
||||||
|
return json_decode($json, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $gerrit_user_id
|
||||||
|
* @return DateTime
|
||||||
|
*/
|
||||||
|
public function getUserLastCommit($gerrit_user_id){
|
||||||
|
$url = sprintf("%s/changes/?q=status:merged+owner:%s&n=1", $this->domain, $gerrit_user_id);
|
||||||
|
$json = $this->fixGerritJsonResponse($this->doRequest($url));
|
||||||
|
$response = json_decode($json, true);
|
||||||
|
if(is_array($response) && count($response) > 0){
|
||||||
|
$response = $response[0];
|
||||||
|
$last_committed_date = $response['updated'];
|
||||||
|
$last_committed_date = explode('.',$last_committed_date);
|
||||||
|
if(is_array($last_committed_date) && count($last_committed_date) > 0){
|
||||||
|
return DateTime::createFromFormat('Y-m-d H:i:s', $last_committed_date[0]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private function fixGerritJsonResponse($json){
|
||||||
|
$json = str_replace(")]}'",'',$json);
|
||||||
|
return $json;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,68 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class TeamInvitationEmailSender
|
||||||
|
*/
|
||||||
|
final class TeamInvitationEmailSender implements ITeamInvitationSender {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ITeamInvitationRepository
|
||||||
|
*/
|
||||||
|
private $team_invitation_repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ITeamInvitationRepository $team_invitation_repository
|
||||||
|
*/
|
||||||
|
public function __construct(ITeamInvitationRepository $team_invitation_repository){
|
||||||
|
$this->team_invitation_repository = $team_invitation_repository;
|
||||||
|
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* @param ITeamInvitation $invitation
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function sendInvitation(ITeamInvitation $invitation) {
|
||||||
|
$invite_dto = $invitation->getInviteInfo();
|
||||||
|
|
||||||
|
$email_to = $invite_dto->getEmail();
|
||||||
|
//to avoid accidentally send undesired emails....
|
||||||
|
if(defined('CCLA_DEBUG_EMAIL'))
|
||||||
|
$email_to = CCLA_DEBUG_EMAIL;
|
||||||
|
|
||||||
|
$email = EmailFactory::getInstance()->buildEmail(CCLA_TEAM_INVITATION_EMAIL_FROM, $email_to , "You Have been Invited to Team ".$invitation->getTeam()->getName());
|
||||||
|
|
||||||
|
$template_data = array(
|
||||||
|
'FirstName' => $invite_dto->getFirstName(),
|
||||||
|
'LastName' => $invite_dto->getLastName(),
|
||||||
|
'TeamName' => $invitation->getTeam()->getName(),
|
||||||
|
'CompanyName' => $invitation->getTeam()->getCompany()->Name
|
||||||
|
);
|
||||||
|
|
||||||
|
if($invitation->isInviteRegisteredAsUser()){
|
||||||
|
$email->setTemplate('TeamInvitation_RegisteredUser');
|
||||||
|
do{
|
||||||
|
$token = $invitation->generateConfirmationToken();
|
||||||
|
} while ($this->team_invitation_repository->existsConfirmationToken($token));
|
||||||
|
$template_data['ConfirmationLink'] = sprintf('%s/team-invitations/%s/confirm', Director::protocolAndHost(), $token);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$email->setTemplate('TeamInvitation_UnRegisteredUser');
|
||||||
|
$template_data['RegistrationLink'] = sprintf('%s/join/register', Director::protocolAndHost());
|
||||||
|
}
|
||||||
|
|
||||||
|
$email->populateTemplate($template_data);
|
||||||
|
|
||||||
|
$email->send();
|
||||||
|
}
|
||||||
|
}
|
35
ICLA/code/infrastructure/tasks/PullCLAFromGerritTask.php
Normal file
35
ICLA/code/infrastructure/tasks/PullCLAFromGerritTask.php
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class PullCLAFromGerritTask
|
||||||
|
*/
|
||||||
|
final class PullCLAFromGerritTask extends CliController {
|
||||||
|
|
||||||
|
function process(){
|
||||||
|
|
||||||
|
set_time_limit(0);
|
||||||
|
|
||||||
|
$manager = new ICLAManager (
|
||||||
|
new GerritAPI(GERRIT_BASE_URL, GERRIT_USER, GERRIT_PASSWORD),
|
||||||
|
new SapphireBatchTaskRepository,
|
||||||
|
new SapphireCLAMemberRepository,
|
||||||
|
new BatchTaskFactory,
|
||||||
|
SapphireTransactionManager::getInstance()
|
||||||
|
);
|
||||||
|
|
||||||
|
$members_updated = $manager->processICLAGroup(ICLA_GROUP_ID, PULL_ICLA_DATA_FROM_GERRIT_BATCH_SIZE);
|
||||||
|
|
||||||
|
echo $members_updated;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,35 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class UpdateLastCommittedDateTask
|
||||||
|
*/
|
||||||
|
final class UpdateLastCommittedDateTask extends CliController {
|
||||||
|
|
||||||
|
function process(){
|
||||||
|
|
||||||
|
set_time_limit(0);
|
||||||
|
|
||||||
|
$manager = new ICLAManager (
|
||||||
|
new GerritAPI(GERRIT_BASE_URL, GERRIT_USER, GERRIT_PASSWORD),
|
||||||
|
new SapphireBatchTaskRepository,
|
||||||
|
new SapphireCLAMemberRepository,
|
||||||
|
new BatchTaskFactory,
|
||||||
|
SapphireTransactionManager::getInstance()
|
||||||
|
);
|
||||||
|
|
||||||
|
$members_updated = $manager->updateLastCommittedDate(PULL_LAST_COMMITTED_DATA_FROM_GERRIT_BATCH_SIZE);
|
||||||
|
|
||||||
|
echo $members_updated;
|
||||||
|
}
|
||||||
|
}
|
335
ICLA/code/interfaces/restfull_api/ICLARestfulAPI.php
Normal file
335
ICLA/code/interfaces/restfull_api/ICLARestfulAPI.php
Normal file
@ -0,0 +1,335 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class ICLARestfulAPI
|
||||||
|
*/
|
||||||
|
final class ICLARestfulAPI
|
||||||
|
extends AbstractRestfulJsonApi {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ICLACompanyRepository
|
||||||
|
*/
|
||||||
|
private $company_repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var CCLACompanyService
|
||||||
|
*/
|
||||||
|
private $company_manager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ICLAMemberRepository
|
||||||
|
*/
|
||||||
|
private $member_repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var CCLATeamManager
|
||||||
|
*/
|
||||||
|
private $team_manager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ITeamInvitationRepository
|
||||||
|
*/
|
||||||
|
private $invitation_repository;
|
||||||
|
|
||||||
|
public function __construct(){
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->company_repository = new SapphireICLACompanyRepository;
|
||||||
|
$this->member_repository = new SapphireCLAMemberRepository;
|
||||||
|
$this->invitation_repository = new SapphireTeamInvitationRepository;
|
||||||
|
$this->company_manager = new CCLACompanyService($this->company_repository, SapphireTransactionManager::getInstance());
|
||||||
|
|
||||||
|
$this->team_manager = new CCLATeamManager(
|
||||||
|
$this->invitation_repository,
|
||||||
|
$this->member_repository,
|
||||||
|
new TeamInvitationFactory,
|
||||||
|
new TeamFactory,
|
||||||
|
new CCLAValidatorFactory,
|
||||||
|
new SapphireTeamRepository,
|
||||||
|
SapphireTransactionManager::getInstance());
|
||||||
|
|
||||||
|
//filters...
|
||||||
|
|
||||||
|
$this_var = $this;
|
||||||
|
$this->addBeforeFilter('signCompanyCCLA','check_sign',function ($request) use($this_var){
|
||||||
|
if(!Permission::check("SANGRIA_ACCESS"))
|
||||||
|
return $this_var->permissionFailure();
|
||||||
|
});
|
||||||
|
$this->addBeforeFilter('unsignCompanyCCLA','check_unsign',function ($request) use($this_var){
|
||||||
|
if(!Permission::check("SANGRIA_ACCESS"))
|
||||||
|
return $this_var->permissionFailure();
|
||||||
|
});
|
||||||
|
$this->addBeforeFilter('searchCCLAMembers','check_members_search',function() use($this_var){
|
||||||
|
return $this_var->checkCCLAdmin();
|
||||||
|
});
|
||||||
|
$this->addBeforeFilter('addInvitation','check_add_invitation',function() use($this_var){
|
||||||
|
return $this_var->checkCCLAdmin();
|
||||||
|
});
|
||||||
|
$this->addBeforeFilter('deleteInvitation','check_delete_invitation',function() use($this_var){
|
||||||
|
return $this_var->checkCCLAdmin();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return SS_HTTPResponse
|
||||||
|
*/
|
||||||
|
public function checkCCLAdmin(){
|
||||||
|
$member = Member::currentUser();
|
||||||
|
if(!$member) return $this->permissionFailure();
|
||||||
|
if(!$member->isCCLAAdmin()) return $this->permissionFailure();
|
||||||
|
}
|
||||||
|
|
||||||
|
const ApiPrefix = 'api/v1/ccla';
|
||||||
|
|
||||||
|
protected function isApiCall()
|
||||||
|
{
|
||||||
|
$request = $this->getRequest();
|
||||||
|
if(is_null($request)) return false;
|
||||||
|
return strpos(strtolower($request->getURL()),self::ApiPrefix) !== false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
protected function authorize()
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
static $url_handlers = array(
|
||||||
|
'PUT companies/$COMPANY_ID/sign' => 'signCompanyCCLA',
|
||||||
|
'DELETE companies/$COMPANY_ID/sign' => 'unsignCompanyCCLA',
|
||||||
|
'GET members' => 'searchCCLAMembers',
|
||||||
|
'POST invitations' => 'addInvitation',
|
||||||
|
'DELETE teams/$TEAM_ID/memberships/$ID/$STATUS' => 'resignMembership',
|
||||||
|
'POST teams' => 'addTeam',
|
||||||
|
'DELETE teams/$TEAM_ID' => 'deleteTeam',
|
||||||
|
'PUT teams/$TEAM_ID' => 'updateTeamName',
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
static $allowed_actions = array(
|
||||||
|
'signCompanyCCLA',
|
||||||
|
'unsignCompanyCCLA',
|
||||||
|
'searchCCLAMembers',
|
||||||
|
'addInvitation',
|
||||||
|
'resignMembership',
|
||||||
|
'confirmTeamInvitation',
|
||||||
|
'addTeam',
|
||||||
|
'deleteTeam',
|
||||||
|
'updateTeamName',
|
||||||
|
);
|
||||||
|
|
||||||
|
public function addInvitation(){
|
||||||
|
$data = $this->getJsonRequest();
|
||||||
|
try{
|
||||||
|
$entity = $this->team_manager->sendInvitation($data, new TeamInvitationEmailSender($this->invitation_repository));
|
||||||
|
return $this->created($entity->getIdentifier());
|
||||||
|
}
|
||||||
|
catch(NotFoundEntityException $ex1){
|
||||||
|
SS_Log::log($ex1,SS_Log::NOTICE);
|
||||||
|
return $this->notFound($ex1->getMessage());
|
||||||
|
}
|
||||||
|
catch(EntityValidationException $ex2){
|
||||||
|
SS_Log::log($ex2,SS_Log::NOTICE);
|
||||||
|
return $this->validationError($ex2->getMessages());
|
||||||
|
}
|
||||||
|
catch(TeamMemberAlreadyExistsException $ex3){
|
||||||
|
SS_Log::log($ex3,SS_Log::NOTICE);
|
||||||
|
return $this->validationError(array( array('attribute'=>'error', 'message' => $ex3->getMessage())));
|
||||||
|
}
|
||||||
|
catch(MemberNotSignedCCLAException $ex4){
|
||||||
|
SS_Log::log($ex4,SS_Log::NOTICE);
|
||||||
|
return $this->validationError(array( array('attribute'=>'error', 'message' => $ex4->getMessage())));
|
||||||
|
}
|
||||||
|
catch(Exception $ex){
|
||||||
|
SS_Log::log($ex,SS_Log::ERR);
|
||||||
|
return $this->serverError();
|
||||||
|
}
|
||||||
|
if (!$data) return $this->serverError();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function resignMembership(){
|
||||||
|
|
||||||
|
$id = (int)$this->request->param('ID');
|
||||||
|
$team_id = (int)$this->request->param('TEAM_ID');
|
||||||
|
$status = $this->request->param('STATUS');
|
||||||
|
|
||||||
|
try{
|
||||||
|
$this->team_manager->resignMembership($team_id, $id, $status);
|
||||||
|
return $this->deleted();
|
||||||
|
}
|
||||||
|
catch(NotFoundEntityException $ex1){
|
||||||
|
SS_Log::log($ex1,SS_Log::NOTICE);
|
||||||
|
return $this->notFound($ex1->getMessage());
|
||||||
|
}
|
||||||
|
catch(Exception $ex){
|
||||||
|
SS_Log::log($ex,SS_Log::ERR);
|
||||||
|
return $this->serverError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function signCompanyCCLA(){
|
||||||
|
$company_id = (int)$this->request->param('COMPANY_ID');
|
||||||
|
try{
|
||||||
|
$res = $this->company_manager->signCCLA($company_id);
|
||||||
|
return $this->ok(array('sign_date' => $res));
|
||||||
|
}
|
||||||
|
catch(NotFoundEntityException $ex1){
|
||||||
|
SS_Log::log($ex1,SS_Log::NOTICE);
|
||||||
|
return $this->notFound($ex1->getMessage());
|
||||||
|
}
|
||||||
|
catch(Exception $ex){
|
||||||
|
SS_Log::log($ex,SS_Log::ERR);
|
||||||
|
return $this->serverError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function unsignCompanyCCLA(){
|
||||||
|
$company_id = (int)$this->request->param('COMPANY_ID');
|
||||||
|
try{
|
||||||
|
$this->company_manager->unsignCCLA($company_id);
|
||||||
|
return $this->ok();
|
||||||
|
}
|
||||||
|
catch(NotFoundEntityException $ex1){
|
||||||
|
SS_Log::log($ex1,SS_Log::NOTICE);
|
||||||
|
return $this->notFound($ex1->getMessage());
|
||||||
|
}
|
||||||
|
catch(Exception $ex){
|
||||||
|
SS_Log::log($ex,SS_Log::ERR);
|
||||||
|
return $this->serverError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function searchCCLAMembers(){
|
||||||
|
|
||||||
|
$params = $this->request->getVars();
|
||||||
|
$field = $params['field'];
|
||||||
|
$term = $params['term'];
|
||||||
|
|
||||||
|
try{
|
||||||
|
$res = array();
|
||||||
|
|
||||||
|
switch($field){
|
||||||
|
case 'email':
|
||||||
|
list($list, $size) = $this->member_repository->getAllIClaMembersByEmail($term,0,25);
|
||||||
|
break;
|
||||||
|
case 'fname':
|
||||||
|
list($list, $size) = $this->member_repository->getAllIClaMembersByFirstName($term,0,25);
|
||||||
|
break;
|
||||||
|
case 'lname':
|
||||||
|
list($list, $size) = $this->member_repository->getAllIClaMembersByLastName($term,0,25);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return $this->validationError('criteria not supported!');
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($list as $member){
|
||||||
|
$label = sprintf('%s - (%s) - %s',$member->getFullName(), $member->Email, $member->LastVisited);
|
||||||
|
array_push($res, array( 'label' => $label,
|
||||||
|
'value' => $member->getIdentifier(),
|
||||||
|
'email' => $member->Email,
|
||||||
|
'first_name' => $member->FirstName,
|
||||||
|
'last_name' => $member->Surname));
|
||||||
|
}
|
||||||
|
return $this->ok($res);
|
||||||
|
}
|
||||||
|
catch(NotFoundEntityException $ex1){
|
||||||
|
SS_Log::log($ex1,SS_Log::NOTICE);
|
||||||
|
return $this->notFound($ex1->getMessage());
|
||||||
|
}
|
||||||
|
catch(Exception $ex){
|
||||||
|
SS_Log::log($ex,SS_Log::ERR);
|
||||||
|
return $this->serverError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
//Teams
|
||||||
|
|
||||||
|
public function addTeam(){
|
||||||
|
$data = $this->getJsonRequest();
|
||||||
|
if (!$data) return $this->serverError();
|
||||||
|
|
||||||
|
try{
|
||||||
|
$entity = $this->team_manager->registerTeam($data);
|
||||||
|
return $this->created($entity->getIdentifier());
|
||||||
|
}
|
||||||
|
catch(TeamAlreadyExistsException $ex1){
|
||||||
|
SS_Log::log($ex1,SS_Log::NOTICE);
|
||||||
|
return $this->validationError(array( array('attribute'=>'error', 'message' => 'Team Already exist on Company!')));
|
||||||
|
}
|
||||||
|
catch(EntityValidationException $ex2){
|
||||||
|
SS_Log::log($ex2,SS_Log::NOTICE);
|
||||||
|
return $this->validationError($ex2->getMessages());
|
||||||
|
}
|
||||||
|
|
||||||
|
catch(Exception $ex){
|
||||||
|
SS_Log::log($ex,SS_Log::ERR);
|
||||||
|
return $this->serverError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function updateTeamName(){
|
||||||
|
$data = $this->getJsonRequest();
|
||||||
|
if (!$data) return $this->serverError();
|
||||||
|
$team_id = (int)$this->request->param('TEAM_ID');
|
||||||
|
try{
|
||||||
|
$this->team_manager->updateTeam($team_id, $data);
|
||||||
|
return $this->updated();
|
||||||
|
}
|
||||||
|
catch(TeamAlreadyExistsException $ex1){
|
||||||
|
SS_Log::log($ex1,SS_Log::NOTICE);
|
||||||
|
return $this->validationError(array( array('attribute'=>'error', 'message' => 'Team Already exist on Company!')));
|
||||||
|
}
|
||||||
|
catch(EntityValidationException $ex2){
|
||||||
|
SS_Log::log($ex2,SS_Log::NOTICE);
|
||||||
|
return $this->validationError($ex2->getMessages());
|
||||||
|
}
|
||||||
|
catch(NotFoundEntityException $ex3){
|
||||||
|
SS_Log::log($ex3,SS_Log::NOTICE);
|
||||||
|
return $this->validationError(array( array('attribute'=>'error', 'message' => 'Team does not exist on Company!')));
|
||||||
|
}
|
||||||
|
catch(Exception $ex){
|
||||||
|
SS_Log::log($ex,SS_Log::ERR);
|
||||||
|
return $this->serverError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function deleteTeam(){
|
||||||
|
$team_id = (int)$this->request->param('TEAM_ID');
|
||||||
|
try{
|
||||||
|
$this->team_manager->removeTeam($team_id);
|
||||||
|
return $this->deleted();
|
||||||
|
}
|
||||||
|
catch(EntityValidationException $ex2){
|
||||||
|
SS_Log::log($ex2,SS_Log::NOTICE);
|
||||||
|
return $this->validationError($ex2->getMessages());
|
||||||
|
}
|
||||||
|
catch(NotFoundEntityException $ex3){
|
||||||
|
SS_Log::log($ex3,SS_Log::NOTICE);
|
||||||
|
return $this->validationError(array( array('attribute'=>'error', 'message' => 'Team does not exist on Company!')));
|
||||||
|
}
|
||||||
|
catch(Exception $ex){
|
||||||
|
SS_Log::log($ex,SS_Log::ERR);
|
||||||
|
return $this->serverError();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,85 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class TeamInvitationConfirmation_Controller
|
||||||
|
*/
|
||||||
|
final class TeamInvitationConfirmation_Controller extends AbstractController {
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
static $url_handlers = array(
|
||||||
|
'GET $CONFIRMATION_TOKEN/confirm' => 'confirmTeamInvitation',
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
static $allowed_actions = array(
|
||||||
|
'confirmTeamInvitation',
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ICLAMemberRepository
|
||||||
|
*/
|
||||||
|
private $member_repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var CCLATeamManager
|
||||||
|
*/
|
||||||
|
private $team_manager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ITeamInvitationRepository
|
||||||
|
*/
|
||||||
|
|
||||||
|
public function __construct(){
|
||||||
|
parent::__construct();
|
||||||
|
|
||||||
|
$this->member_repository = new SapphireCLAMemberRepository;
|
||||||
|
$this->invitation_repository = new SapphireTeamInvitationRepository;
|
||||||
|
|
||||||
|
$this->team_manager = new CCLATeamManager(
|
||||||
|
$this->invitation_repository,
|
||||||
|
$this->member_repository,
|
||||||
|
new TeamInvitationFactory,
|
||||||
|
new TeamFactory,
|
||||||
|
new CCLAValidatorFactory,
|
||||||
|
new SapphireTeamRepository,
|
||||||
|
SapphireTransactionManager::getInstance());
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string|void
|
||||||
|
*/
|
||||||
|
public function confirmTeamInvitation(){
|
||||||
|
$token = $this->request->param('CONFIRMATION_TOKEN');
|
||||||
|
try{
|
||||||
|
$current_member = Member::currentUser();
|
||||||
|
if(is_null($current_member))
|
||||||
|
return Director::redirect("Security/login?BackURL=" . urlencode($_SERVER['REQUEST_URI']));
|
||||||
|
$team = $this->team_manager->confirmInvitation($token, $current_member);
|
||||||
|
return $this->renderWith( array('TeamInvitationConfirmation_successfull','Page') , array('TeamName' => $team->getName() , 'CompanyName' => $team->getCompany()->Name ) );
|
||||||
|
}
|
||||||
|
catch(InvitationBelongsToAnotherMemberException $ex1){
|
||||||
|
SS_Log::log($ex1,SS_Log::ERR);
|
||||||
|
$invitation = $this->invitation_repository->findByConfirmationToken($token);
|
||||||
|
|
||||||
|
return $this->renderWith(array('TeamInvitationConfirmation_belongs_2_another_user','Page'), array('UserName' => $invitation->getMember()->Email));
|
||||||
|
}
|
||||||
|
catch(Exception $ex){
|
||||||
|
SS_Log::log($ex,SS_Log::ERR);
|
||||||
|
return $this->renderWith(array('TeamInvitationConfirmation_error','Page'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
47
ICLA/code/migrations/CLAICLAGroupsCreationTask.php
Normal file
47
ICLA/code/migrations/CLAICLAGroupsCreationTask.php
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class CLAICLAGroupsCreationTask
|
||||||
|
*/
|
||||||
|
final class CLAICLAGroupsCreationTask extends MigrationTask {
|
||||||
|
|
||||||
|
protected $title = "CCLA/ICLA Migration";
|
||||||
|
|
||||||
|
protected $description = "Creates CLA/ICLA Security Groups";
|
||||||
|
|
||||||
|
function up(){
|
||||||
|
echo "Starting Migration Proc ...<BR>";
|
||||||
|
//check if migration already had ran ...
|
||||||
|
$migration = Migration::get()->filter('Name',$this->title)->first();
|
||||||
|
if (!$migration) {
|
||||||
|
$g = new Group();
|
||||||
|
$g->setTitle('CCLA Admin');
|
||||||
|
$g->setDescription('Company CCLA Admin');
|
||||||
|
$g->setSlug(ICLAMemberDecorator::CCLAGroupSlug);
|
||||||
|
$g->write();
|
||||||
|
|
||||||
|
Permission::grant($g->getIdentifier(),ICLAMemberDecorator::CCLAPermissionSlug);
|
||||||
|
|
||||||
|
$migration = new Migration();
|
||||||
|
$migration->Name = $this->title;
|
||||||
|
$migration->Description = $this->description;
|
||||||
|
$migration->Write();
|
||||||
|
}
|
||||||
|
echo "Ending Migration Proc ...<BR>";
|
||||||
|
}
|
||||||
|
|
||||||
|
function down() {
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
74
ICLA/code/model/CCLACompanyService.php
Normal file
74
ICLA/code/model/CCLACompanyService.php
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/***
|
||||||
|
* Class CCLACompanyService
|
||||||
|
*/
|
||||||
|
final class CCLACompanyService {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ICLACompanyRepository
|
||||||
|
*/
|
||||||
|
private $company_repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ITransactionManager
|
||||||
|
*/
|
||||||
|
private $tx_manager;
|
||||||
|
|
||||||
|
public function __construct(ICLACompanyRepository $company_repository, ITransactionManager $tx_manager){
|
||||||
|
$this->company_repository = $company_repository;
|
||||||
|
$this->tx_manager = $tx_manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $company_id
|
||||||
|
* @return DateTime
|
||||||
|
*/
|
||||||
|
public function signCCLA($company_id){
|
||||||
|
|
||||||
|
$company_repository = $this->company_repository;
|
||||||
|
|
||||||
|
return $this->tx_manager->transaction(function() use($company_id, $company_repository){
|
||||||
|
$company = $company_repository->getById($company_id);
|
||||||
|
|
||||||
|
if(!$company)
|
||||||
|
throw new NotFoundEntityException('Company',sprintf(' id %s',$company_id));
|
||||||
|
|
||||||
|
if(!$company->isICLASigned())
|
||||||
|
$company->signICLA();
|
||||||
|
|
||||||
|
return $company->ICLASignedDate();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $company_id
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function unsignCCLA($company_id){
|
||||||
|
|
||||||
|
$company_repository = $this->company_repository;
|
||||||
|
|
||||||
|
return $this->tx_manager->transaction(function() use($company_id, $company_repository){
|
||||||
|
$company = $company_repository->getById($company_id);
|
||||||
|
|
||||||
|
if(!$company)
|
||||||
|
throw new NotFoundEntityException('Company',sprintf(' id %s',$company_id));
|
||||||
|
|
||||||
|
if($company->isICLASigned())
|
||||||
|
$company->unsignICLA();
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
263
ICLA/code/model/CCLATeamManager.php
Normal file
263
ICLA/code/model/CCLATeamManager.php
Normal file
@ -0,0 +1,263 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class CCLATeamManager
|
||||||
|
*/
|
||||||
|
final class CCLATeamManager {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ITeamInvitationRepository
|
||||||
|
*/
|
||||||
|
private $invitation_repository;
|
||||||
|
/**
|
||||||
|
* @var ITransactionManager
|
||||||
|
*/
|
||||||
|
private $tx_manager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ITeamRepository
|
||||||
|
*/
|
||||||
|
private $team_repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ITeamInvitationFactory
|
||||||
|
*/
|
||||||
|
private $invitation_factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ICCLAValidatorFactory
|
||||||
|
*/
|
||||||
|
private $validator_factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ICLAMemberRepository
|
||||||
|
*/
|
||||||
|
private $member_repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ITeamFactory
|
||||||
|
*/
|
||||||
|
private $team_factory;
|
||||||
|
|
||||||
|
public function __construct(ITeamInvitationRepository $invitation_repository,
|
||||||
|
ICLAMemberRepository $member_repository,
|
||||||
|
ITeamInvitationFactory $invitation_factory,
|
||||||
|
ITeamFactory $team_factory,
|
||||||
|
ICCLAValidatorFactory $validator_factory,
|
||||||
|
ITeamRepository $team_repository,
|
||||||
|
ITransactionManager $tx_manager){
|
||||||
|
|
||||||
|
$this->invitation_repository = $invitation_repository;
|
||||||
|
$this->tx_manager = $tx_manager;
|
||||||
|
$this->team_repository = $team_repository;
|
||||||
|
$this->member_repository = $member_repository;
|
||||||
|
$this->invitation_factory = $invitation_factory;
|
||||||
|
$this->validator_factory = $validator_factory;
|
||||||
|
$this->team_factory = $team_factory;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
* @param ITeamInvitationSender $invitation_sender
|
||||||
|
* @return ITeamInvitation
|
||||||
|
*/
|
||||||
|
public function sendInvitation(array $data, ITeamInvitationSender $invitation_sender){
|
||||||
|
|
||||||
|
$team_repository = $this->team_repository;
|
||||||
|
$invitation_factory = $this->invitation_factory;
|
||||||
|
$validator_factory = $this->validator_factory;
|
||||||
|
$member_repository = $this->member_repository;
|
||||||
|
$invitation_repository = $this->invitation_repository;
|
||||||
|
|
||||||
|
return $this->tx_manager->transaction(function() use($data, $invitation_repository, $team_repository, $invitation_factory , $validator_factory, $member_repository, $invitation_sender){
|
||||||
|
$validator = $validator_factory->buildValidatorForTeamInvitation($data);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
throw new EntityValidationException($validator->messages());
|
||||||
|
}
|
||||||
|
|
||||||
|
$team = $team_repository->getById((int)$data['team_id']);
|
||||||
|
if(!$team) throw new NotFoundEntityException('Team',sprintf('id %s',$data['team_id']));
|
||||||
|
|
||||||
|
$member = false;
|
||||||
|
//is a already selected ICLA/CCLA Member
|
||||||
|
if(isset($data['member_id'])){
|
||||||
|
$member = $member_repository->getById((int)$data['member_id']);
|
||||||
|
if(!$member) throw new NotFoundEntityException('Member',sprintf('id %s',$data['member_id']));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$member = $member_repository->findByEmail(trim($data['email']));
|
||||||
|
if($member && !$member->hasSignedCLA())
|
||||||
|
throw new MemberNotSignedCCLAException('This user has not yet signed the ICLA. Please ensure they have followed the appropriate steps outlined here: https://wiki.openstack.org/wiki/How_To_Contribute#Contributor_License_Agreement');
|
||||||
|
}
|
||||||
|
|
||||||
|
if($member && ($team->isMember($member) || $team->isInvite($member)))
|
||||||
|
throw new TeamMemberAlreadyExistsException('Member Already exists on Team!');
|
||||||
|
|
||||||
|
$invitation = $invitation_factory->buildInvitation(new InvitationDTO($data['first_name'], $data['last_name'], $data['email'], $team, $member ));
|
||||||
|
|
||||||
|
$invitation_repository->add($invitation);
|
||||||
|
|
||||||
|
$invitation_sender->sendInvitation($invitation);
|
||||||
|
|
||||||
|
return $invitation;
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public function verifyInvitations($member_id, ITeamInvitationSender $invitation_sender){
|
||||||
|
|
||||||
|
$member_repository = $this->member_repository;
|
||||||
|
$invitation_repository = $this->invitation_repository;
|
||||||
|
|
||||||
|
return $this->tx_manager->transaction(function() use($member_id, $invitation_repository, $member_repository, $invitation_sender){
|
||||||
|
|
||||||
|
$member = $member_repository->getById($member_id);
|
||||||
|
if(!$member) throw new NotFoundEntityException('Member',sprintf('id %s',$member_id));
|
||||||
|
|
||||||
|
foreach($invitation_repository->findByInviteEmail($member->Email) as $invitation){
|
||||||
|
$invitation->updateInvite($member);
|
||||||
|
$invitation_sender->sendInvitation($invitation);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $team_id
|
||||||
|
* @param int $id
|
||||||
|
* @param string $status
|
||||||
|
* @throws NotFoundEntityException
|
||||||
|
*/
|
||||||
|
public function resignMembership($team_id, $id, $status){
|
||||||
|
$team_repository = $this->team_repository;
|
||||||
|
$member_repository = $this->member_repository;
|
||||||
|
$invitation_repository = $this->invitation_repository;
|
||||||
|
|
||||||
|
$this->tx_manager->transaction(function() use($team_id,$id , $status ,$team_repository, $member_repository, $invitation_repository){
|
||||||
|
$team = $team_repository->getById($team_id);
|
||||||
|
if(!$team) throw new NotFoundEntityException('Team',sprintf('id %s',$team_id));
|
||||||
|
|
||||||
|
switch($status){
|
||||||
|
case 'member':{
|
||||||
|
$member = $member_repository->getById($id);
|
||||||
|
if(!$member) throw new NotFoundEntityException('Member',sprintf('id %s',$id));
|
||||||
|
$team->removeMember($member);
|
||||||
|
$team->removeInvitation($invitation_repository->findByInviteEmailAndTeam($member->Email, $team));
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
default:{
|
||||||
|
$invitation = $invitation_repository->getById($id);
|
||||||
|
if(!$invitation) throw new NotFoundEntityException('TeamInvitation',sprintf('id %s',$id));
|
||||||
|
$team->removeInvitation($invitation);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $token
|
||||||
|
* @param ICLAMember $member
|
||||||
|
* @return ITeam
|
||||||
|
*/
|
||||||
|
public function confirmInvitation($token, ICLAMember $member){
|
||||||
|
$invitation_repository = $this->invitation_repository;
|
||||||
|
|
||||||
|
return $this->tx_manager->transaction(function() use($token, $member, $invitation_repository){
|
||||||
|
$invitation = $invitation_repository->findByConfirmationToken($token);
|
||||||
|
if(!$invitation)
|
||||||
|
throw new NotFoundEntityException('TeamInvitation', sprintf('token %s',$token));
|
||||||
|
if($invitation->getMember()->getIdentifier() !== $member->getIdentifier())
|
||||||
|
throw new InvitationBelongsToAnotherMemberException;
|
||||||
|
$invitation->doConfirmation($token);
|
||||||
|
$invitation->getTeam()->addMember($invitation->getMember());
|
||||||
|
return $invitation->getTeam();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $team_data
|
||||||
|
* @return ITeam
|
||||||
|
*/
|
||||||
|
public function registerTeam(array $team_data){
|
||||||
|
$validator_factory = $this->validator_factory;
|
||||||
|
$team_repository = $this->team_repository;
|
||||||
|
$team_factory = $this->team_factory;
|
||||||
|
|
||||||
|
return $this->tx_manager->transaction(function() use($team_data, $validator_factory, $team_repository, $team_factory){
|
||||||
|
|
||||||
|
$validator = $validator_factory->buildValidatorForTeam($team_data);
|
||||||
|
if ($validator->fails()) {
|
||||||
|
throw new EntityValidationException($validator->messages());
|
||||||
|
}
|
||||||
|
|
||||||
|
$team = $team_factory->buildTeam($team_data);
|
||||||
|
|
||||||
|
if($team_repository->getByNameAndCompany($team->getName(),$team->getCompany()->getIdentifier()))
|
||||||
|
throw new TeamAlreadyExistsException;
|
||||||
|
|
||||||
|
$team_repository->add($team);
|
||||||
|
|
||||||
|
return $team;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $team_id
|
||||||
|
* @param array $data
|
||||||
|
* @return ITeam
|
||||||
|
*/
|
||||||
|
public function updateTeam($team_id, $data){
|
||||||
|
$validator_factory = $this->validator_factory;
|
||||||
|
$team_repository = $this->team_repository;
|
||||||
|
$team_factory = $this->team_factory;
|
||||||
|
|
||||||
|
return $this->tx_manager->transaction(function() use($team_id, $data , $validator_factory, $team_repository, $team_factory){
|
||||||
|
|
||||||
|
$team = $team_repository->getById($team_id);
|
||||||
|
|
||||||
|
if(!$team)
|
||||||
|
throw new NotFoundEntityException('Team', sprintf(' id %s',$team_id ));
|
||||||
|
|
||||||
|
$old_team = $team_repository->getByNameAndCompany($team->getName(),$team->getCompany()->getIdentifier());
|
||||||
|
if($old_team->getIdentifier()!=$team_id)
|
||||||
|
throw new TeamAlreadyExistsException;
|
||||||
|
|
||||||
|
$team->updateName($data['name']);
|
||||||
|
|
||||||
|
return $team;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $team_id
|
||||||
|
*/
|
||||||
|
public function removeTeam($team_id){
|
||||||
|
|
||||||
|
$team_repository = $this->team_repository;
|
||||||
|
$this->tx_manager->transaction(function() use($team_id, $team_repository){
|
||||||
|
|
||||||
|
$team = $team_repository->getById($team_id);
|
||||||
|
|
||||||
|
if(!$team)
|
||||||
|
throw new NotFoundEntityException('Team', sprintf(' id %s',$team_id ));
|
||||||
|
|
||||||
|
$team->clearMembers();
|
||||||
|
$team->clearInvitations();
|
||||||
|
|
||||||
|
$team_repository->delete($team);
|
||||||
|
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
59
ICLA/code/model/IBatchTask.php
Normal file
59
ICLA/code/model/IBatchTask.php
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/***
|
||||||
|
* Interface IBatchTask
|
||||||
|
*/
|
||||||
|
interface IBatchTask extends IEntity {
|
||||||
|
/***
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function name();
|
||||||
|
/***
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function lastRecordProcessed();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function lastResponse();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return DateTime
|
||||||
|
*/
|
||||||
|
public function lastResponseDate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function totalRecords();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $response
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function updateResponse($response);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function updateLastRecord();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $total_qty
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function initialize($total_qty);
|
||||||
|
|
||||||
|
}
|
24
ICLA/code/model/IBatchTaskFactory.php
Normal file
24
ICLA/code/model/IBatchTaskFactory.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Interface IBatchTaskFactory
|
||||||
|
*/
|
||||||
|
interface IBatchTaskFactory {
|
||||||
|
/**
|
||||||
|
* @param string $task_name
|
||||||
|
* @param int $total_record_qty
|
||||||
|
* @return IBatchTask
|
||||||
|
*/
|
||||||
|
public function buildBatchTask($task_name, $total_record_qty);
|
||||||
|
}
|
23
ICLA/code/model/IBatchTaskRepository.php
Normal file
23
ICLA/code/model/IBatchTaskRepository.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Interface IBatchTaskRepository
|
||||||
|
*/
|
||||||
|
interface IBatchTaskRepository extends IEntityRepository {
|
||||||
|
/***
|
||||||
|
* @param string $name
|
||||||
|
* @return IBatchTask
|
||||||
|
*/
|
||||||
|
public function findByName($name);
|
||||||
|
}
|
29
ICLA/code/model/ICCLAValidatorFactory.php
Normal file
29
ICLA/code/model/ICCLAValidatorFactory.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Interface ICCLAValidatorFactory
|
||||||
|
*/
|
||||||
|
interface ICCLAValidatorFactory {
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
* @return IValidator
|
||||||
|
*/
|
||||||
|
public function buildValidatorForTeamInvitation(array $data);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param array $data
|
||||||
|
* @return ValidatorService
|
||||||
|
*/
|
||||||
|
public function buildValidatorForTeam(array $data);
|
||||||
|
}
|
45
ICLA/code/model/ICLACompany.php
Normal file
45
ICLA/code/model/ICLACompany.php
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Interface ICLACompany
|
||||||
|
*/
|
||||||
|
interface ICLACompany extends IEntity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function signICLA();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function unsignICLA();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isICLASigned();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return DateTime
|
||||||
|
*/
|
||||||
|
public function ICLASignedDate();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ITeam[]
|
||||||
|
*/
|
||||||
|
public function Teams();
|
||||||
|
|
||||||
|
public function addTeam(ITeam $team);
|
||||||
|
}
|
19
ICLA/code/model/ICLACompanyRepository.php
Normal file
19
ICLA/code/model/ICLACompanyRepository.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Interface ICLACompanyRepository
|
||||||
|
*/
|
||||||
|
interface ICLACompanyRepository extends IEntityRepository {
|
||||||
|
|
||||||
|
}
|
168
ICLA/code/model/ICLAManager.php
Normal file
168
ICLA/code/model/ICLAManager.php
Normal file
@ -0,0 +1,168 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class ICLAManager
|
||||||
|
*/
|
||||||
|
final class ICLAManager {
|
||||||
|
|
||||||
|
const ICLAGroupTaskName = 'ICLAGroupTask';
|
||||||
|
|
||||||
|
const UpdateLastCommittedDateTaskName = 'UpdateLastCommittedDateTaskName ';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var IGerritAPI
|
||||||
|
*/
|
||||||
|
private $gerrit_api;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var IBatchTaskRepository
|
||||||
|
*/
|
||||||
|
private $batch_repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ICLAMemberRepository
|
||||||
|
*/
|
||||||
|
private $member_repository;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ITransactionManager
|
||||||
|
*/
|
||||||
|
private $tx_manager;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var IBatchTaskFactory
|
||||||
|
*/
|
||||||
|
private $batch_task_factory;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param IGerritAPI $gerrit_api
|
||||||
|
* @param IBatchTaskRepository $batch_repository
|
||||||
|
* @param ICLAMemberRepository $member_repository
|
||||||
|
* @param IBatchTaskFactory $batch_task_factory
|
||||||
|
* @param ITransactionManager $tx_manager
|
||||||
|
*/
|
||||||
|
public function __construct(IGerritAPI $gerrit_api,
|
||||||
|
IBatchTaskRepository $batch_repository,
|
||||||
|
ICLAMemberRepository $member_repository,
|
||||||
|
IBatchTaskFactory $batch_task_factory,
|
||||||
|
ITransactionManager $tx_manager){
|
||||||
|
|
||||||
|
$this->gerrit_api = $gerrit_api;
|
||||||
|
$this->batch_repository = $batch_repository;
|
||||||
|
$this->member_repository = $member_repository;
|
||||||
|
$this->batch_task_factory = $batch_task_factory;
|
||||||
|
$this->tx_manager = $tx_manager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $icla_group_id
|
||||||
|
* @param int $batch_size
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function processICLAGroup($icla_group_id, $batch_size){
|
||||||
|
|
||||||
|
$batch_repository = $this->batch_repository;
|
||||||
|
$member_repository = $this->member_repository;
|
||||||
|
$gerrit_api = $this->gerrit_api;
|
||||||
|
$batch_task_factory = $this->batch_task_factory;
|
||||||
|
|
||||||
|
return $this->tx_manager->transaction(function() use($icla_group_id, $batch_size, $member_repository, $batch_repository, $gerrit_api, $batch_task_factory) {
|
||||||
|
|
||||||
|
$task = $batch_repository->findByName(ICLAManager::ICLAGroupTaskName);
|
||||||
|
$members_ids_on_icla = $member_repository->getAllGerritIds();
|
||||||
|
|
||||||
|
if(!$task){
|
||||||
|
// query gerrit service
|
||||||
|
$icla_members_response = $gerrit_api->listAllMembersFromGroup($icla_group_id);
|
||||||
|
|
||||||
|
$task = $batch_task_factory->buildBatchTask(ICLAManager::ICLAGroupTaskName, count($icla_members_response));
|
||||||
|
$batch_repository->add($task);
|
||||||
|
|
||||||
|
$task->updateResponse(json_encode($icla_members_response));
|
||||||
|
}
|
||||||
|
else if($task->lastRecordProcessed() == $task->totalRecords()){
|
||||||
|
|
||||||
|
$icla_members_response = $gerrit_api->listAllMembersFromGroup($icla_group_id);
|
||||||
|
if(count($icla_members_response) == count(json_decode($task->lastResponse(), true))) return;//nothing to process..
|
||||||
|
$task->initialize(count($icla_members_response));
|
||||||
|
$task->updateResponse(json_encode($icla_members_response));
|
||||||
|
}
|
||||||
|
|
||||||
|
$members = json_decode($task->lastResponse(), true);
|
||||||
|
|
||||||
|
$updated_members = 0;
|
||||||
|
|
||||||
|
for($i = 0; $i < $batch_size && ( ($task->lastRecordProcessed()) < $task->totalRecords() ); $i++){
|
||||||
|
|
||||||
|
$index = $task->lastRecordProcessed();
|
||||||
|
$gerrit_info = $members[$index];
|
||||||
|
$email = @$gerrit_info['email'];
|
||||||
|
$gerrit_id = @$gerrit_info['_account_id'];
|
||||||
|
|
||||||
|
if(!empty($email) && !empty($gerrit_id) ){
|
||||||
|
if(!array_key_exists($gerrit_id, $members_ids_on_icla)){
|
||||||
|
$member = $member_repository->findByEmail($email);
|
||||||
|
if($member){
|
||||||
|
$member->signICLA($gerrit_id);
|
||||||
|
++$updated_members;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$task->updateLastRecord();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $updated_members;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function updateLastCommittedDate($batch_size){
|
||||||
|
|
||||||
|
$batch_repository = $this->batch_repository;
|
||||||
|
$member_repository = $this->member_repository;
|
||||||
|
$gerrit_api = $this->gerrit_api;
|
||||||
|
$batch_task_factory = $this->batch_task_factory;
|
||||||
|
|
||||||
|
return $this->tx_manager->transaction(function() use($batch_size, $member_repository, $batch_repository, $gerrit_api, $batch_task_factory) {
|
||||||
|
|
||||||
|
$task = $batch_repository->findByName(ICLAManager::UpdateLastCommittedDateTaskName);
|
||||||
|
|
||||||
|
$last_index = 0;
|
||||||
|
$members = array();
|
||||||
|
$updated_members = 0;
|
||||||
|
|
||||||
|
if($task){
|
||||||
|
$last_index = $task->lastRecordProcessed();
|
||||||
|
list($members,$total_size) = $member_repository->getAllICLAMembers($last_index, $batch_size);
|
||||||
|
if($task->lastRecordProcessed() == $task->totalRecords()) $task->initialize($total_size);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
list($members,$total_size) = $member_repository->getAllICLAMembers($last_index, $batch_size);
|
||||||
|
$task = $batch_task_factory->buildBatchTask(ICLAManager::UpdateLastCommittedDateTaskName, $total_size);
|
||||||
|
$batch_repository->add($task);
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($members as $member){
|
||||||
|
$last_commit_date = $gerrit_api->getUserLastCommit($member->getGerritId());
|
||||||
|
if(!is_null($last_commit_date) && $last_commit_date){
|
||||||
|
$member->updateLastCommitedDate($last_commit_date);
|
||||||
|
++$updated_members;
|
||||||
|
}
|
||||||
|
$task->updateLastRecord();
|
||||||
|
}
|
||||||
|
|
||||||
|
return $updated_members;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
59
ICLA/code/model/ICLAMember.php
Normal file
59
ICLA/code/model/ICLAMember.php
Normal file
@ -0,0 +1,59 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Interface ICLAMember
|
||||||
|
*/
|
||||||
|
interface ICLAMember extends IEntity {
|
||||||
|
|
||||||
|
const CCLAGroupSlug = 'ccla-admin';
|
||||||
|
const CCLAPermissionSlug = 'CCLA_ADMIN';
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getGerritId();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return DateTime
|
||||||
|
*/
|
||||||
|
public function getLastCommitedDate();
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $gerrit_id
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function signICLA($gerrit_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param DateTime $date
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function updateLastCommitedDate(DateTime $date);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isCCLAAdmin();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ICLACompany
|
||||||
|
*/
|
||||||
|
public function getManagedCCLACompany();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function hasSignedCLA();
|
||||||
|
}
|
55
ICLA/code/model/ICLAMemberRepository.php
Normal file
55
ICLA/code/model/ICLAMemberRepository.php
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Interface ICLAMemberRepository
|
||||||
|
*/
|
||||||
|
interface ICLAMemberRepository extends IMemberRepository {
|
||||||
|
|
||||||
|
/***
|
||||||
|
* @return int[]
|
||||||
|
*/
|
||||||
|
function getAllGerritIds();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $offset
|
||||||
|
* @param int $limit
|
||||||
|
* @return ICLAMember[]
|
||||||
|
*/
|
||||||
|
function getAllICLAMembers($offset, $limit);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $email
|
||||||
|
* @param int $offset
|
||||||
|
* @param int $limit
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function getAllIClaMembersByEmail($email, $offset, $limit);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $first_name
|
||||||
|
* @param int $offset
|
||||||
|
* @param int $limit
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function getAllIClaMembersByFirstName($first_name, $offset, $limit);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $last_name
|
||||||
|
* @param int $offset
|
||||||
|
* @param int $limit
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
function getAllIClaMembersByLastName($last_name, $offset, $limit);
|
||||||
|
|
||||||
|
}
|
29
ICLA/code/model/IGerritAPI.php
Normal file
29
ICLA/code/model/IGerritAPI.php
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Interface IGerritAPI
|
||||||
|
*/
|
||||||
|
interface IGerritAPI {
|
||||||
|
/**
|
||||||
|
* @param string $group_id
|
||||||
|
* @return array
|
||||||
|
*/
|
||||||
|
public function listAllMembersFromGroup($group_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $gerrit_user_id
|
||||||
|
* @return DateTime
|
||||||
|
*/
|
||||||
|
public function getUserLastCommit($gerrit_user_id);
|
||||||
|
}
|
23
ICLA/code/model/IMemberRepository.php
Normal file
23
ICLA/code/model/IMemberRepository.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Interface IMemberRepository
|
||||||
|
*/
|
||||||
|
interface IMemberRepository extends IEntityRepository {
|
||||||
|
/**
|
||||||
|
* @param string $email
|
||||||
|
* @return ICLAMember
|
||||||
|
*/
|
||||||
|
public function findByEmail($email);
|
||||||
|
}
|
83
ICLA/code/model/ITeam.php
Normal file
83
ICLA/code/model/ITeam.php
Normal file
@ -0,0 +1,83 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Interface ITeam
|
||||||
|
*/
|
||||||
|
interface ITeam extends IEntity {
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getName();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $name
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function updateName($name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ICLAMember[]
|
||||||
|
*/
|
||||||
|
public function getMembers();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ICLAMember $member
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function addMember(ICLAMember $member);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ICLAMember $member
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function removeMember(ICLAMember $member);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ITeamInvitation[]
|
||||||
|
*/
|
||||||
|
public function getInvitations();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ITeamInvitation[]
|
||||||
|
*/
|
||||||
|
public function getUnconfirmedInvitations();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ICLACompany
|
||||||
|
*/
|
||||||
|
public function getCompany();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ICLAMember $member
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isInvite(ICLAMember $member);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ICLAMember $member
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isMember(ICLAMember $member);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ITeamInvitation $invitation
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function removeInvitation(ITeamInvitation $invitation);
|
||||||
|
|
||||||
|
public function clearMembers();
|
||||||
|
|
||||||
|
public function clearInvitations();
|
||||||
|
|
||||||
|
}
|
23
ICLA/code/model/ITeamFactory.php
Normal file
23
ICLA/code/model/ITeamFactory.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Interface ITeamFactory
|
||||||
|
*/
|
||||||
|
interface ITeamFactory {
|
||||||
|
/**
|
||||||
|
* @param array $team_data
|
||||||
|
* @return ITeam
|
||||||
|
*/
|
||||||
|
public function buildTeam(array $team_data);
|
||||||
|
}
|
53
ICLA/code/model/ITeamInvitation.php
Normal file
53
ICLA/code/model/ITeamInvitation.php
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Interface ITeamInvitation
|
||||||
|
*/
|
||||||
|
interface ITeamInvitation extends IEntity {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return InviteInfoDTO
|
||||||
|
*/
|
||||||
|
public function getInviteInfo();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isInviteRegisteredAsUser();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ITeam
|
||||||
|
*/
|
||||||
|
public function getTeam();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function generateConfirmationToken();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $token
|
||||||
|
* @return bool
|
||||||
|
* @throws InvalidHashInvitationException
|
||||||
|
* @throws InvitationAlreadyConfirmedException
|
||||||
|
*/
|
||||||
|
public function doConfirmation($token);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ICLAMember
|
||||||
|
*/
|
||||||
|
public function getMember();
|
||||||
|
|
||||||
|
public function updateInvite(ICLAMember $invite);
|
||||||
|
}
|
23
ICLA/code/model/ITeamInvitationFactory.php
Normal file
23
ICLA/code/model/ITeamInvitationFactory.php
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Interface ITeamInvitationFactory
|
||||||
|
*/
|
||||||
|
interface ITeamInvitationFactory {
|
||||||
|
/**
|
||||||
|
* @param InvitationDTO $invitation_dto
|
||||||
|
* @return ITeamInvitation
|
||||||
|
*/
|
||||||
|
public function buildInvitation(InvitationDTO $invitation_dto);
|
||||||
|
}
|
43
ICLA/code/model/ITeamInvitationRepository.php
Normal file
43
ICLA/code/model/ITeamInvitationRepository.php
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Interface ITeamInvitationRepository
|
||||||
|
*/
|
||||||
|
interface ITeamInvitationRepository extends IEntityRepository {
|
||||||
|
/**
|
||||||
|
* @param string $token
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function existsConfirmationToken($token);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $token
|
||||||
|
* @return ITeamInvitation
|
||||||
|
*/
|
||||||
|
public function findByConfirmationToken($token);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $email
|
||||||
|
* @param bool $all
|
||||||
|
* @return ITeamInvitation[]
|
||||||
|
*/
|
||||||
|
public function findByInviteEmail($email, $all = false);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $email
|
||||||
|
* @param ITeam $team
|
||||||
|
* @return ITeamInvitation
|
||||||
|
*/
|
||||||
|
public function findByInviteEmailAndTeam($email, ITeam $team);
|
||||||
|
}
|
24
ICLA/code/model/ITeamInvitationSender.php
Normal file
24
ICLA/code/model/ITeamInvitationSender.php
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Interface ITeamInvitationSender
|
||||||
|
*/
|
||||||
|
interface ITeamInvitationSender {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param ITeamInvitation $invitation
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function sendInvitation(ITeamInvitation $invitation);
|
||||||
|
}
|
30
ICLA/code/model/ITeamRepository.php
Normal file
30
ICLA/code/model/ITeamRepository.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Interface ITeamRepository
|
||||||
|
*/
|
||||||
|
interface ITeamRepository extends IEntityRepository {
|
||||||
|
/**
|
||||||
|
* @param int $company_id
|
||||||
|
* @return ITeam[]
|
||||||
|
*/
|
||||||
|
public function getByCompany($company_id);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $name
|
||||||
|
* @param int $company_id
|
||||||
|
* @return ITeam
|
||||||
|
*/
|
||||||
|
public function getByNameAndCompany($name, $company_id);
|
||||||
|
}
|
55
ICLA/code/model/InvitationDTO.php
Normal file
55
ICLA/code/model/InvitationDTO.php
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class InvitationDTO
|
||||||
|
*/
|
||||||
|
final class InvitationDTO extends InviteInfoDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ITeam
|
||||||
|
*/
|
||||||
|
private $team;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ICLAMember
|
||||||
|
*/
|
||||||
|
private $member;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $first_name
|
||||||
|
* @param string $last_name
|
||||||
|
* @param string $email
|
||||||
|
* @param ITeam $team
|
||||||
|
* @param ICLAMember $member
|
||||||
|
*/
|
||||||
|
public function __construct($first_name, $last_name, $email, ITeam $team, ICLAMember $member = null){
|
||||||
|
parent::__construct($first_name, $last_name, $email);
|
||||||
|
$this->team = $team;
|
||||||
|
$this->member = $member;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @return ITeam
|
||||||
|
*/
|
||||||
|
public function getTeam(){
|
||||||
|
return $this->team;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return ICLAMember
|
||||||
|
*/
|
||||||
|
public function getMember(){
|
||||||
|
return $this->member;
|
||||||
|
}
|
||||||
|
}
|
65
ICLA/code/model/InviteInfoDTO.php
Normal file
65
ICLA/code/model/InviteInfoDTO.php
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class InviteInfoDTO
|
||||||
|
*/
|
||||||
|
class InviteInfoDTO {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $first_name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $last_name;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
protected $email;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $first_name
|
||||||
|
* @param string $last_name
|
||||||
|
* @param string $email
|
||||||
|
*/
|
||||||
|
public function __construct($first_name, $last_name, $email){
|
||||||
|
$this->first_name = $first_name;
|
||||||
|
$this->last_name = $last_name;
|
||||||
|
$this->email = $email;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getFirstName(){
|
||||||
|
return $this->first_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getLastName(){
|
||||||
|
return $this->last_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getEmail(){
|
||||||
|
return $this->email;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class InvalidHashInvitationException
|
||||||
|
*/
|
||||||
|
final class InvalidHashInvitationException extends Exception {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class InvitationAlreadyConfirmedException
|
||||||
|
*/
|
||||||
|
final class InvitationAlreadyConfirmedException extends Exception {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class InvitationBelongsToAnotherMemberException
|
||||||
|
*/
|
||||||
|
final class InvitationBelongsToAnotherMemberException extends Exception {
|
||||||
|
|
||||||
|
}
|
20
ICLA/code/model/exceptions/MemberNotSignedCCLAException.php
Normal file
20
ICLA/code/model/exceptions/MemberNotSignedCCLAException.php
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class MemberNotSignedCCLAException
|
||||||
|
*/
|
||||||
|
final class MemberNotSignedCCLAException extends Exception {
|
||||||
|
|
||||||
|
|
||||||
|
}
|
19
ICLA/code/model/exceptions/TeamAlreadyExistsException.php
Normal file
19
ICLA/code/model/exceptions/TeamAlreadyExistsException.php
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class TeamAlreadyExistsException
|
||||||
|
*/
|
||||||
|
final class TeamAlreadyExistsException extends Exception {
|
||||||
|
|
||||||
|
}
|
@ -0,0 +1,19 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class TeamMemberAlreadyExistsException
|
||||||
|
*/
|
||||||
|
final class TeamMemberAlreadyExistsException extends Exception {
|
||||||
|
|
||||||
|
}
|
89
ICLA/code/ui/admin/SangriaPageICLACompaniesExtension.php
Normal file
89
ICLA/code/ui/admin/SangriaPageICLACompaniesExtension.php
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class SangriaPageICLACompaniesExtension
|
||||||
|
*/
|
||||||
|
final class SangriaPageICLACompaniesExtension extends Extension {
|
||||||
|
|
||||||
|
private static $allowed_actions = array('ViewICLACompanies','exportCCLACompanies');
|
||||||
|
/**
|
||||||
|
* @var ICLACompanyRepository
|
||||||
|
*/
|
||||||
|
private $company_repository;
|
||||||
|
|
||||||
|
public function __construct(){
|
||||||
|
parent::__construct();
|
||||||
|
$this->company_repository = new SapphireICLACompanyRepository();
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onBeforeInit(){
|
||||||
|
Config::inst()->update(get_class($this->owner), 'allowed_actions', array('ViewICLACompanies','exportCCLACompanies'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getQuickActionsExtensions(&$html){
|
||||||
|
$view = new SSViewer('SangriaPage_ICLALinks');
|
||||||
|
$html .= $view->process($this->owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function ViewICLACompanies(){
|
||||||
|
Requirements::css('ICLA/css/sangia.ccla.companies.css');
|
||||||
|
Requirements::javascript('ICLA/js/sangia.ccla.companies.js');
|
||||||
|
return $this->owner->getViewer('ViewICLACompanies')->process($this->owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCompanies(){
|
||||||
|
$query = new QueryObject;
|
||||||
|
$query->addOrder(QueryOrder::asc('Name'));
|
||||||
|
list($list,$size) = $this->company_repository->getAll($query,0,1000);
|
||||||
|
return new ArrayList($list);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function exportCCLACompanies(){
|
||||||
|
//clean output buffer
|
||||||
|
ob_end_clean();
|
||||||
|
// file name for download
|
||||||
|
$filename = "companies_ccla" . date('Ymd') . ".xls";
|
||||||
|
header("Content-Disposition: attachment; filename=\"$filename\"");
|
||||||
|
header("Content-Type: application/vnd.ms-excel");
|
||||||
|
$query = new QueryObject;
|
||||||
|
$query->addOrder(QueryOrder::asc('Name'));
|
||||||
|
list($list,$size) = $this->company_repository->getAll($query,0,1000);
|
||||||
|
$data = array();
|
||||||
|
foreach($list as $company){
|
||||||
|
$row = array();
|
||||||
|
$row['CompanyName'] = $company->Name;
|
||||||
|
$row['CCLADate'] = $company->isICLASigned()? $company->CCLADate:'N/A';
|
||||||
|
$row['CCLASigned'] = $company->isICLASigned()? 'True':'False';
|
||||||
|
array_push($data, $row);
|
||||||
|
}
|
||||||
|
$flag = false;
|
||||||
|
foreach($data as $row) {
|
||||||
|
if(!$flag) {
|
||||||
|
// display field/column names as first row
|
||||||
|
echo implode("\t", array_keys($row)) . "\n";
|
||||||
|
$flag = true;
|
||||||
|
}
|
||||||
|
array_walk($row, array($this,'cleanData'));
|
||||||
|
echo implode("\t", array_values($row)) . "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function cleanData(&$str)
|
||||||
|
{
|
||||||
|
$str = preg_replace("/\t/", "\\t", $str);
|
||||||
|
$str = preg_replace("/\r?\n/", "\\n", $str);
|
||||||
|
if(strstr($str, '"')) $str = '"' . str_replace('"', '""', $str) . '"';
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
110
ICLA/code/ui/frontend/EditProfilePageICLAExtension.php
Normal file
110
ICLA/code/ui/frontend/EditProfilePageICLAExtension.php
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class EditProfilePageICLAExtension
|
||||||
|
*/
|
||||||
|
final class EditProfilePageICLAExtension extends Extension {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var ITeamRepository
|
||||||
|
*/
|
||||||
|
private $team_repository;
|
||||||
|
|
||||||
|
public function __construct(){
|
||||||
|
$this->team_repository = new SapphireTeamRepository;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function onBeforeInit(){
|
||||||
|
Config::inst()->update(get_class($this), 'allowed_actions', array('CCLATeamAdmin'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getNavActionsExtensions(&$html){
|
||||||
|
$view = new SSViewer('EditProfilePage_ICLANav');
|
||||||
|
$html .= $view->process($this->owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function CCLATeamAdmin(){
|
||||||
|
Requirements::javascript('marketplace/code/ui/admin/js/utils.js');
|
||||||
|
Requirements::customScript('var company_id = '.$this->getCompanyID().';');
|
||||||
|
Requirements::javascript('ICLA/js/edit.profile.ccla.teams.js');
|
||||||
|
Requirements::javascript(Director::protocol()."ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/jquery.validate.min.js");
|
||||||
|
Requirements::javascript(Director::protocol()."ajax.aspnetcdn.com/ajax/jquery.validate/1.11.1/additional-methods.min.js");
|
||||||
|
Requirements::javascript("themes/openstack/javascript/jquery.validate.custom.methods.js");
|
||||||
|
Requirements::css('ICLA/css/edit.profile.ccla.teams.css');
|
||||||
|
return $this->owner->getViewer('CCLATeamAdmin')->process($this->owner);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTeamsDLL($id='add_member_team'){
|
||||||
|
$current_member = Member::currentUser();
|
||||||
|
if(!$current_member) return false;
|
||||||
|
$company = $current_member->getManagedCCLACompany();
|
||||||
|
if(!$company) return false;
|
||||||
|
$res = $this->team_repository->getByCompany($company->getIdentifier());
|
||||||
|
$res = new ArrayList($res);
|
||||||
|
$ddl = new DropdownField($id,null, $res->map("ID", "Name"));
|
||||||
|
$ddl->setEmptyString('-- Select a Team --');
|
||||||
|
return $ddl;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTeamMembers(){
|
||||||
|
$current_member = Member::currentUser();
|
||||||
|
if(!$current_member) return false;
|
||||||
|
$company = $current_member->getManagedCCLACompany();
|
||||||
|
if(!$company) return false;
|
||||||
|
$teams = $this->team_repository->getByCompany($company->getIdentifier());
|
||||||
|
$members = array();
|
||||||
|
|
||||||
|
foreach($teams as $team){
|
||||||
|
|
||||||
|
foreach($team->getMembers() as $team_member){
|
||||||
|
array_push($members, new TeamMemberViewModel($team_member->FirstName, $team_member->Surname, $team_member->Email, $team->getIdentifier() ,$team->getName(),'member', $team_member->getIdentifier() ,$team_member->DateAdded));
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach($team->getUnconfirmedInvitations() as $team_invitation){
|
||||||
|
$info = $team_invitation->getInviteInfo();
|
||||||
|
$status = $team_invitation->isInviteRegisteredAsUser()? 'needs-confirmation':'needs-registration';
|
||||||
|
array_push($members, new TeamMemberViewModel($info->getFirstName(), $info->getLastName(), $info->getEmail(), $team->getIdentifier() , $team->getName(), $status, $team_invitation->getIdentifier(),$team_invitation->Created ));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
usort($members, array($this,'cmp_team_members'));
|
||||||
|
|
||||||
|
return new ArrayList($members);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function cmp_team_members($a, $b){
|
||||||
|
$name1 = $a->getFirstName().' '.$a->getLastName();
|
||||||
|
$name2 = $b->getFirstName().' '.$b->getLastName();
|
||||||
|
if ($name1 == $name2) {
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
return ($name1 < $name2) ? -1 : 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCompanyName(){
|
||||||
|
$current_member = Member::currentUser();
|
||||||
|
if(!$current_member) return false;
|
||||||
|
$company = $current_member->getManagedCCLACompany();
|
||||||
|
if(!$company) return false;
|
||||||
|
return $company->Name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getCompanyID(){
|
||||||
|
$current_member = Member::currentUser();
|
||||||
|
if(!$current_member) return false;
|
||||||
|
$company = $current_member->getManagedCCLACompany();
|
||||||
|
if(!$company) return false;
|
||||||
|
return $company->ID;
|
||||||
|
}
|
||||||
|
}
|
107
ICLA/code/ui/frontend/TeamMemberViewModel.php
Normal file
107
ICLA/code/ui/frontend/TeamMemberViewModel.php
Normal file
@ -0,0 +1,107 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class TeamMemberViewModel
|
||||||
|
*/
|
||||||
|
final class TeamMemberViewModel extends ViewableData {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $first_name;
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $last_name;
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $email;
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $team_name;
|
||||||
|
/**
|
||||||
|
* @var string
|
||||||
|
*/
|
||||||
|
private $status;
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private $id;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var int
|
||||||
|
*/
|
||||||
|
private $team_id;
|
||||||
|
|
||||||
|
private $date_added;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $first_name
|
||||||
|
* @param string $last_name
|
||||||
|
* @param string $email
|
||||||
|
* @param string $team_name
|
||||||
|
* @param int $team_id
|
||||||
|
* @param string $status
|
||||||
|
* @param int $id
|
||||||
|
* @param $date_added
|
||||||
|
*/
|
||||||
|
public function __construct($first_name, $last_name, $email, $team_id, $team_name, $status, $id, $date_added){
|
||||||
|
$this->first_name = $first_name;
|
||||||
|
$this->last_name = $last_name;
|
||||||
|
$this->email = $email;
|
||||||
|
$this->team_name = $team_name;
|
||||||
|
$this->team_id = $team_id;
|
||||||
|
$this->status = $status;
|
||||||
|
$this->id = $id;
|
||||||
|
$this->date_added = $date_added;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function getStatus(){
|
||||||
|
return $this->status;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getFirstName(){
|
||||||
|
return $this->first_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getLastName(){
|
||||||
|
return $this->last_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getEmail(){
|
||||||
|
return $this->email;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getId(){
|
||||||
|
return $this->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTeamName(){
|
||||||
|
return $this->team_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getTeamId(){
|
||||||
|
return $this->team_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getDateAdded(){
|
||||||
|
return $this->date_added;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
52
ICLA/css/edit.profile.ccla.teams.css
Normal file
52
ICLA/css/edit.profile.ccla.teams.css
Normal file
@ -0,0 +1,52 @@
|
|||||||
|
#ccla_teams {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-collapse: collapse;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ccla_teams thead th {
|
||||||
|
background: none repeat scroll 0 0 #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-base {
|
||||||
|
border-radius: 50%;
|
||||||
|
width: 15px;
|
||||||
|
height: 15px;
|
||||||
|
cursor: pointer;
|
||||||
|
}
|
||||||
|
|
||||||
|
.member {
|
||||||
|
background: green;
|
||||||
|
}
|
||||||
|
|
||||||
|
.needs-confirmation {
|
||||||
|
background: yellow;
|
||||||
|
}
|
||||||
|
|
||||||
|
.needs-registration {
|
||||||
|
background: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
label.error {
|
||||||
|
width: auto !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
input.error {
|
||||||
|
padding: 0 !important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.ui-autocomplete {
|
||||||
|
z-index: 999999999999999999!important;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-legend{
|
||||||
|
float:left;
|
||||||
|
padding-left: 5px;
|
||||||
|
padding-right: 5px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.status-legend-container{
|
||||||
|
padding-top: 5px;
|
||||||
|
padding-bottom: 5px;
|
||||||
|
}
|
13
ICLA/css/sangia.ccla.companies.css
Normal file
13
ICLA/css/sangia.ccla.companies.css
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
#ccla-companies-table {
|
||||||
|
border: 1px solid #ccc;
|
||||||
|
border-collapse: collapse;
|
||||||
|
clear: both;
|
||||||
|
}
|
||||||
|
|
||||||
|
#ccla-companies-table thead th {
|
||||||
|
background: none repeat scroll 0 0 #FFFFFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
.row-0{
|
||||||
|
background-color:#dcdcdc;
|
||||||
|
}
|
300
ICLA/js/edit.profile.ccla.teams.js
Normal file
300
ICLA/js/edit.profile.ccla.teams.js
Normal file
@ -0,0 +1,300 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
jQuery(document).ready(function($) {
|
||||||
|
|
||||||
|
var form = $('#ccla_teams_form');
|
||||||
|
|
||||||
|
var form_validator = form.validate({
|
||||||
|
rules: {
|
||||||
|
add_member_email : {
|
||||||
|
required:true,
|
||||||
|
email:true
|
||||||
|
},
|
||||||
|
add_member_lname : {
|
||||||
|
required:true,
|
||||||
|
ValidPlainText:true
|
||||||
|
},
|
||||||
|
add_member_fname : {
|
||||||
|
required:true,
|
||||||
|
ValidPlainText:true
|
||||||
|
},
|
||||||
|
add_member_team:{
|
||||||
|
required:true
|
||||||
|
}
|
||||||
|
},
|
||||||
|
onfocusout: false,
|
||||||
|
focusCleanup: true,
|
||||||
|
focusInvalid: false,
|
||||||
|
invalidHandler: function(form, validator) {
|
||||||
|
if (!validator.numberOfInvalids())
|
||||||
|
return;
|
||||||
|
var element = $(validator.errorList[0].element);
|
||||||
|
if(!element.is(":visible")){
|
||||||
|
element = element.parent();
|
||||||
|
}
|
||||||
|
|
||||||
|
$('html, body').animate({
|
||||||
|
scrollTop: element.offset().top
|
||||||
|
}, 2000);
|
||||||
|
},
|
||||||
|
errorPlacement: function(error, element) {
|
||||||
|
if(!element.is(":visible")){
|
||||||
|
element = element.parent();
|
||||||
|
}
|
||||||
|
error.insertAfter(element);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#add_member_email').autocomplete({
|
||||||
|
source: 'api/v1/ccla/members?field=email',
|
||||||
|
minLength: 2,
|
||||||
|
select: function (event, ui) {
|
||||||
|
$("#add_member_email" ).val(ui.item.email);
|
||||||
|
$("#add_member_lname" ).val(ui.item.last_name);
|
||||||
|
$("#add_member_fname" ).val(ui.item.first_name);
|
||||||
|
$('#add_member_row').attr("data-member-id", ui.item.value);
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
focus: function( event, ui ) {
|
||||||
|
$("#add_member_email" ).val(ui.item.email);
|
||||||
|
$("#add_member_lname" ).val(ui.item.last_name);
|
||||||
|
$("#add_member_fname" ).val(ui.item.first_name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
$('#add_member_lname').autocomplete({
|
||||||
|
source: 'api/v1/ccla/members?field=lname',
|
||||||
|
minLength: 2,
|
||||||
|
select: function (event, ui) {
|
||||||
|
$("#add_member_email" ).val(ui.item.email);
|
||||||
|
$("#add_member_lname" ).val(ui.item.last_name);
|
||||||
|
$("#add_member_fname" ).val(ui.item.first_name);
|
||||||
|
$('#add_member_row').attr("data-member-id", ui.item.value);
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
focus: function( event, ui ) {
|
||||||
|
$("#add_member_email" ).val(ui.item.email);
|
||||||
|
$("#add_member_lname" ).val(ui.item.last_name);
|
||||||
|
$("#add_member_fname" ).val(ui.item.first_name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
$('#add_member_fname').autocomplete({
|
||||||
|
source: 'api/v1/ccla/members?field=fname',
|
||||||
|
minLength: 2,
|
||||||
|
select: function (event, ui) {
|
||||||
|
$("#add_member_email" ).val(ui.item.email);
|
||||||
|
$("#add_member_lname" ).val(ui.item.last_name);
|
||||||
|
$("#add_member_fname" ).val(ui.item.first_name);
|
||||||
|
$('#add_member_row').attr("data-member-id", ui.item.value);
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
focus: function( event, ui ) {
|
||||||
|
$("#add_member_email" ).val(ui.item.email);
|
||||||
|
$("#add_member_lname" ).val(ui.item.last_name);
|
||||||
|
$("#add_member_fname" ).val(ui.item.first_name);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
$('.delete_member').live('click',function(event){
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
|
||||||
|
if(confirm('Are you sure?')){
|
||||||
|
var button = $(this);
|
||||||
|
if(button.prop('disabled')){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
button.prop('disabled',true);
|
||||||
|
|
||||||
|
var id = button.attr('data-id');
|
||||||
|
var status = button.attr('data-status');
|
||||||
|
var team_id = button.attr('data-team-id');
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: 'DELETE',
|
||||||
|
url: 'api/v1/ccla/teams/'+team_id+'/memberships/'+id+'/'+status,
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
dataType: "json",
|
||||||
|
success: function (data,textStatus,jqXHR) {
|
||||||
|
var row = button.parent().parent();
|
||||||
|
row.remove();
|
||||||
|
},
|
||||||
|
error: function (jqXHR, textStatus, errorThrown) {
|
||||||
|
ajaxError(jqXHR, textStatus, errorThrown);
|
||||||
|
button.prop('disabled',false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#add_member').click(function(event){
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
var button = $(this);
|
||||||
|
if(button.prop('disabled')){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var is_valid = form.valid();
|
||||||
|
if(!is_valid){
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
//save
|
||||||
|
var invitation = {
|
||||||
|
email : $("#add_member_email" ).val(),
|
||||||
|
first_name : $("#add_member_fname" ).val(),
|
||||||
|
last_name : $("#add_member_lname" ).val(),
|
||||||
|
team_id : $("#add_member_team" ).val()
|
||||||
|
};
|
||||||
|
|
||||||
|
var member_id = $('#add_member_row').attr("data-member-id");
|
||||||
|
|
||||||
|
if(typeof(member_id) !== "undefined")
|
||||||
|
invitation.member_id = member_id;
|
||||||
|
|
||||||
|
button.prop('disabled',true);
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: 'api/v1/ccla/invitations',
|
||||||
|
data: JSON.stringify(invitation),
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
dataType: "json",
|
||||||
|
success: function (data,textStatus,jqXHR) {
|
||||||
|
button.prop('disabled',false);
|
||||||
|
$("#add_member_email" ).val('');
|
||||||
|
$("#add_member_fname" ).val('');
|
||||||
|
$("#add_member_lname" ).val('');
|
||||||
|
$("#add_member_team" ).val('');
|
||||||
|
$('#add_member_row').attr("data-member-id",'');
|
||||||
|
location.reload();
|
||||||
|
},
|
||||||
|
error: function (jqXHR, textStatus, errorThrown) {
|
||||||
|
ajaxError(jqXHR, textStatus, errorThrown);
|
||||||
|
button.prop('disabled',false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return false;
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#select_edit_team').change(function(event){
|
||||||
|
var team_id = $(this).val();
|
||||||
|
if(team_id!=''){
|
||||||
|
$('#edit_team_name').val($('option:selected', this).text());
|
||||||
|
$('#add_team').hide();
|
||||||
|
$('#save_team').show();
|
||||||
|
$('#delete_team').show();
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$('#add_team').show();
|
||||||
|
$('#save_team').hide();
|
||||||
|
$('#delete_team').hide();
|
||||||
|
$('#edit_team_name').val('');
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#save_team').click(function(event){
|
||||||
|
|
||||||
|
$('#add_team').show();
|
||||||
|
$('#save_team').hide();
|
||||||
|
$('#delete_team').hide();
|
||||||
|
var button = $(this);
|
||||||
|
var team_id = $('#select_edit_team').val();
|
||||||
|
var team = {name : $('#edit_team_name').val()};
|
||||||
|
|
||||||
|
if(team.name.trim()===''){
|
||||||
|
alert('You must provide a valid team name!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#edit_team_name').val('');
|
||||||
|
$.ajax({
|
||||||
|
type: 'PUT',
|
||||||
|
url: 'api/v1/ccla/teams/'+team_id,
|
||||||
|
data: JSON.stringify(team),
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
dataType: "json",
|
||||||
|
success: function (data,textStatus,jqXHR) {
|
||||||
|
location.reload();
|
||||||
|
},
|
||||||
|
error: function (jqXHR, textStatus, errorThrown) {
|
||||||
|
ajaxError(jqXHR, textStatus, errorThrown);
|
||||||
|
button.prop('disabled',false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#add_team').click(function(event){
|
||||||
|
|
||||||
|
var button = $(this);
|
||||||
|
var team = { name: $('#edit_team_name').val() , company_id : company_id};
|
||||||
|
|
||||||
|
if(team.name.trim()===''){
|
||||||
|
alert('You must provide a valid team name!');
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
$('#edit_team_name').val('');
|
||||||
|
$('#add_team').show();
|
||||||
|
$('#save_team').hide();
|
||||||
|
$('#delete_team').hide();
|
||||||
|
button.prop('disabled',true);
|
||||||
|
$.ajax({
|
||||||
|
type: 'POST',
|
||||||
|
url: 'api/v1/ccla/teams',
|
||||||
|
data: JSON.stringify(team),
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
dataType: "json",
|
||||||
|
success: function (data,textStatus,jqXHR) {
|
||||||
|
location.reload();
|
||||||
|
},
|
||||||
|
error: function (jqXHR, textStatus, errorThrown) {
|
||||||
|
ajaxError(jqXHR, textStatus, errorThrown);
|
||||||
|
button.prop('disabled',false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
$('#delete_team').click(function(event){
|
||||||
|
if(confirm('Are you sure? this will clear all memberships and all pending invitations as well.')){
|
||||||
|
$('#edit_team_name').val('');
|
||||||
|
$('#add_team').show();
|
||||||
|
$('#save_team').hide();
|
||||||
|
$('#delete_team').hide();
|
||||||
|
var button = $(this);
|
||||||
|
button.prop('disabled',true);
|
||||||
|
var team_id = $('#select_edit_team').val();
|
||||||
|
$.ajax({
|
||||||
|
type: 'DELETE',
|
||||||
|
url: 'api/v1/ccla/teams/'+team_id,
|
||||||
|
contentType: "application/json; charset=utf-8",
|
||||||
|
dataType: "json",
|
||||||
|
success: function (data,textStatus,jqXHR) {
|
||||||
|
location.reload();
|
||||||
|
},
|
||||||
|
error: function (jqXHR, textStatus, errorThrown) {
|
||||||
|
ajaxError(jqXHR, textStatus, errorThrown);
|
||||||
|
button.prop('disabled',false);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
48
ICLA/js/sangia.ccla.companies.js
Normal file
48
ICLA/js/sangia.ccla.companies.js
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
jQuery(document).ready(function($) {
|
||||||
|
|
||||||
|
$('.ccla_checkbox').click(function(event){
|
||||||
|
var sign = $(this).is(":checked");
|
||||||
|
|
||||||
|
if(!sign && !confirm("Are you sure...?")){
|
||||||
|
event.preventDefault();
|
||||||
|
event.stopPropagation();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
var company_id = $(this).attr('data-company-id');
|
||||||
|
var url = 'api/v1/ccla/companies/'+company_id+'/sign';
|
||||||
|
var verb = sign?'PUT':'DELETE';
|
||||||
|
|
||||||
|
$.ajax({
|
||||||
|
async:true,
|
||||||
|
type: verb,
|
||||||
|
url: url,
|
||||||
|
dataType: "json",
|
||||||
|
success: function (data,textStatus,jqXHR) {
|
||||||
|
var td = $('#ccla_date_'+company_id);
|
||||||
|
if(sign){
|
||||||
|
var date = data.sign_date.date;
|
||||||
|
td.html(date);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
td.html('');
|
||||||
|
}
|
||||||
|
},
|
||||||
|
error: function (jqXHR, textStatus, errorThrown) {
|
||||||
|
alert( "Request failed: " + textStatus );
|
||||||
|
}
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
24
ICLA/readme.txt
Normal file
24
ICLA/readme.txt
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
** Scheduled tasks
|
||||||
|
|
||||||
|
make cache folder writable to all
|
||||||
|
|
||||||
|
sudo chmod 777 -R tmp/path/to/ss/cache/folder
|
||||||
|
|
||||||
|
add to _ss_environment.php file following global:
|
||||||
|
|
||||||
|
global $_FILE_TO_URL_MAPPING;
|
||||||
|
$_FILE_TO_URL_MAPPING['/path/to/project'] = 'http://localhost';
|
||||||
|
|
||||||
|
|
||||||
|
PullCLAFromGerritTask:
|
||||||
|
|
||||||
|
pulls gerrit endpoint https://gerrit-review.googlesource.com/Documentation/rest-api-groups.html#group-members
|
||||||
|
using icla group id, and update all members on Member table with gerrit id and icla signed
|
||||||
|
|
||||||
|
* php /path/to/project/sapphire/cli-script.php /PullCLAFromGerritTask
|
||||||
|
|
||||||
|
UpdateLastCommitedDateTask:
|
||||||
|
|
||||||
|
pulls from gerrit the last commit date for all users with icla signed and update on member table
|
||||||
|
|
||||||
|
* php /path/to/project/sapphire/cli-script.php /UpdateLastCommittedDateTask
|
25
ICLA/templates/Layout/EditProfilePage_CCLATeamAdmin.ss
Normal file
25
ICLA/templates/Layout/EditProfilePage_CCLATeamAdmin.ss
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
$SetCurrentTab(6)
|
||||||
|
<% require themedCSS(profile-section) %>
|
||||||
|
<h1>$Title</h1>
|
||||||
|
<% if CurrentMember %>
|
||||||
|
<% include ProfileNav %>
|
||||||
|
<% if CurrentMember.isCCLAAdmin %>
|
||||||
|
<fieldset>
|
||||||
|
<% include EditProfilePage_Teams %>
|
||||||
|
<br>
|
||||||
|
<br>
|
||||||
|
<% include EditProfilePage_TeamMembers %>
|
||||||
|
</fieldset>
|
||||||
|
<% else %>
|
||||||
|
<p>You are not allowed to administer ICCLA/CCLA Team Members</p>
|
||||||
|
<% end_if %>
|
||||||
|
<% else %>
|
||||||
|
<p>In order to edit your community profile, you will first need to
|
||||||
|
<a href="/Security/login/?BackURL=%2Fprofile%2F">login as a member</a>. Don't have an account?
|
||||||
|
<a href="/join/">Join The Foundation</a>
|
||||||
|
</p>
|
||||||
|
<p>
|
||||||
|
<a class="roundedButton" href="/Security/login/?BackURL=%2Fprofile%2F">Login</a>
|
||||||
|
<a href="/join/" class="roundedButton">Join The Foundation</a>
|
||||||
|
</p>
|
||||||
|
<% end_if %>
|
3
ICLA/templates/Layout/EditProfilePage_ICLANav.ss
Normal file
3
ICLA/templates/Layout/EditProfilePage_ICLANav.ss
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
<% if CurrentMember.isCCLAAdmin %>
|
||||||
|
<a href="{$Link}CCLATeamAdmin" <% if CurrentTab=6 %>class="active"<% end_if %> >CCLA Team Administration</a>
|
||||||
|
<% end_if %>
|
@ -0,0 +1,57 @@
|
|||||||
|
<h2>$CompanyName Team Members Administration</h2>
|
||||||
|
|
||||||
|
<form name="ccla_teams_form" id="ccla_teams_form">
|
||||||
|
<div class="status-legend-container">
|
||||||
|
<div style="float:left" class="status-base needs-registration"></div><div class="status-legend">Needs Registration</div>
|
||||||
|
<div style="float:left" class="status-base needs-confirmation"></div><div class="status-legend">Needs Confirmation</div>
|
||||||
|
<div style="float:left" class="status-base member"></div><div class="status-legend">Is Member</div>
|
||||||
|
</div>
|
||||||
|
<table id="ccla_teams">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>First Name</th>
|
||||||
|
<th>Last Name</th>
|
||||||
|
<th>Email</th>
|
||||||
|
<th>Team</th>
|
||||||
|
<th>Date Added</th>
|
||||||
|
<th> </th>
|
||||||
|
<th> </th>
|
||||||
|
</tr>
|
||||||
|
<tr id="add_member_row">
|
||||||
|
<td>
|
||||||
|
<input type="text" id="add_member_fname" name="add_member_fname">
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
<input type="text" id="add_member_lname" name="add_member_lname">
|
||||||
|
</td>
|
||||||
|
|
||||||
|
<td>
|
||||||
|
<input type="text" id="add_member_email" name="add_member_email">
|
||||||
|
</td>
|
||||||
|
<td>
|
||||||
|
$TeamsDLL
|
||||||
|
</td>
|
||||||
|
<td colspan="3">
|
||||||
|
<button id="add_member">Add</button>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tfoot>
|
||||||
|
</tfoot>
|
||||||
|
<tbody>
|
||||||
|
<% if TeamMembers %>
|
||||||
|
<% loop TeamMembers %>
|
||||||
|
<tr data-id="{$Id}">
|
||||||
|
<td>$FirstName</td>
|
||||||
|
<td>$LastName</td>
|
||||||
|
<td>$Email</td>
|
||||||
|
<td>$TeamName</td>
|
||||||
|
<td>$DateAdded</td>
|
||||||
|
<td><div class="status-base {$Status}" title="{$Status}"></div></td>
|
||||||
|
<td><button class="delete_member" data-team-id="{$TeamId}" data-id="{$Id}" data-status="{$Status}">Delete</button></td>
|
||||||
|
</tr>
|
||||||
|
<% end_loop %>
|
||||||
|
<% end_if %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
</form>
|
6
ICLA/templates/Layout/Includes/EditProfilePage_Teams.ss
Normal file
6
ICLA/templates/Layout/Includes/EditProfilePage_Teams.ss
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
<h2>$CompanyName Teams Administration</h2>
|
||||||
|
<input type="text" name="edit_team_name" id="edit_team_name">
|
||||||
|
<button id="add_team" >Add</button>
|
||||||
|
<button id="save_team" style="display:none;">Save</button>
|
||||||
|
<button id="delete_team" style="display:none;">Delete</button>
|
||||||
|
$getTeamsDLL('select_edit_team')
|
@ -0,0 +1,6 @@
|
|||||||
|
<p> $FirstName $LastName, a request has been made by $CompanyName
|
||||||
|
to add you to their Corporate CLA. In order to confirm the invitation please click on following link
|
||||||
|
<a href="{$ConfirmationLink}">Confirm Membership</a>.
|
||||||
|
</p>
|
||||||
|
Thank you,<BR>
|
||||||
|
The OpenStack Team.<BR>
|
@ -0,0 +1,5 @@
|
|||||||
|
<p> Hello, $FirstName $LastName, you have been invited to $CompanyName $TeamName Team.
|
||||||
|
In order to be able to join to this team, please register first with an OpenstackID
|
||||||
|
<a href="{$RegistrationLink}">Register</a>.
|
||||||
|
The OpenStack Team.
|
||||||
|
</p>
|
4
ICLA/templates/Layout/SangriaPage_ICLALinks.ss
Normal file
4
ICLA/templates/Layout/SangriaPage_ICLALinks.ss
Normal file
@ -0,0 +1,4 @@
|
|||||||
|
<h2>CLA/ICLA Companies</h2>
|
||||||
|
<ul>
|
||||||
|
<li><a href="$Top.Link(ViewICLACompanies)">View CLA/ICLA Companies</a></li>
|
||||||
|
</ul>
|
25
ICLA/templates/Layout/SangriaPage_ViewICLACompanies.ss
Normal file
25
ICLA/templates/Layout/SangriaPage_ViewICLACompanies.ss
Normal file
@ -0,0 +1,25 @@
|
|||||||
|
<h2>CLA/ICLA Companies</h2>
|
||||||
|
<% if Companies %>
|
||||||
|
<a href="$Link(exportCCLACompanies)">export to excel</a>
|
||||||
|
<table id="ccla-companies-table">
|
||||||
|
<thead>
|
||||||
|
<tr>
|
||||||
|
<th>Company Name</th>
|
||||||
|
<th>CCLA Date</th>
|
||||||
|
<th>CCLA Signed</th>
|
||||||
|
</tr>
|
||||||
|
</thead>
|
||||||
|
<tbody>
|
||||||
|
<% loop Companies %>
|
||||||
|
<tr class="row-{$Modulus(2)}">
|
||||||
|
|
||||||
|
<td>$Name</td>
|
||||||
|
<td id="ccla_date_{$ID}">$CCLADate</td>
|
||||||
|
<td>
|
||||||
|
<input type="checkbox" class="ccla_checkbox" data-company-id="{$ID}" id="ccla_signed_checkbox_{$ID}" name="ccla_signed_checkbox_{$ID}" <% if isICLASigned %> checked <% end_if %>>
|
||||||
|
</td>
|
||||||
|
</tr>
|
||||||
|
<% end_loop %>
|
||||||
|
</tbody>
|
||||||
|
</table>
|
||||||
|
<% end_if %>
|
@ -0,0 +1,3 @@
|
|||||||
|
<p>
|
||||||
|
Team Membership confirmation belongs to user $UserName. Logout and try to login as that user in order to confirm.
|
||||||
|
</p>
|
@ -0,0 +1,3 @@
|
|||||||
|
<p>
|
||||||
|
There was an error on your Team Membership confirmation.
|
||||||
|
</p>
|
@ -0,0 +1,6 @@
|
|||||||
|
<p>
|
||||||
|
You have been added successfully to $CompanyName $TeamName Team!
|
||||||
|
Congratulations.
|
||||||
|
<a href="/profile">Go to your Profile</a>
|
||||||
|
The Open Stack Team.
|
||||||
|
</p>
|
51
ICLA/tests/ICLAManagerTest.php
Normal file
51
ICLA/tests/ICLAManagerTest.php
Normal file
@ -0,0 +1,51 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class ICLAManagerTest
|
||||||
|
*/
|
||||||
|
final class ICLAManagerTest extends SapphireTest {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @expectedException UnauthorizedRestfullAPIException
|
||||||
|
*/
|
||||||
|
public function testprocessICLAGroupUnauthorizedRestfullAPIException(){
|
||||||
|
|
||||||
|
$manager = new ICLAManager (
|
||||||
|
new GerritAPI('https://review.openstack.org', 'smarcet', ''),
|
||||||
|
new SapphireBatchTaskRepository,
|
||||||
|
new SapphireCLAMemberRepository,
|
||||||
|
new BatchTaskFactory,
|
||||||
|
SapphireTransactionManager::getInstance()
|
||||||
|
);
|
||||||
|
|
||||||
|
$manager->processICLAGroup('a49e4febb69477d0aa5737038c1802dd6cab67c5',10);
|
||||||
|
|
||||||
|
$this->setExpectedException('UnauthorizedRestfullAPIException');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function testprocessICLAGroup(){
|
||||||
|
|
||||||
|
$manager = new ICLAManager (
|
||||||
|
new GerritAPI('https://review.openstack.org', 'smarcet', 'TwxKcgZurLX6'),
|
||||||
|
new SapphireBatchTaskRepository,
|
||||||
|
new SapphireCLAMemberRepository,
|
||||||
|
new BatchTaskFactory,
|
||||||
|
SapphireTransactionManager::getInstance()
|
||||||
|
);
|
||||||
|
|
||||||
|
$manager->processICLAGroup('a49e4febb69477d0aa5737038c1802dd6cab67c5',10);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
65
README.md
Normal file
65
README.md
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
## Overview
|
||||||
|
|
||||||
|
The OpenStack Foundation Website
|
||||||
|
|
||||||
|
WHAT IS IT?
|
||||||
|
|
||||||
|
openstack.org runs a PHP web application called Silverstripe, and we've made several improvements to meet the specific needs of OpenStack. More about the Silverstripe CMS is available here: http://silverstripe.org/
|
||||||
|
|
||||||
|
This repository is designed to help other project members develop, test, and contribute to the openstack.org website project. Note that this project is only for code that powers the public openstack.org website. To participate in building the actual OpenStack software, go to:
|
||||||
|
http://wiki.openstack.org/HowToContribute
|
||||||
|
|
||||||
|
WHY RELEASE THE SOURCE?
|
||||||
|
|
||||||
|
The OpenStack.org website helps promote OpenStack, the open source cloud computing platform. We felt it only make sense to share the code that powers our website so that other open source projects might benefit, and so that developers in our community might help us improve the code that powers the website dedicated to promoting their favorite open source project.
|
||||||
|
|
||||||
|
A REMINDER ON TRADEMARKS:
|
||||||
|
|
||||||
|
In light of the trademarks held by the OpenStack Foundation, it is important that you not use the code to build a website or webpage that could be confused with the openstack.org website, including by building a site or page with the same look and feel of the openstack.org site or by using trademarks that are the same as or similar to marks found on the openstack.org site. For the rules regarding other uses of OpenStack trademarks, see the OpenStack Trademark Policy http://www.openstack.org/brand/openstack-trademark-policy/ and the OpenStack Brand Guide http://www.openstack.org/brand/. Please contact logo@openstack.org with any questions.
|
||||||
|
|
||||||
|
LICENSE:
|
||||||
|
|
||||||
|
Unless otherwise noted, all code is released under the APACHE 2.0 License
|
||||||
|
http://www.apache.org/licenses/LICENSE-2.0.html
|
||||||
|
|
||||||
|
WHO DO I CONTACT WITH QUESTIONS?
|
||||||
|
For now we will continue to use Lanchpad bugs to track issues: https://bugs.launchpad.net/openstack-org/
|
||||||
|
|
||||||
|
WHAT'S INCLUDED
|
||||||
|
Included in this repository are:
|
||||||
|
|
||||||
|
Third Party:
|
||||||
|
- The Silverstripe CMS v 3.1.x (for easy of deployment)
|
||||||
|
|
||||||
|
WHAT'S NOT INCLUDED
|
||||||
|
- Images - You'll note many missing images throughout the site. This is due to one of the following: trademark restrictions (see above), copyright restrictions, OpenStack sponsors, file size restrictions.
|
||||||
|
|
||||||
|
|
||||||
|
REQUIREMENTS FOR DEPLOYING OPENSTACK.ORG
|
||||||
|
|
||||||
|
To run the openstack.org website, the server environment needs:
|
||||||
|
- Apache 1.3 or greater
|
||||||
|
- PHP 5.2.0 or greater
|
||||||
|
- MySQL 5.0 or greater
|
||||||
|
|
||||||
|
INSTALLATION
|
||||||
|
|
||||||
|
openstack.org website uses composer (https://getcomposer.org/) to manage all dependencies
|
||||||
|
|
||||||
|
to install run following commands
|
||||||
|
|
||||||
|
* curl -sS https://getcomposer.org/installer | php
|
||||||
|
* php composer.phar install
|
||||||
|
* php composer.phar dump-autoload --optimize
|
||||||
|
* chmod 777 -R vendor/ezyang/htmlpurifier/library/HTMLPurifier/DefinitionCache/Serializer
|
||||||
|
|
||||||
|
DATABASE
|
||||||
|
OpenStack will provide a db dump on a weekly basis, purged of protected data. The dump can be found https://mycloud.rackspace.com/cloud/920805/files#object-store%2CcloudFiles%2CDFW/www.openstack.org-cron-db-backups-purged/. The database will create one default admin user. All other data will need to be populated by the user.
|
||||||
|
|
||||||
|
TODO:
|
||||||
|
We need detailed installation instructions to run the site locally on LAMP or MAMP.
|
||||||
|
|
||||||
|
SUBMITTING PATCHES:
|
||||||
|
|
||||||
|
We welcome patches and will be reviewing those as they come in initially, and plan to move to gerrit for reviews in the future.
|
||||||
|
|
18
change_password/_config.php
Normal file
18
change_password/_config.php
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
|
||||||
|
define('CHANGE_PASSWORD_EMAIL_FROM','noreply@openstack.org');
|
||||||
|
define('CHANGE_PASSWORD_EMAIL_SUBJECT','OpenStack Profile Password Recovery');
|
||||||
|
|
||||||
|
Object::useCustomClass('Member_ForgotPasswordEmail', 'CustomMember_ForgotPasswordEmail');
|
7
change_password/_config/routes.yml
Normal file
7
change_password/_config/routes.yml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
Name: changepasswordoutes
|
||||||
|
After: 'framework/routes#coreroutes'
|
||||||
|
---
|
||||||
|
Director:
|
||||||
|
rules:
|
||||||
|
'Security//$Action/$ID/$OtherID': 'CustomPasswordController'
|
@ -0,0 +1,27 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Class CustomMember_ForgotPasswordEmail
|
||||||
|
*/
|
||||||
|
final class CustomMember_ForgotPasswordEmail extends Member_ForgotPasswordEmail {
|
||||||
|
protected $from = ''; // setting a blank from address uses the site's default administrator email
|
||||||
|
protected $subject = '';
|
||||||
|
protected $ss_template = 'CustomForgotPasswordEmail';
|
||||||
|
|
||||||
|
function __construct() {
|
||||||
|
parent::__construct();
|
||||||
|
$this->subject = _t('Member.SUBJECTPASSWORDRESET', "Your password reset link", PR_MEDIUM, 'Email subject');
|
||||||
|
}
|
||||||
|
}
|
69
change_password/code/model/PasswordManager.php
Normal file
69
change_password/code/model/PasswordManager.php
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class PasswordManager
|
||||||
|
*/
|
||||||
|
final class PasswordManager {
|
||||||
|
/**
|
||||||
|
* @param int $member_id
|
||||||
|
* @param string $token
|
||||||
|
* @throws InvalidPasswordResetLinkException
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function verifyToken($member_id, $token){
|
||||||
|
if (is_null($member_id) || $member_id == 0 || empty($token)){
|
||||||
|
throw new InvalidPasswordResetLinkException;
|
||||||
|
}
|
||||||
|
//get member
|
||||||
|
$member = Member::get()->byId($member_id);
|
||||||
|
//check if token already was used...
|
||||||
|
if(!$member || !$member->validateAutoLoginToken($token)){
|
||||||
|
throw new InvalidPasswordResetLinkException;
|
||||||
|
}
|
||||||
|
$current_member = Member::currentUser();
|
||||||
|
if($current_member && $member->ID !== $current_member->ID){
|
||||||
|
throw new InvalidPasswordResetLinkException;
|
||||||
|
}
|
||||||
|
return $member->encryptWithUserSettings($token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param string $token
|
||||||
|
* @param string $password
|
||||||
|
* @param string $password_confirmation
|
||||||
|
* @throws InvalidResetPasswordTokenException
|
||||||
|
* @throws EmptyPasswordException
|
||||||
|
* @throws InvalidPasswordException
|
||||||
|
* @throws PasswordMismatchException
|
||||||
|
*/
|
||||||
|
public function changePassword($token, $password, $password_confirmation){
|
||||||
|
if(empty($token)) throw new InvalidResetPasswordTokenException;
|
||||||
|
$member = Member::member_from_autologinhash($token);
|
||||||
|
if(!$member) throw new InvalidResetPasswordTokenException;
|
||||||
|
if(empty($password)) throw new EmptyPasswordException;
|
||||||
|
if($password !== $password_confirmation) throw new PasswordMismatchException;
|
||||||
|
$isValid = $member->changePassword($password);
|
||||||
|
if(!$isValid->valid()) throw new InvalidPasswordException($isValid->starredList());
|
||||||
|
|
||||||
|
$member->logIn();
|
||||||
|
//invalidate former auto login token
|
||||||
|
$member->generateAutologinTokenAndStoreHash();
|
||||||
|
|
||||||
|
//send confirmation email
|
||||||
|
$email = EmailFactory::getInstance()->buildEmail(CHANGE_PASSWORD_EMAIL_FROM, $member->Email, CHANGE_PASSWORD_EMAIL_SUBJECT);
|
||||||
|
$email->setTemplate('ChangedPasswordEmail');
|
||||||
|
$email->populateTemplate(array('MemberName' => $member->getFullName()));
|
||||||
|
$email->send();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class EmptyPasswordException
|
||||||
|
*/
|
||||||
|
final class EmptyPasswordException extends Exception {
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class InvalidPasswordException
|
||||||
|
*/
|
||||||
|
final class InvalidPasswordException extends Exception {
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class InvalidPasswordResetLinkException
|
||||||
|
*/
|
||||||
|
final class InvalidPasswordResetLinkException extends Exception {
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class InvalidResetPasswordTokenException
|
||||||
|
*/
|
||||||
|
final class InvalidResetPasswordTokenException extends Exception {
|
||||||
|
}
|
@ -0,0 +1,18 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class PasswordMismatchException
|
||||||
|
*/
|
||||||
|
final class PasswordMismatchException extends Exception {
|
||||||
|
}
|
69
change_password/code/ui/CustomChangePasswordForm.php
Normal file
69
change_password/code/ui/CustomChangePasswordForm.php
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
|
||||||
|
final class CustomChangePasswordForm extends ChangePasswordForm {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var PasswordManager
|
||||||
|
*/
|
||||||
|
private $password_manager;
|
||||||
|
|
||||||
|
function __construct($controller, $name, $fields = null, $actions = null){
|
||||||
|
parent::__construct($controller, $name, $fields, $actions);
|
||||||
|
$this->fields->removeByName('OldPassword');
|
||||||
|
$this->password_manager = new PasswordManager;
|
||||||
|
}
|
||||||
|
/**
|
||||||
|
* Change the password
|
||||||
|
*
|
||||||
|
* @param array $data The user submitted data
|
||||||
|
*/
|
||||||
|
function doChangePassword(array $data) {
|
||||||
|
|
||||||
|
try{
|
||||||
|
$token = Session::get('AutoLoginHash');
|
||||||
|
$this->password_manager->changePassword($token,@$data['NewPassword1'],@$data['NewPassword2']);
|
||||||
|
Session::clear('AutoLoginHash');
|
||||||
|
if (isset($_REQUEST['BackURL']) && $_REQUEST['BackURL'] // absolute redirection URLs may cause spoofing
|
||||||
|
&& Director::is_site_url($_REQUEST['BackURL'])) {
|
||||||
|
Controller::curr()->redirect($_REQUEST['BackURL']);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Redirect to default location - the login form saying "You are logged in as..."
|
||||||
|
// $redirectURL = HTTP::setGetVar('BackURL', Director::absoluteBaseURL(), Security::Link('login'));
|
||||||
|
$redirectURL = '/direct-after-login/';
|
||||||
|
Controller::curr()->redirect($redirectURL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(InvalidResetPasswordTokenException $ex1){
|
||||||
|
Session::clear('AutoLoginHash');
|
||||||
|
Controller::curr()->redirect('loginpage');
|
||||||
|
}
|
||||||
|
catch(EmptyPasswordException $ex2){
|
||||||
|
$this->clearMessage();
|
||||||
|
$this->sessionMessage(_t('Member.EMPTYNEWPASSWORD', "The new password can't be empty, please try again"),"bad");
|
||||||
|
Controller::curr()->redirectBack();
|
||||||
|
}
|
||||||
|
catch(PasswordMismatchException $ex3){
|
||||||
|
$this->clearMessage();
|
||||||
|
$this->sessionMessage(_t('Member.ERRORNEWPASSWORD', "You have entered your new password differently, try again"),"bad");
|
||||||
|
Controller::curr()->redirectBack();
|
||||||
|
}
|
||||||
|
catch(InvalidPasswordException $ex4){
|
||||||
|
$this->clearMessage();
|
||||||
|
$this->sessionMessage(sprintf(_t('Member.INVALIDNEWPASSWORD', "We couldn't accept that password: %s"), nl2br("\n".$ex4->getMessage())),"bad");
|
||||||
|
Controller::curr()->redirectBack();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
82
change_password/code/ui/CustomPasswordController.php
Normal file
82
change_password/code/ui/CustomPasswordController.php
Normal file
@ -0,0 +1,82 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/***
|
||||||
|
* Class CustomPasswordController
|
||||||
|
*/
|
||||||
|
class CustomPasswordController extends Security {
|
||||||
|
|
||||||
|
private static $allowed_actions = array(
|
||||||
|
'changepassword',
|
||||||
|
'ChangePasswordForm',
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @var PasswordManager
|
||||||
|
*/
|
||||||
|
private $password_manager;
|
||||||
|
|
||||||
|
public function __construct(){
|
||||||
|
parent::__construct();
|
||||||
|
$this->password_manager = new PasswordManager;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Factory method for the lost password form
|
||||||
|
*
|
||||||
|
* @return Form Returns the lost password form
|
||||||
|
*/
|
||||||
|
public function ChangePasswordForm() {
|
||||||
|
return new CustomChangePasswordForm($this, 'ChangePasswordForm');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function changepassword() {
|
||||||
|
$tmpPage = new Page();
|
||||||
|
$tmpPage->Title = _t('Security.CHANGEPASSWORDHEADER', 'Change your password');
|
||||||
|
$tmpPage->URLSegment = 'Security';
|
||||||
|
$tmpPage->ID = -1; // Set the page ID to -1 so we dont get the top level pages as its children
|
||||||
|
$controller = new Page_Controller($tmpPage);
|
||||||
|
$controller->init();
|
||||||
|
|
||||||
|
try{
|
||||||
|
$former_hash = Session::get('AutoLoginHash');
|
||||||
|
if(!empty($former_hash)){
|
||||||
|
// Subsequent request after the "first load with hash"
|
||||||
|
$customisedController = $controller->customise(array(
|
||||||
|
'Content' =>
|
||||||
|
'<p>' .
|
||||||
|
_t('Security.ENTERNEWPASSWORD', 'Please enter a new password.') .
|
||||||
|
'</p>',
|
||||||
|
'Form' => $this->ChangePasswordForm(),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
$new_hash = $this->password_manager->verifyToken((int)@$_REQUEST['m'], @$_REQUEST['t']);
|
||||||
|
Session::set('AutoLoginHash', $new_hash);
|
||||||
|
return $this->redirect($this->Link('changepassword'));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch(InvalidPasswordResetLinkException $ex1){
|
||||||
|
$customisedController = $controller->customise(
|
||||||
|
array('Content' =>
|
||||||
|
sprintf('<p>This link is no longer valid as a newer request for a password reset has been made. Please check your mailbox for the most recent link</p><p>You can request a new one <a href="%s">here',
|
||||||
|
$this->Link('lostpassword'))
|
||||||
|
)
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return $customisedController->renderWith(array('Security_changepassword', 'Security', $this->stat('template_main'), 'ContentController'));
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,6 @@
|
|||||||
|
$MemberName,<br>
|
||||||
|
<p>
|
||||||
|
Your OpenStack.org Member Profile password was just reset. If you did not take this action, please email <a href="mailto:info@openstack.org">info@openstack.org</a> with your memberID and concerns.
|
||||||
|
</p>
|
||||||
|
Thank you,<br>
|
||||||
|
OpenStack Foundation Staff<br>
|
@ -0,0 +1,8 @@
|
|||||||
|
<div id="content-body">
|
||||||
|
<h1 id="page-title">$MenuTitle.XML</h1>
|
||||||
|
<% if CurrentMember %>
|
||||||
|
<div class="loggedInBox">You are logged in as: <strong>$CurrentMember.Name</strong> <a class="roundedButton" href="{$Link}logout/">Logout</a></p>
|
||||||
|
<% end_if %>
|
||||||
|
$Content
|
||||||
|
$Form
|
||||||
|
</div>
|
@ -0,0 +1,4 @@
|
|||||||
|
<p><% _t('HELLO', 'Hi') %> $FirstName,</p>
|
||||||
|
|
||||||
|
<p><% _t('TEXT1', 'Here is your') %> <a href="$PasswordResetLink"><% _t('TEXT2', 'password reset link') %></a> for the OpenStack website.</p>
|
||||||
|
|
23
composer.json
Normal file
23
composer.json
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
{
|
||||||
|
"name": "silverstripe/installer",
|
||||||
|
"description": "The SilverStripe Framework Installer",
|
||||||
|
"require": {
|
||||||
|
"php": ">=5.3.2",
|
||||||
|
"silverstripe/cms": "3.1.5",
|
||||||
|
"silverstripe/framework": "3.1.5",
|
||||||
|
"silverstripe/translatable": "2.0.3",
|
||||||
|
"ezyang/htmlpurifier": "dev-master",
|
||||||
|
"undefinedoffset/sortablegridfield":"dev-master",
|
||||||
|
"tractorcow/silverstripe-colorpicker":"3.0.*@dev"
|
||||||
|
},
|
||||||
|
"autoload": {
|
||||||
|
"classmap": [
|
||||||
|
"geoip/code",
|
||||||
|
"html2pdf_v4.03"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"config": {
|
||||||
|
"process-timeout": 600
|
||||||
|
},
|
||||||
|
"minimum-stability": "dev"
|
||||||
|
}
|
13
datepicker/_config.php
Normal file
13
datepicker/_config.php
Normal file
@ -0,0 +1,13 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
96
datepicker/code/JQueryUIDatePickerField.php
Normal file
96
datepicker/code/JQueryUIDatePickerField.php
Normal file
@ -0,0 +1,96 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
|
||||||
|
require_once 'Zend/Date.php';
|
||||||
|
|
||||||
|
class JQueryUIDatePickerField extends TextField {
|
||||||
|
|
||||||
|
private $data_dependant;
|
||||||
|
|
||||||
|
protected $locale = null;
|
||||||
|
|
||||||
|
protected $valueObj = null;
|
||||||
|
|
||||||
|
public function __construct($name, $title = null, $value = '', $form = null,$data_dependant=""){
|
||||||
|
$this->data_dependant = $data_dependant;
|
||||||
|
if(!$this->locale) {
|
||||||
|
$this->locale = i18n::get_locale();
|
||||||
|
}
|
||||||
|
|
||||||
|
parent::__construct($name, $title, $value, 6, $form);
|
||||||
|
}
|
||||||
|
|
||||||
|
function Field() {
|
||||||
|
$this->addExtraClass('DatePickerField');
|
||||||
|
Requirements::block(SAPPHIRE_DIR .'/thirdparty/jquery/jquery.js');
|
||||||
|
|
||||||
|
Requirements::css("themes/openstack/javascript/jquery-ui-1.10.3.custom/css/smoothness/jquery-ui-1.10.3.custom.min.css");
|
||||||
|
|
||||||
|
Requirements::javascript('themes/openstack/javascript/jquery-2.0.3.min.js');
|
||||||
|
Requirements::javascript('themes/openstack/javascript/jquery-migrate-1.2.1.min.js');
|
||||||
|
Requirements::javascript("themes/openstack/javascript/jquery-ui-1.10.3.custom/js/jquery-ui-1.10.3.custom.min.js");
|
||||||
|
Requirements::javascript("datepicker/javascript/datepicker.js");
|
||||||
|
|
||||||
|
$attributes = array(
|
||||||
|
'type' => 'text',
|
||||||
|
'class' => 'text' . ($this->extraClass() ? $this->extraClass() : ''),
|
||||||
|
'id' => $this->id(),
|
||||||
|
'name' => $this->Name(),
|
||||||
|
'value' => $this->Value(),
|
||||||
|
'tabindex' => $this->getTabIndex(),
|
||||||
|
'maxlength' => ($this->maxLength) ? $this->maxLength : null,
|
||||||
|
'size' => ($this->maxLength) ? min( $this->maxLength, 10 ) : null,
|
||||||
|
);
|
||||||
|
if(!empty($this->data_dependant)){
|
||||||
|
$attributes["data-dependant-on"] = $this->data_dependant;
|
||||||
|
}
|
||||||
|
if($this->disabled) $attributes['disabled'] = 'disabled';
|
||||||
|
return $this->createTag('input', $attributes);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the internal value to ISO date format.
|
||||||
|
*
|
||||||
|
* @param String|Array $val
|
||||||
|
*/
|
||||||
|
function setValue($val) {
|
||||||
|
if(empty($val)) {
|
||||||
|
$this->value = null;
|
||||||
|
$this->valueObj = null;
|
||||||
|
} else {
|
||||||
|
// Quick fix for overzealous Zend validation, its case sensitive on month names (see #5990)
|
||||||
|
if(is_string($val)) $val = ucwords(strtolower($val));
|
||||||
|
// load ISO date from database (usually through Form->loadDataForm())
|
||||||
|
if(!empty($val) && Zend_Date::isDate($val, 'yyyy-MM-dd')) {
|
||||||
|
$this->valueObj = new Zend_Date($val, 'yyyy-MM-dd');
|
||||||
|
$this->value = $this->valueObj->get('yyyy-MM-dd', $this->locale);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
$this->value = $val;
|
||||||
|
$this->valueObj = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return String ISO 8601 date, suitable for insertion into database
|
||||||
|
*/
|
||||||
|
function dataValue() {
|
||||||
|
if($this->valueObj) {
|
||||||
|
return $this->valueObj->toString('yyyy-MM-dd');
|
||||||
|
} else {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
54
datepicker/javascript/datepicker.js
Normal file
54
datepicker/javascript/datepicker.js
Normal file
@ -0,0 +1,54 @@
|
|||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
|
||||||
|
var DatePickerFieldHandler = function(){
|
||||||
|
var $ = jQuery;
|
||||||
|
|
||||||
|
this.initAll = function(){
|
||||||
|
var fnc = this.initById;
|
||||||
|
$('.DatePickerField').each(function(){
|
||||||
|
fnc('#' + $(this).attr('id'));
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
this.initById = function(id){
|
||||||
|
var date_picker = $(id);
|
||||||
|
date_picker.datepicker({
|
||||||
|
dateFormat: 'yy-mm-dd',
|
||||||
|
onSelect:function(text,inst){
|
||||||
|
var dependant = $(this).attr('data-dependant-on');
|
||||||
|
if(dependant){
|
||||||
|
var date_dependant = $('#'+dependant);
|
||||||
|
date_dependant.val($(this).val());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
datePickerFieldHandler = new DatePickerFieldHandler();
|
||||||
|
|
||||||
|
//check if prototype wrapper is required.
|
||||||
|
if(typeof Behaviour == 'object'){
|
||||||
|
Behaviour.register({
|
||||||
|
'.DatePickerField' : {
|
||||||
|
initialise : function(){
|
||||||
|
datePickerFieldHandler.initById('#' + this.id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
jQuery(document).ready(function(){
|
||||||
|
datePickerFieldHandler.initAll();
|
||||||
|
});
|
17
elections/_config.php
Normal file
17
elections/_config.php
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
|
||||||
|
Object::add_extension('Member', 'FoundationMember');
|
||||||
|
define('REVOCATION_NOTIFICATION_EMAIL_SUBJECT','OpenStack Foundation notice: your Foundation Membership will end in 30 days.');
|
||||||
|
define('ELECTION_VOTERS_INGEST_PATH','elections/input');
|
7
elections/_config/routes.yml
Normal file
7
elections/_config/routes.yml
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
---
|
||||||
|
Name: electionroutes
|
||||||
|
After: 'framework/routes#coreroutes'
|
||||||
|
---
|
||||||
|
Director:
|
||||||
|
rules:
|
||||||
|
'revocation-notifications' : 'RevocationNotificationAction_Controller'
|
49
elections/code/infrastructure/active_records/Election.php
Normal file
49
elections/code/infrastructure/active_records/Election.php
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class Election
|
||||||
|
*/
|
||||||
|
final class Election extends DataObject implements IElection {
|
||||||
|
|
||||||
|
static $create_table_options = array('MySQLDatabase' => 'ENGINE=InnoDB');
|
||||||
|
|
||||||
|
static $db = array(
|
||||||
|
'ElectionsOpen' => 'Date', // The day elections start
|
||||||
|
'ElectionsClose' => 'Date', // The day they close
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return DateTime
|
||||||
|
*/
|
||||||
|
public function startDate()
|
||||||
|
{
|
||||||
|
return new DateTime($this->getField('ElectionsOpen'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return DateTime
|
||||||
|
*/
|
||||||
|
public function endDate()
|
||||||
|
{
|
||||||
|
return new DateTime($this->getField('ElectionsClose'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getIdentifier()
|
||||||
|
{
|
||||||
|
return (int)$this->getField('ID');
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,108 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class FoundationMember
|
||||||
|
*/
|
||||||
|
final class FoundationMember
|
||||||
|
extends DataExtension
|
||||||
|
implements IFoundationMember, ICommunityMember {
|
||||||
|
|
||||||
|
static $has_many = array(
|
||||||
|
'RevocationNotifications' => 'FoundationMemberRevocationNotification',
|
||||||
|
'Votes' => 'Vote'
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getIdentifier()
|
||||||
|
{
|
||||||
|
return (int)$this->owner->getField('ID');
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public function convert2SiteUser(){
|
||||||
|
$this->resign();
|
||||||
|
$this->owner->addToGroupByCode(IFoundationMember::CommunityMemberGroupSlug);
|
||||||
|
}
|
||||||
|
|
||||||
|
public function isFoundationMember(){
|
||||||
|
$res = false;
|
||||||
|
$res = $this->owner->inGroup(IFoundationMember::FoundationMemberGroupSlug);
|
||||||
|
$legal_agreements = DataObject::get("LegalAgreement", " LegalDocumentPageID=422 AND MemberID =" . $this->owner->ID);
|
||||||
|
$res = $res && $legal_agreements->count() > 0;
|
||||||
|
return $res;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function upgradeToFoundationMember(){
|
||||||
|
if(!$this->isFoundationMember()){
|
||||||
|
// Assign the member to be part of the foundation group
|
||||||
|
$this->owner->addToGroupByCode(IFoundationMember::FoundationMemberGroupSlug);
|
||||||
|
// Set up member with legal agreement for becoming an OpenStack Foundation Member
|
||||||
|
$legalAgreement = new LegalAgreement();
|
||||||
|
$legalAgreement->MemberID = $this->owner->ID;
|
||||||
|
$legalAgreement->LegalDocumentPageID = 422;
|
||||||
|
$legalAgreement->write();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param int $latest_election_id
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function hasPendingRevocationNotifications($latest_election_id)
|
||||||
|
{
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public function resign(){
|
||||||
|
// Remove member from Foundation group
|
||||||
|
foreach($this->owner->Groups() as $g){
|
||||||
|
$this->owner->Groups()->remove($g->ID);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove member mamaged companies
|
||||||
|
foreach($this->owner->ManagedCompanies() as $c){
|
||||||
|
$this->owner->ManagedCompanies()->remove($c->ID);
|
||||||
|
}
|
||||||
|
// Remove Member's Legal Agreements
|
||||||
|
$legal_agreements = $this->owner->LegalAgreements();
|
||||||
|
if($legal_agreements)
|
||||||
|
foreach($legal_agreements as $document) {
|
||||||
|
$document->delete();
|
||||||
|
}
|
||||||
|
|
||||||
|
// Remove Member's Affiliations
|
||||||
|
$affiliations = $this->owner->Affiliations();
|
||||||
|
if($legal_agreements)
|
||||||
|
foreach($affiliations as $affiliation) {
|
||||||
|
$affiliation->delete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isCommunityMember() {
|
||||||
|
$group = $this->owner->inGroup(IFoundationMember::CommunityMemberGroupSlug);
|
||||||
|
$is_speaker = DataObject::get_one('Speaker', 'MemberID = '. $this->owner->ID);
|
||||||
|
$is_foundation_member = $this->isFoundationMember();
|
||||||
|
return $group || $is_speaker || $is_foundation_member;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,187 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class FoundationMemberRevocationNotification
|
||||||
|
*/
|
||||||
|
final class FoundationMemberRevocationNotification
|
||||||
|
extends DataObject
|
||||||
|
implements IFoundationMemberRevocationNotification {
|
||||||
|
|
||||||
|
static $create_table_options = array('MySQLDatabase' => 'ENGINE=InnoDB');
|
||||||
|
|
||||||
|
static $db = array(
|
||||||
|
'Action' => "Enum('None, Renew, Revoked, Resign','None')",
|
||||||
|
'ActionDate' => 'SS_Datetime',
|
||||||
|
'SentDate' => 'SS_Datetime',
|
||||||
|
'Hash' => 'Text',
|
||||||
|
);
|
||||||
|
|
||||||
|
static $has_one = array(
|
||||||
|
'LastElection' => 'Election',
|
||||||
|
'Recipient' => 'Member',
|
||||||
|
);
|
||||||
|
|
||||||
|
protected function onBeforeWrite() {
|
||||||
|
parent::onBeforeWrite();
|
||||||
|
$this->setField('SentDate',gmdate('Y-m-d H:i:s'));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getIdentifier()
|
||||||
|
{
|
||||||
|
return (int)$this->getField('ID');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function action()
|
||||||
|
{
|
||||||
|
return (string)$this->getField('Action');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return DateTime
|
||||||
|
*/
|
||||||
|
public function actionDate()
|
||||||
|
{
|
||||||
|
if($this->isExpired() && $this->action()=='None')
|
||||||
|
return $this->expirationDate();
|
||||||
|
|
||||||
|
$date = $this->getField('ActionDate');
|
||||||
|
return new DateTime($date);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return DateTime
|
||||||
|
*/
|
||||||
|
public function sentDate()
|
||||||
|
{
|
||||||
|
$date = $this->getField('SentDate');
|
||||||
|
return new DateTime($date);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isExpired()
|
||||||
|
{
|
||||||
|
$date = new DateTime('now',new DateTimeZone("UTC"));
|
||||||
|
$date = $date->sub(new DateInterval('P'.IFoundationMemberRevocationNotification::DaysBeforeRevocation.'D'));
|
||||||
|
$sent_date = $this->sentDate();
|
||||||
|
return $sent_date <= $date;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @param IElection $latest_election
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function renew(IElection $latest_election)
|
||||||
|
{
|
||||||
|
AssociationFactory::getInstance()->getMany2OneAssociation($this,'LastElection')->setTarget($latest_election);
|
||||||
|
$this->setField('Action','Renew');
|
||||||
|
$this->setField('ActionDate',gmdate('Y-m-d H:i:s'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return void
|
||||||
|
*/
|
||||||
|
public function revoke()
|
||||||
|
{
|
||||||
|
$member = $this->recipient();
|
||||||
|
$member->convert2SiteUser();
|
||||||
|
$this->setField('Action','Revoked');
|
||||||
|
$this->setField('ActionDate',gmdate('Y-m-d H:i:s'));
|
||||||
|
}
|
||||||
|
|
||||||
|
public function resign(){
|
||||||
|
$member = $this->recipient();
|
||||||
|
$member->resign();
|
||||||
|
$this->setField('Action','Resign');
|
||||||
|
$this->setField('ActionDate',gmdate('Y-m-d H:i:s'));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return IFoundationMember
|
||||||
|
*/
|
||||||
|
public function recipient()
|
||||||
|
{
|
||||||
|
return AssociationFactory::getInstance()->getMany2OneAssociation($this,'Recipient')->getTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function hash()
|
||||||
|
{
|
||||||
|
return (string)$this->getField('Hash');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function generateHash()
|
||||||
|
{
|
||||||
|
$generator = new RandomGenerator();
|
||||||
|
$token = $generator->randomToken();
|
||||||
|
$hash = self::HashConfirmationToken($token);
|
||||||
|
$this->setField('Hash',$hash);
|
||||||
|
return $token;
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function HashConfirmationToken($token){
|
||||||
|
return md5($token);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return IElection
|
||||||
|
*/
|
||||||
|
public function latestElection()
|
||||||
|
{
|
||||||
|
return AssociationFactory::getInstance()->getMany2OneAssociation($this,'LastElection')->getTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function remainingDays() {
|
||||||
|
$send_date = $this->sentDate();
|
||||||
|
$void_date = $send_date->add(new DateInterval('P'.IFoundationMemberRevocationNotification::DaysBeforeRevocation.'D'));
|
||||||
|
$diff = (int)$void_date->diff($send_date)->format("%a");
|
||||||
|
return IFoundationMemberRevocationNotification::DaysBeforeRevocation - $diff;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return DateTime
|
||||||
|
*/
|
||||||
|
public function expirationDate()
|
||||||
|
{
|
||||||
|
$sent_date = $this->sentDate();
|
||||||
|
$void_date = $sent_date->add(new DateInterval('P'.IFoundationMemberRevocationNotification::DaysBeforeRevocation.'D'));
|
||||||
|
return $void_date;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return bool
|
||||||
|
*/
|
||||||
|
public function isValid()
|
||||||
|
{
|
||||||
|
if($this->isExpired()) return false;
|
||||||
|
$action = $this->getField('Action');
|
||||||
|
return $action == 'None';
|
||||||
|
}
|
||||||
|
}
|
67
elections/code/infrastructure/active_records/Vote.php
Normal file
67
elections/code/infrastructure/active_records/Vote.php
Normal file
@ -0,0 +1,67 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class Vote
|
||||||
|
*/
|
||||||
|
final class Vote
|
||||||
|
extends DataObject
|
||||||
|
implements IVote {
|
||||||
|
|
||||||
|
static $create_table_options = array('MySQLDatabase' => 'ENGINE=InnoDB');
|
||||||
|
|
||||||
|
static $db = array(
|
||||||
|
|
||||||
|
);
|
||||||
|
|
||||||
|
static $has_one = array(
|
||||||
|
'Voter' => 'Member',
|
||||||
|
'Election' => 'Election',
|
||||||
|
);
|
||||||
|
|
||||||
|
static $indexes = array(
|
||||||
|
'Voter_Election' => array('type'=>'unique', 'value'=>'VoterID,ElectionID'),
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getIdentifier()
|
||||||
|
{
|
||||||
|
return (int)$this->getField('ID');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return IFoundationMember
|
||||||
|
*/
|
||||||
|
public function voter()
|
||||||
|
{
|
||||||
|
return AssociationFactory::getInstance()->getMany2OneAssociation($this,'Voter')->getTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return IElection
|
||||||
|
*/
|
||||||
|
public function election()
|
||||||
|
{
|
||||||
|
return AssociationFactory::getInstance()->getMany2OneAssociation($this,'Election')->getTarget();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return DateTime
|
||||||
|
*/
|
||||||
|
public function date()
|
||||||
|
{
|
||||||
|
// TODO: Implement date() method.
|
||||||
|
}
|
||||||
|
}
|
44
elections/code/infrastructure/active_records/VoterFile.php
Normal file
44
elections/code/infrastructure/active_records/VoterFile.php
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* Copyright 2014 Openstack.org
|
||||||
|
* Licensed 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.
|
||||||
|
**/
|
||||||
|
/**
|
||||||
|
* Class VoterFile
|
||||||
|
*/
|
||||||
|
final class VoterFile extends DataObject implements IVoterFile {
|
||||||
|
|
||||||
|
static $create_table_options = array('MySQLDatabase' => 'ENGINE=InnoDB');
|
||||||
|
|
||||||
|
static $db = array(
|
||||||
|
'FileName' => 'Varchar(255)',
|
||||||
|
);
|
||||||
|
|
||||||
|
static $indexes = array(
|
||||||
|
'FileName' => array('type'=>'unique', 'value'=>'FileName'),
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return int
|
||||||
|
*/
|
||||||
|
public function getIdentifier()
|
||||||
|
{
|
||||||
|
return (int)$this->getField('ID');
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @return string
|
||||||
|
*/
|
||||||
|
public function name()
|
||||||
|
{
|
||||||
|
return (string)$this->getField('FileName');
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user