Updated get member endpoint

* added filter by github_user
* updated mappings to return ccla_teams relation

Change-Id: Ied32b72380d347aaa599005773485b6d1ba4adc7
This commit is contained in:
Sebastian Marcet 2017-11-22 17:17:38 -03:00
parent 19d968b85a
commit e480843874
10 changed files with 270 additions and 12 deletions

View File

@ -88,6 +88,7 @@ final class OAuth2MembersApiController extends OAuth2ProtectedController
'group_id' => ['=='],
'email_verified' => ['=='],
'active' => ['=='],
'github_user' => ['=@', '=='],
));
}

View File

@ -1,4 +1,6 @@
<?php namespace utils;
use models\exceptions\ValidationException;
/**
* Copyright 2015 OpenStack Foundation
* Licensed under the Apache License, Version 2.0 (the "License");
@ -49,8 +51,13 @@ final class FilterParser
$field = $operands[0];
$value = $operands[1];
if (!isset($allowed_fields[$field])) continue;
if (!in_array($op, $allowed_fields[$field])) continue;
if (!isset($allowed_fields[$field])){
throw new FilterParserException(sprintf("filter by field %s is not allowed", $field));
}
if (!in_array($op, $allowed_fields[$field])){
throw new FilterParserException(sprintf("%s op is not allowed for filter by field %s",$op, $field));
}
$f_or = self::buildFilter($field, $op, $value);
if (!is_null($f_or))
$f[] = $f_or;
@ -67,8 +74,13 @@ final class FilterParser
$field = $operands[0];
$value = $operands[1];
if (!isset($allowed_fields[$field])) continue;
if (!in_array($op, $allowed_fields[$field])) continue;
if (!isset($allowed_fields[$field])){
throw new FilterParserException(sprintf("filter by field %s is not allowed", $field));
}
if (!in_array($op, $allowed_fields[$field])){
throw new FilterParserException(sprintf("%s op is not allowed for filter by field %s",$op, $field));
}
$f = self::buildFilter($field, $op, $value);
}

View File

@ -26,6 +26,7 @@ class AbstractMemberSerializer extends SilverStripeSerializer
'FirstName' => 'first_name:json_string',
'LastName' => 'last_name:json_string',
'Gender' => 'gender:json_string',
'GitHubUser' => 'github_user:json_string',
'Bio' => 'bio:json_string',
'LinkedInProfile' => 'linked_in:json_string',
'IrcHandle' => 'irc:json_string',
@ -39,6 +40,7 @@ class AbstractMemberSerializer extends SilverStripeSerializer
protected static $allowed_relations = [
'groups',
'affiliations',
'ccla_teams',
];
/**
@ -61,6 +63,9 @@ class AbstractMemberSerializer extends SilverStripeSerializer
if(in_array('groups', $relations))
$values['groups'] = $member->getGroupsIds();
if(in_array('ccla_teams', $relations))
$values['ccla_teams'] = $member->getCCLATeamsIds();
if(in_array('affiliations', $relations)){
$res = [];
foreach ($member->getCurrentAffiliations() as $affiliation){
@ -95,6 +100,16 @@ class AbstractMemberSerializer extends SilverStripeSerializer
$values['groups'] = $groups;
}
break;
case 'ccla_teams': {
if(!in_array('ccla_teams', $relations)) break;
$teams = [];
unset($values['ccla_teams']);
foreach ($member->getCCLATeams() as $t) {
$teams[] = SerializerRegistry::getInstance()->getSerializer($t)->serialize('company', [], ['none']);
}
$values['ccla_teams'] = $teams;
}
break;
}
}
}

View File

@ -0,0 +1,81 @@
<?php namespace App\ModelSerializers\CCLA;
/**
* Copyright 2017 OpenStack Foundation
* 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.
**/
use Models\Foundation\Main\CCLA\Team;
use ModelSerializers\SerializerRegistry;
use ModelSerializers\SilverStripeSerializer;
/**
* Class TeamSerializer
* @package App\ModelSerializers\CCLA
*/
final class TeamSerializer extends SilverStripeSerializer
{
protected static $array_mappings = array
(
'Name' => 'name:json_string',
'CompanyId' => 'company_id:json_int',
);
/**
* @param null $expand
* @param array $fields
* @param array $relations
* @param array $params
* @return array
*/
public function serialize($expand = null, array $fields = array(), array $relations = array(), array $params = array() )
{
$team = $this->object;
if(!$team instanceof Team) return [];
$values = parent::serialize($expand, $fields, $relations, $params);
$members = [];
foreach($team->getMembers() as $member){
$members[] = $member->getId();
}
$values['members'] = $members;
if (!empty($expand)) {
$expand_to = explode(',', $expand);
foreach ($expand_to as $relation) {
switch (trim($relation)) {
case 'company':{
if(isset($values['company_id']))
{
unset($values['company_id']);
$values['company'] = SerializerRegistry::getInstance()->getSerializer($team->getCompany())->serialize($expand);
}
}
break;
case 'members':{
unset( $values['members']);
$members = [];
foreach($team->getMembers() as $member){
$members[] = SerializerRegistry::getInstance()->getSerializer($member)->serialize($expand);
}
$values['members'] = $members;
}
break;
}
}
}
return $values;
}
}

View File

@ -1,4 +1,5 @@
<?php namespace ModelSerializers;
use App\ModelSerializers\CCLA\TeamSerializer;
use App\ModelSerializers\Marketplace\CloudServiceOfferedSerializer;
use App\ModelSerializers\Marketplace\ConfigurationManagementTypeSerializer;
use App\ModelSerializers\Marketplace\ConsultantClientSerializer;
@ -157,6 +158,10 @@ final class SerializerRegistry
$this->registry['OpenStackComponent'] = OpenStackComponentSerializer::class;
$this->registry['OpenStackRelease'] = OpenStackReleaseSerializer::class;
// ccla
$this->registry['Team'] = TeamSerializer::class;
}
/**

View File

@ -0,0 +1,77 @@
<?php namespace Models\Foundation\Main\CCLA;
/**
* Copyright 2017 OpenStack Foundation
* 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.
**/
use Doctrine\Common\Collections\ArrayCollection;
use models\main\Company;
use models\main\Member;
use models\utils\SilverstripeBaseModel;
use Doctrine\ORM\Mapping AS ORM;
/**
* Class Team
* @ORM\Entity
* @ORM\Table(name="Team")
* @package Models\Foundation\Main\CCLA
*/
class Team extends SilverstripeBaseModel
{
/**
* @ORM\Column(name="Name", type="string")
*/
private $name;
public function __construct(){
parent::__construct();
$this->members = new ArrayCollection();
}
/**
* @ORM\ManyToMany(targetEntity="models\main\Member", mappedBy="ccla_teams")
*/
private $members;
/**
* @ORM\ManyToOne(targetEntity="models\main\Company")
* @ORM\JoinColumn(name="CompanyID", referencedColumnName="ID")
* @var Company
*/
private $company;
/**
* @return Company
*/
public function getCompany(){
return $this->company;
}
/**
* @return Member[]
*/
public function getMembers(){
return $this->members->toArray();
}
/**
* @return string
*/
public function getName(){
return $this->name;
}
/**
* @return int
*/
public function getCompanyId(){
return $this->company->getId();
}
}

View File

@ -13,11 +13,11 @@
* limitations under the License.
**/
use Models\Foundation\Main\CCLA\Team;
use Doctrine\Common\Collections\ArrayCollection;
use Doctrine\Common\Collections\Criteria;
use Doctrine\ORM\NonUniqueResultException;
use Doctrine\ORM\NoResultException;
use Doctrine\ORM\Query\ResultSetMappingBuilder;
use models\exceptions\ValidationException;
use models\summit\CalendarSync\CalendarSyncInfo;
use models\summit\CalendarSync\ScheduleCalendarSyncInfo;
@ -56,6 +56,12 @@ class Member extends SilverstripeBaseModel
*/
private $last_name;
/**
* @ORM\Column(name="GitHubUser", type="string")
* @var string
*/
private $github_user;
/**
* @ORM\OneToMany(targetEntity="models\summit\SummitEventFeedback", mappedBy="owner", cascade={"persist"})
* @var SummitEventFeedback[]
@ -180,6 +186,16 @@ class Member extends SilverstripeBaseModel
*/
private $groups;
/**
* @ORM\ManyToMany(targetEntity="Models\Foundation\Main\CCLA\Team", inversedBy="members")
* @ORM\JoinTable(name="Team_Members",
* joinColumns={@ORM\JoinColumn(name="MemberID", referencedColumnName="ID")},
* inverseJoinColumns={@ORM\JoinColumn(name="TeamID", referencedColumnName="ID")}
* )
* @var Team[]
*/
private $ccla_teams;
/**
* @ORM\OneToMany(targetEntity="ChatTeamMember", mappedBy="member", cascade={"persist"}, orphanRemoval=true)
* @var ChatTeamMember[]
@ -200,6 +216,7 @@ class Member extends SilverstripeBaseModel
parent::__construct();
$this->feedback = new ArrayCollection();
$this->groups = new ArrayCollection();
$this->ccla_teams = new ArrayCollection();
$this->affiliations = new ArrayCollection();
$this->team_memberships = new ArrayCollection();
$this->favorites = new ArrayCollection();
@ -405,6 +422,13 @@ class Member extends SilverstripeBaseModel
$this->email = $email;
}
/**
* @return string
*/
public function getGitHubUser(){
return $this->github_user;
}
/**
* @return bool
*/
@ -578,6 +602,21 @@ class Member extends SilverstripeBaseModel
return $ids;
}
public function getCCLATeamsIds(){
$ids = [];
foreach ($this->getCCLATeams() as $t) {
$ids[] = intval($t->getId());
}
return $ids;
}
/**
* @return Team[]
*/
public function getCCLATeams(){
return $this->ccla_teams->toArray();
}
/**
* @return string[]
*/
@ -924,4 +963,5 @@ SQL;
$this->calendars_sync->removeElement($calendar_sync_info);
$calendar_sync_info->clearOwner();
}
}

View File

@ -56,18 +56,19 @@ final class DoctrineMemberRepository
if(!is_null($filter)){
$filter->apply2Query($query, [
'irc' => 'm.irc_handle:json_string',
'twitter' => 'm.twitter_handle:json_string',
'first_name' => 'm.first_name:json_string',
'last_name' => 'm.last_name:json_string',
'email' => ['m.email:json_string', 'm.second_email:json_string', 'm.third_email:json_string'],
'group_slug' => new DoctrineJoinFilterMapping
'irc' => 'm.irc_handle:json_string',
'twitter' => 'm.twitter_handle:json_string',
'first_name' => 'm.first_name:json_string',
'last_name' => 'm.last_name:json_string',
'github_user' => 'm.github_user:json_string',
'email' => ['m.email:json_string', 'm.second_email:json_string', 'm.third_email:json_string'],
'group_slug' => new DoctrineJoinFilterMapping
(
'm.groups',
'g',
"g.code :operator ':value'"
),
'group_id' => new DoctrineJoinFilterMapping
'group_id' => new DoctrineJoinFilterMapping
(
'm.groups',
'g',

View File

@ -111,4 +111,29 @@ final class OAuth2MembersApiTest extends ProtectedApiTest
$this->assertTrue(!is_null($member));
$this->assertResponseStatus(200);
}
public function testGetMembersByGitHubUser()
{
$params = [
'filter' => 'github_user=@smarcet',
'order' => '+first_name,-last_name',
'expand' => 'groups, ccla_teams'
];
$headers = array("HTTP_Authorization" => " Bearer " . $this->access_token);
$response = $this->action(
"GET",
"OAuth2MembersApiController@getMembers",
$params,
array(),
array(),
array(),
$headers
);
$content = $response->getContent();
$members = json_decode($content);
$this->assertTrue(!is_null($members));
$this->assertResponseStatus(200);
}
}

View File

@ -1,4 +1,5 @@
#!/usr/bin/env bash
php composer.phar dump-autoload --optimize;
php artisan doctrine:generate:proxies
php artisan doctrine:clear:metadata:cache
php artisan doctrine:clear:query:cache