2
0
mirror of https://github.com/VinylDNS/vinyldns synced 2025-08-30 13:58:15 +00:00

Open list groups access (#809)

This commit is contained in:
Britney Wright
2019-08-21 14:26:51 -04:00
committed by GitHub
parent e7820e6005
commit d0d88dc0ea
24 changed files with 232 additions and 101 deletions

View File

@@ -9,6 +9,7 @@ from vinyldns_context import VinylDNSTestContext
class ListGroupsSearchContext(object):
def __init__(self):
self.client = VinylDNSClient(VinylDNSTestContext.vinyldns_url, access_key='listGroupAccessKey', secret_key='listGroupSecretKey')
self.support_user_client = VinylDNSClient(VinylDNSTestContext.vinyldns_url, 'supportUserAccessKey', 'supportUserSecretKey')
self.tear_down() # ensures that the environment is clean before starting
try:
@@ -29,6 +30,15 @@ class ListGroupsSearchContext(object):
pass
raise
def verify_ignore_access(self, results):
assert_that(results, has_length(3)) # 3 fields
assert_that(len(results['groups']), greater_than(50))
assert_that(results, is_not(has_key('groupNameFilter')))
assert_that(results, is_not(has_key('startFrom')))
assert_that(results, is_not(has_key('nextId')))
assert_that(results['maxItems'], is_(100))
def tear_down(self):
clear_zones(self.client)
clear_groups(self.client)
@@ -51,7 +61,7 @@ def test_list_my_groups_no_parameters(list_my_groups_context):
results = list_my_groups_context.client.list_my_groups(status=200)
assert_that(results, has_length(2)) # 2 fields
assert_that(results, has_length(3)) # 3 fields
assert_that(results['groups'], has_length(50))
assert_that(results, is_not(has_key('groupNameFilter')))
@@ -70,7 +80,7 @@ def test_get_my_groups_using_old_account_auth(list_my_groups_context):
Test passing in an account will return an empty set
"""
results = list_my_groups_context.client.list_my_groups(status=200)
assert_that(results, has_length(2))
assert_that(results, has_length(3))
assert_that(results, is_not(has_key('groupNameFilter')))
assert_that(results, is_not(has_key('startFrom')))
assert_that(results, is_not(has_key('nextId')))
@@ -83,7 +93,7 @@ def test_list_my_groups_max_items(list_my_groups_context):
"""
results = list_my_groups_context.client.list_my_groups(max_items=5, status=200)
assert_that(results, has_length(3)) # 3 fields
assert_that(results, has_length(4)) # 4 fields
assert_that(results, has_key('groups'))
assert_that(results, is_not(has_key('groupNameFilter')))
@@ -98,7 +108,7 @@ def test_list_my_groups_paging(list_my_groups_context):
"""
results=list_my_groups_context.client.list_my_groups(max_items=20, status=200)
assert_that(results, has_length(3)) # 3 fields
assert_that(results, has_length(4)) # 4 fields
assert_that(results, has_key('groups'))
assert_that(results, is_not(has_key('groupNameFilter')))
assert_that(results, is_not(has_key('startFrom')))
@@ -110,7 +120,7 @@ def test_list_my_groups_paging(list_my_groups_context):
results = list_my_groups_context.client.list_my_groups(max_items=20, start_from=results['nextId'], status=200)
if 'nextId' in results:
assert_that(results, has_length(4)) # 4 fields
assert_that(results, has_length(5)) # 5 fields
assert_that(results, has_key('groups'))
assert_that(results, is_not(has_key('groupNameFilter')))
assert_that(results['startFrom'], is_(prev['nextId']))
@@ -118,7 +128,7 @@ def test_list_my_groups_paging(list_my_groups_context):
assert_that(results['maxItems'], is_(20))
else:
assert_that(results, has_length(3)) # 3 fields
assert_that(results, has_length(4)) # 4 fields
assert_that(results, has_key('groups'))
assert_that(results, is_not(has_key('groupNameFilter')))
assert_that(results['startFrom'], is_(prev['nextId']))
@@ -132,7 +142,7 @@ def test_list_my_groups_filter_matches(list_my_groups_context):
"""
results = list_my_groups_context.client.list_my_groups(group_name_filter="test-list-my-groups-01", status=200)
assert_that(results, has_length(3)) # 3 fields
assert_that(results, has_length(4)) # 4 fields
assert_that(results['groups'], has_length(10))
assert_that(results['groupNameFilter'], is_('test-list-my-groups-01'))
@@ -163,3 +173,35 @@ def test_list_my_groups_no_deleted(list_my_groups_context):
for g in results['groups']:
assert_that(g['status'], is_not('Deleted'))
def test_list_my_groups_with_ignore_access_true(list_my_groups_context):
"""
Test that we can get all the groups whether a user is a member or not
"""
results = list_my_groups_context.client.list_my_groups(ignore_access=True, status=200)
list_my_groups_context.verify_ignore_access(results)
my_results = list_my_groups_context.client.list_my_groups(status=200)
my_results['groups'] = sorted(my_results['groups'], key=lambda x: x['name'])
for i in range(0, 50):
assert_that(my_results['groups'][i]['name'], is_("test-list-my-groups-{0:0>3}".format(i)))
def test_list_my_groups_as_support_user(list_my_groups_context):
"""
Test that we can get all the groups as a support user, even without ignore_access
"""
results = list_my_groups_context.support_user_client.list_my_groups(status=200)
list_my_groups_context.verify_ignore_access(results)
def test_list_my_groups_as_support_user_with_ignore_access_true(list_my_groups_context):
"""
Test that we can get all the groups as a support user
"""
results = list_my_groups_context.support_user_client.list_my_groups(ignore_access=True, status=200)
list_my_groups_context.verify_ignore_access(results)

View File

@@ -226,12 +226,13 @@ class VinylDNSClient(object):
return data
def list_my_groups(self, group_name_filter=None, start_from=None, max_items=None, **kwargs):
def list_my_groups(self, group_name_filter=None, start_from=None, max_items=None, ignore_access=False, **kwargs):
"""
Retrieves my groups
:param start_from: the start key of the page
:param max_items: the page limit
:param group_name_filter: only returns groups whose names contain filter string
:param ignore_access: determines if groups should be retrieved based on requester's membership
:return: the content of the response
"""
@@ -242,6 +243,8 @@ class VinylDNSClient(object):
args.append(u'startFrom={0}'.format(start_from))
if max_items is not None:
args.append(u'maxItems={0}'.format(max_items))
if ignore_access is not False:
args.append(u'ignoreAccess={0}'.format(ignore_access))
url = urljoin(self.index_url, u'/groups') + u'?' + u'&'.join(args)
response, data = self.make_request(url, u'GET', self.headers, **kwargs)

View File

@@ -140,7 +140,8 @@ final case class ListMyGroupsResponse(
groupNameFilter: Option[String] = None,
startFrom: Option[String] = None,
nextId: Option[String] = None,
maxItems: Int)
maxItems: Int,
ignoreAccess: Boolean)
final case class GroupNotFoundError(msg: String) extends Throwable(msg)

View File

@@ -135,16 +135,17 @@ class MembershipService(
groupNameFilter: Option[String],
startFrom: Option[String],
maxItems: Int,
authPrincipal: AuthPrincipal): Result[ListMyGroupsResponse] = {
authPrincipal: AuthPrincipal,
ignoreAccess: Boolean): Result[ListMyGroupsResponse] = {
val groupsCall =
if (authPrincipal.isSystemAdmin) {
if (authPrincipal.isSystemAdmin || ignoreAccess) {
groupRepo.getAllGroups()
} else {
groupRepo.getGroups(authPrincipal.memberGroupIds.toSet)
}
groupsCall.map { grp =>
pageListGroupsResponse(grp.toList, groupNameFilter, startFrom, maxItems)
pageListGroupsResponse(grp.toList, groupNameFilter, startFrom, maxItems, ignoreAccess)
}
}.toResult
@@ -152,7 +153,8 @@ class MembershipService(
allGroups: Seq[Group],
groupNameFilter: Option[String],
startFrom: Option[String],
maxItems: Int): ListMyGroupsResponse = {
maxItems: Int,
ignoreAccess: Boolean): ListMyGroupsResponse = {
val allMyGroups = allGroups
.filter(_.status == GroupStatus.Active)
.sortBy(_.id)
@@ -165,7 +167,7 @@ class MembershipService(
val nextId = if (filtered.length > maxItems) Some(filtered(maxItems - 1).id) else None
val groups = filtered.take(maxItems)
ListMyGroupsResponse(groups, groupNameFilter, startFrom, nextId, maxItems)
ListMyGroupsResponse(groups, groupNameFilter, startFrom, nextId, maxItems, ignoreAccess)
}
def getGroupActivity(

View File

@@ -42,7 +42,8 @@ trait MembershipServiceAlgebra {
groupNameFilter: Option[String],
startFrom: Option[String],
maxItems: Int,
authPrincipal: AuthPrincipal): Result[ListMyGroupsResponse]
authPrincipal: AuthPrincipal,
ignoreAccess: Boolean): Result[ListMyGroupsResponse]
def listMembers(
groupId: String,

View File

@@ -69,8 +69,16 @@ class MembershipRoute(
}
} ~
(get & monitor("Endpoint.listMyGroups")) {
parameters("startFrom".?, "maxItems".as[Int].?(DEFAULT_MAX_ITEMS), "groupNameFilter".?) {
(startFrom: Option[String], maxItems: Int, groupNameFilter: Option[String]) =>
parameters(
"startFrom".?,
"maxItems".as[Int].?(DEFAULT_MAX_ITEMS),
"groupNameFilter".?,
"ignoreAccess".as[Boolean].?(false)) {
(
startFrom: Option[String],
maxItems: Int,
groupNameFilter: Option[String],
ignoreAccess: Boolean) =>
{
handleRejections(invalidQueryHandler) {
validate(
@@ -81,8 +89,9 @@ class MembershipRoute(
""".stripMargin
) {
authenticateAndExecute(membershipService
.listMyGroups(groupNameFilter, startFrom, maxItems, _)) { groups =>
complete(StatusCodes.OK, groups)
.listMyGroups(groupNameFilter, startFrom, maxItems, _, ignoreAccess)) {
groups =>
complete(StatusCodes.OK, groups)
}
}
}

View File

@@ -529,14 +529,15 @@ class MembershipServiceSpec
.when(mockGroupRepo)
.getGroups(any[Set[String]])
val result: ListMyGroupsResponse =
rightResultOf(underTest.listMyGroups(None, None, 100, listOfDummyGroupsAuth).value)
rightResultOf(underTest.listMyGroups(None, None, 100, listOfDummyGroupsAuth, false).value)
verify(mockGroupRepo, never()).getAllGroups()
result shouldBe ListMyGroupsResponse(
groups = listOfDummyGroupInfo.take(100),
None,
None,
nextId = Some(listOfDummyGroups(99).id),
maxItems = 100)
maxItems = 100,
ignoreAccess = false)
}
"return only return groups whose name matches the filter" in {
doReturn(IO.pure(listOfDummyGroups.toSet))
@@ -548,14 +549,16 @@ class MembershipServiceSpec
groupNameFilter = Some("name-dummy01"),
startFrom = None,
maxItems = 100,
listOfDummyGroupsAuth)
listOfDummyGroupsAuth,
false)
.value)
result shouldBe ListMyGroupsResponse(
groups = listOfDummyGroupInfo.slice(10, 20),
groupNameFilter = Some("name-dummy01"),
startFrom = None,
nextId = None,
maxItems = 100)
maxItems = 100,
ignoreAccess = false)
}
"return only return groups after startFrom" in {
doReturn(IO.pure(listOfDummyGroups.toSet))
@@ -567,14 +570,16 @@ class MembershipServiceSpec
groupNameFilter = None,
startFrom = Some(listOfDummyGroups(99).id),
maxItems = 100,
listOfDummyGroupsAuth)
listOfDummyGroupsAuth,
ignoreAccess = false)
.value)
result shouldBe ListMyGroupsResponse(
groups = listOfDummyGroupInfo.slice(100, 200),
groupNameFilter = None,
startFrom = Some(listOfDummyGroups(99).id),
nextId = None,
maxItems = 100)
maxItems = 100,
ignoreAccess = false)
}
"return only return maxItems groups" in {
doReturn(IO.pure(listOfDummyGroups.toSet))
@@ -586,35 +591,65 @@ class MembershipServiceSpec
groupNameFilter = None,
startFrom = None,
maxItems = 10,
listOfDummyGroupsAuth)
listOfDummyGroupsAuth,
ignoreAccess = false)
.value)
result shouldBe ListMyGroupsResponse(
groups = listOfDummyGroupInfo.slice(0, 10),
groupNameFilter = None,
startFrom = None,
nextId = Some(listOfDummyGroups(9).id),
maxItems = 10)
maxItems = 10,
ignoreAccess = false)
}
"return an empty set if the user is not a member of any groups" in {
doReturn(IO.pure(Set())).when(mockGroupRepo).getGroups(any[Set[String]])
val result: ListMyGroupsResponse =
rightResultOf(underTest.listMyGroups(None, None, 100, notAuth).value)
result shouldBe ListMyGroupsResponse(Seq(), None, None, None, 100)
rightResultOf(underTest.listMyGroups(None, None, 100, notAuth, false).value)
result shouldBe ListMyGroupsResponse(Seq(), None, None, None, 100, false)
}
"return groups from the database for super users" in {
"return all groups from the database if ignoreAccess is true" in {
doReturn(IO.pure(Set(okGroup, dummyGroup))).when(mockGroupRepo).getAllGroups()
val result: ListMyGroupsResponse =
rightResultOf(underTest.listMyGroups(None, None, 100, superUserAuth).value)
rightResultOf(underTest.listMyGroups(None, None, 100, notAuth, true).value)
verify(mockGroupRepo).getAllGroups()
result.groups should contain theSameElementsAs Seq(
GroupInfo(dummyGroup),
GroupInfo(okGroup))
}
"return groups from the database for support users" in {
"return all groups from the database for super users even if ignoreAccess is false" in {
doReturn(IO.pure(Set(okGroup, dummyGroup))).when(mockGroupRepo).getAllGroups()
val result: ListMyGroupsResponse =
rightResultOf(underTest.listMyGroups(None, None, 100, superUserAuth, false).value)
verify(mockGroupRepo).getAllGroups()
result.groups should contain theSameElementsAs Seq(
GroupInfo(dummyGroup),
GroupInfo(okGroup))
}
"return all groups from the database for super users if ignoreAccess is true" in {
doReturn(IO.pure(Set(okGroup, dummyGroup))).when(mockGroupRepo).getAllGroups()
val result: ListMyGroupsResponse =
rightResultOf(underTest.listMyGroups(None, None, 100, superUserAuth, true).value)
verify(mockGroupRepo).getAllGroups()
result.groups should contain theSameElementsAs Seq(
GroupInfo(dummyGroup),
GroupInfo(okGroup))
}
"return all groups from the database for support users even if ignoreAccess is false" in {
val supportAuth = AuthPrincipal(okUser.copy(isSupport = true), Seq())
doReturn(IO.pure(Set(okGroup, dummyGroup))).when(mockGroupRepo).getAllGroups()
val result: ListMyGroupsResponse =
rightResultOf(underTest.listMyGroups(None, None, 100, supportAuth).value)
rightResultOf(underTest.listMyGroups(None, None, 100, supportAuth, false).value)
verify(mockGroupRepo).getAllGroups()
result.groups should contain theSameElementsAs Seq(
GroupInfo(dummyGroup),
GroupInfo(okGroup))
}
"return all groups from the database for support users if ignoreAccess is true" in {
val supportAuth = AuthPrincipal(okUser.copy(isSupport = true), Seq())
doReturn(IO.pure(Set(okGroup, dummyGroup))).when(mockGroupRepo).getAllGroups()
val result: ListMyGroupsResponse =
rightResultOf(underTest.listMyGroups(None, None, 100, supportAuth, true).value)
verify(mockGroupRepo).getAllGroups()
result.groups should contain theSameElementsAs Seq(
GroupInfo(dummyGroup),
@@ -626,8 +661,8 @@ class MembershipServiceSpec
.when(mockGroupRepo)
.getGroups(any[Set[String]])
val result: ListMyGroupsResponse =
rightResultOf(underTest.listMyGroups(None, None, 100, deletedGroupAuth).value)
result shouldBe ListMyGroupsResponse(Seq(), None, None, None, 100)
rightResultOf(underTest.listMyGroups(None, None, 100, deletedGroupAuth, false).value)
result shouldBe ListMyGroupsResponse(Seq(), None, None, None, 100, false)
}
}

View File

@@ -188,15 +188,16 @@ class MembershipRoutingSpec
"return a 200 response with the groups when no optional parameters are used" in {
val twoUserGroupInfo = GroupInfo(twoUserGroup)
doReturn(
result(ListMyGroupsResponse(Seq(okGroupInfo, twoUserGroupInfo), None, None, None, 100)))
result(
ListMyGroupsResponse(Seq(okGroupInfo, twoUserGroupInfo), None, None, None, 100, false)))
.when(membershipService)
.listMyGroups(None, None, 100, okAuth)
.listMyGroups(None, None, 100, okAuth, false)
Get("/groups") ~> Route.seal(membershipRoute) ~> check {
status shouldBe StatusCodes.OK
val result = responseAs[ListMyGroupsResponse]
val expected =
ListMyGroupsResponse(Seq(okGroupInfo, twoUserGroupInfo), None, None, None, 100)
ListMyGroupsResponse(Seq(okGroupInfo, twoUserGroupInfo), None, None, None, 100, false)
result shouldBe expected
}
@@ -209,13 +210,15 @@ class MembershipRoutingSpec
groupNameFilter = Some("ok"),
startFrom = Some("anyString"),
nextId = None,
maxItems = 100)))
maxItems = 100,
ignoreAccess = false)))
.when(membershipService)
.listMyGroups(
groupNameFilter = Some("ok"),
startFrom = Some("anyString"),
maxItems = 100,
okAuth)
okAuth,
ignoreAccess = false)
Get("/groups?startFrom=anyString&maxItems=100&groupNameFilter=ok") ~> Route.seal(
membershipRoute) ~> check {
status shouldBe StatusCodes.OK
@@ -226,7 +229,8 @@ class MembershipRoutingSpec
groupNameFilter = Some("ok"),
startFrom = Some("anyString"),
maxItems = 100,
nextId = None)
nextId = None,
ignoreAccess = false)
result shouldBe expected
}
@@ -244,7 +248,7 @@ class MembershipRoutingSpec
"return a 500 response when fails" in {
doReturn(result(new IllegalArgumentException("fail")))
.when(membershipService)
.listMyGroups(None, None, 100, okAuth)
.listMyGroups(None, None, 100, okAuth, false)
Get("/groups") ~> Route.seal(membershipRoute) ~> check {
status shouldBe StatusCodes.InternalServerError

View File

@@ -67,6 +67,7 @@ object VinylDNS {
lastName: Option[String],
email: Option[String],
isSuper: Boolean,
isSupport: Boolean,
id: String,
lockStatus: LockStatus)
object UserInfo {
@@ -77,6 +78,7 @@ object VinylDNS {
lastName = user.lastName,
email = user.email,
isSuper = user.isSuper,
isSupport = user.isSupport,
id = user.id,
lockStatus = user.lockStatus
)
@@ -218,7 +220,7 @@ class VinylDNS @Inject()(
})
}
def getMyGroups(): Action[AnyContent] = userAction.async { implicit request =>
def getGroups(): Action[AnyContent] = userAction.async { implicit request =>
val queryParameters = new HashMap[String, java.util.List[String]]()
for {
(name, values) <- request.queryString

View File

@@ -22,7 +22,17 @@
<notification ng-model="alert"></notification>
</div>
</div>
<div class="row">
<!-- START VERTICAL TABS -->
<div class="panel panel-default panel-tabs">
<ul class="nav nav-tabs bar_tabs">
<li class="active"><a data-toggle="tab" ng-click="myGroups()">My Groups</a></li>
<li><a data-toggle="tab" ng-click="allGroups()">All Groups</a></li>
</ul>
<div class="panel-body tab-content">
<div class="tab-pane active" id="groups">
<div class="row">
<div class="col-md-12">
<!-- SIMPLE DATATABLE -->
@@ -63,7 +73,7 @@
<td class="wrap-long-text">{{group.description}}</td>
<td>
<div class="table-form-group">
<a class="btn btn-info btn-rounded" ng-href="/groups/{{group.id}}">
<a ng-if="canSeeGroup(group)" class="btn btn-info btn-rounded" ng-href="/groups/{{group.id}}">
View</a>
<a ng-if="groupAdmin(group)" class="btn btn-warning btn-rounded" ng-click="editGroup(group);">
Edit</a>
@@ -80,6 +90,11 @@
</div>
</div>
</div>
</div>
</div>
<!-- END VERTICAL TABS -->
</div>
<!-- END PAGE CONTENT WRAPPER -->

View File

@@ -42,7 +42,7 @@ PUT /api/zones/:zid/recordsets/:rid @controllers.VinylDNS.updateRec
GET /api/zones/:id/recordsetchanges @controllers.VinylDNS.listRecordSetChanges(id: String)
GET /api/groups @controllers.VinylDNS.getMyGroups
GET /api/groups @controllers.VinylDNS.getGroups
GET /api/groups/:gid @controllers.VinylDNS.getGroup(gid: String)
POST /api/groups @controllers.VinylDNS.newGroup
PUT /api/groups/:gid @controllers.VinylDNS.updateGroup(gid: String)

View File

@@ -19,7 +19,7 @@
angular.module('batch-change')
.controller('BatchChangeNewController', function($scope, $log, $location, $timeout, $q, batchChangeService, utilityService, groupsService){
groupsService.getMyGroups()
groupsService.getGroups()
.then(function (results) {
$scope.myGroups = results['data']['groups'];
if ($scope.myGroups.length == 1) {
@@ -27,7 +27,7 @@
}
})
.catch(function (error) {
handleError(error, 'groupsService::getMyGroups-failure');
handleError(error, 'groupsService::getGroups-failure');
});
$scope.batch = {};

View File

@@ -153,7 +153,7 @@ describe('BatchChange', function(){
deferred = $q.defer();
spyOn(batchChangeService, 'createBatchChange').and.returnValue(deferred.promise);
groupsService.getMyGroups = function() {
groupsService.getGroups = function() {
return $q.when({
data: {
groups: "all my groups"

View File

@@ -23,6 +23,7 @@ angular.module('controller.groups', []).controller('GroupsController', function
$scope.groups = { items: [] };
$scope.groupsLoaded = false;
$scope.alerts = [];
$scope.ignoreAccess = false;
function handleError(error, type) {
var alert = utilityService.failure(error, type);
@@ -101,19 +102,28 @@ angular.module('controller.groups', []).controller('GroupsController', function
});
};
$scope.allGroups = function() {
$scope.ignoreAccess = true;
$scope.refresh();
}
$scope.myGroups = function() {
$scope.ignoreAccess = false;
$scope.refresh();
}
$scope.refresh = function () {
//get users groups
function success(result) {
$log.log('getMyGroups:refresh-success', result);
$log.log('getGroups:refresh-success', result);
//update groups
$scope.groups.items = result.groups;
$scope.groupsLoaded = true;
return result;
}
return getMyGroups()
getGroups($scope.ignoreAccess)
.then(success)
.catch(function (error) {
handleError(error, 'getMyGroups::refresh-failure');
handleError(error, 'getGroups::refresh-failure');
});
};
@@ -131,16 +141,16 @@ angular.module('controller.groups', []).controller('GroupsController', function
return true;
};
function getMyGroups() {
function getGroups() {
function success(response) {
$log.log('groupsService::getMyGroups-success');
$log.log('groupsService::getGroups-success');
return response.data;
}
return groupsService
.getMyGroups()
.getGroups($scope.ignoreAccess)
.then(success)
.catch(function (error){
handleError(error, 'groupsService::getMyGroups-failure');
handleError(error, 'groupsService::getGroups-failure');
});
}
@@ -233,7 +243,14 @@ angular.module('controller.groups', []).controller('GroupsController', function
return x.id === $scope.profile.id;
});
var isSuper = $scope.profile.isSuper;
return (isAdmin || isSuper) ? true : false;
return isAdmin || isSuper;
}
$scope.canSeeGroup = function(group) {
var isMember = group.members.some(x => x.id === $scope.profile.id);
var isSupport = $scope.profile.isSupport;
var isSuper = $scope.profile.isSuper;
return isMember || isSupport || isSuper;
}
//get user data on groups view load

View File

@@ -31,7 +31,7 @@ describe('Controller: GroupsController', function () {
profileService.getAuthenticatedUserData = function() {
return $q.when('data')
};
this.groupsService.getMyGroups = function() {
this.groupsService.getGroups = function() {
return $q.when({
data: {
group: 'mock group'
@@ -57,14 +57,14 @@ describe('Controller: GroupsController', function () {
groups: "all my groups"
}
};
var getMyGroups = spyOn(this.groupsService, 'getMyGroups')
var getGroups = spyOn(this.groupsService, 'getGroups')
.and.stub()
.and.returnValue(this.q.when(response));
this.scope.refresh();
this.scope.$digest();
expect(getMyGroups.calls.count()).toBe(1);
expect(getGroups.calls.count()).toBe(1);
expect(this.scope.groups.items).toBe("all my groups");
});

View File

@@ -18,7 +18,7 @@ angular.module('controller.manageZones', [])
.controller('ManageZonesController', function ($scope, $timeout, $log, recordsService, zonesService, groupsService,
profileService, utilityService) {
groupsService.getMyGroupsStored()
groupsService.getGroupsStored()
.then(function (results) {
$scope.myGroups = results.groups;
})

View File

@@ -33,7 +33,7 @@ describe('Controller: ManageZonesController', function () {
this.recordsService = recordsService;
this.profileService = profileService;
this.q = $q;
this.groupsService.getMyGroups = function () {
this.groupsService.getGroups = function () {
return $q.when({
data: {
groups: "all my groups"

View File

@@ -350,7 +350,7 @@ angular.module('controller.records', [])
function getMembership(){
groupsService
.getMyGroupsStored()
.getGroupsStored()
.then(
function (results) {
$scope.myGroups = results.groups;
@@ -358,7 +358,7 @@ angular.module('controller.records', [])
determineAdmin()
})
.catch(function (error){
handleError(error, 'groupsService::getMyGroupsStored-failure');
handleError(error, 'groupsService::getGroupsStored-failure');
});
}

View File

@@ -126,7 +126,7 @@ describe('Controller: RecordsController', function () {
spyOn(this.recordsService, 'getZone')
.and.stub()
.and.returnValue(this.q.when({ data: {zone: mockZone}}));
spyOn(this.groupsService, 'getMyGroups')
spyOn(this.groupsService, 'getGroups')
.and.stub()
.and.returnValue(this.q.when(mockGroups));
this.$httpBackend.when('GET', '/api/users/currentuser').respond({});
@@ -166,7 +166,7 @@ describe('Controller: RecordsController', function () {
spyOn(this.recordsService, 'getZone')
.and.stub()
.and.returnValue(this.q.when({ data: {zone: mockZone}}));
spyOn(this.groupsService, 'getMyGroups')
spyOn(this.groupsService, 'getGroups')
.and.stub()
.and.returnValue(this.q.when(mockGroups));
this.$httpBackend.when('GET', '/api/users/currentuser').respond({});
@@ -206,7 +206,7 @@ describe('Controller: RecordsController', function () {
spyOn(this.recordsService, 'getZone')
.and.stub()
.and.returnValue(this.q.when({ data: {zone: mockZone}}));
spyOn(this.groupsService, 'getMyGroups')
spyOn(this.groupsService, 'getGroups')
.and.stub()
.and.returnValue(this.q.when(mockGroups));
this.$httpBackend.when('GET', '/api/users/currentuser').respond({});
@@ -246,7 +246,7 @@ describe('Controller: RecordsController', function () {
spyOn(this.recordsService, 'getZone')
.and.stub()
.and.returnValue(this.q.when({ data: {zone: mockZone}}));
spyOn(this.groupsService, 'getMyGroups')
spyOn(this.groupsService, 'getGroups')
.and.stub()
.and.returnValue(this.q.when(mockGroups));
this.$httpBackend.when('GET', '/api/users/currentuser').respond({});

View File

@@ -50,7 +50,7 @@ angular.module('controller.zones', [])
$scope.currentZone.transferConnection = {};
};
groupsService.getMyGroups().then(function (results) {
groupsService.getGroups().then(function (results) {
if (results.data) {
$scope.myGroups = results.data.groups;
$scope.myGroupIds = results.data.groups.map(function(grp) {return grp['id']});

View File

@@ -38,7 +38,7 @@ describe('Controller: ZonesController', function () {
profileService.getAuthenticatedUserData = function() {
return $q.when({data: {}});
};
groupsService.getMyGroups = function() {
groupsService.getGroups = function() {
return $q.when({
data: {
groups: [{id: "all my groups"}]

View File

@@ -70,9 +70,9 @@ angular.module('service.groups', [])
return $http.delete(url, {headers: utilityService.getCsrfHeader()});
};
this.getMyGroups = function () {
this.getGroups = function (ignoreAccess) {
var url = '/api/groups';
url = this.urlBuilder(url, { maxItems: 1000});
url = this.urlBuilder(url, { maxItems: 1000, ignoreAccess: ignoreAccess});
return $http.get(url);
};
@@ -82,9 +82,9 @@ angular.module('service.groups', [])
return $http.get(url);
};
this.getMyGroupsStored = function () {
this.getGroupsStored = function () {
if (_refreshMyGroups || _myGroupsPromise == undefined) {
_myGroupsPromise = this.getMyGroups().then(
_myGroupsPromise = this.getGroups().then(
function(response) {
_refreshMyGroups = false;
return response.data;

View File

@@ -432,26 +432,26 @@ describe('Service: groupsService', function () {
this.$httpBackend.flush();
});
it('getMyGroups method should return 200 with valid groups', function (done) {
it('getGroups method should return 200 with valid groups', function (done) {
var url = '/api/groups';
this.$httpBackend.whenRoute('GET', url).respond(200, getJSONFixture('mockGroupList.json'));
this.groupsService.getMyGroups()
this.groupsService.getGroups()
.then(function (response) {
expect(response.status).toBe(200);
done();
}, function (error) {
fail('getMyGroups expected 200, but got ' + response.status.toString());
fail('getGroups expected 200, but got ' + response.status.toString());
done();
});
this.$httpBackend.flush();
});
it('getMyGroups method should return 401 with invalid credentials', function (done) {
it('getGroups method should return 401 with invalid credentials', function (done) {
var url = '/api/groups';
this.$httpBackend.whenRoute('GET', url).respond(401, "The resource requires authentication, which was not supplied with the request");
this.groupsService.getMyGroups()
this.groupsService.getGroups()
.then(function (response) {
fail("getMyGroups expected 401, but got " + response.status.toString());
fail("getGroups expected 401, but got " + response.status.toString());
done();
}, function (error) {
expect(error.status).toBe(401);
@@ -460,14 +460,14 @@ describe('Service: groupsService', function () {
this.$httpBackend.flush();
});
it('getMyGroupsStored should only call the api on its 1st call', function (done) {
it('getGroupsStored should only call the api on its 1st call', function (done) {
var url = '/api/groups';
var groupsResult = getJSONFixture('mockGroupList.json');
this.$httpBackend.whenRoute('GET', url).respond(200, groupsResult);
var getMyGroupsCalls = spyOn(this.groupsService, 'getMyGroups').and.callThrough();
var getMyGroupsStoredCalls = spyOn(this.groupsService, 'getMyGroupsStored').and.callThrough();
var getGroupsCalls = spyOn(this.groupsService, 'getGroups').and.callThrough();
var getGroupsStoredCalls = spyOn(this.groupsService, 'getGroupsStored').and.callThrough();
this.groupsService.getMyGroupsStored().then(function (response) {
this.groupsService.getGroupsStored().then(function (response) {
expect(response).toEqual(groupsResult);
}, function (error) {
fail('getGroup expected 202 with json, but got' + error.status.toString());
@@ -475,42 +475,42 @@ describe('Service: groupsService', function () {
this.$httpBackend.flush();
this.groupsService.getMyGroupsStored().then(function (response) {
this.groupsService.getGroupsStored().then(function (response) {
expect(response).toEqual(groupsResult);
}, function (error) {
fail('getGroup expected 202 with json, but got' + error.status.toString());
});
expect(getMyGroupsStoredCalls.calls.count()).toBe(2);
expect(getMyGroupsCalls.calls.count()).toBe(1);
expect(getGroupsStoredCalls.calls.count()).toBe(2);
expect(getGroupsCalls.calls.count()).toBe(1);
done();
});
it('getMyGroupsStored should call the api twice when there is an error', function (done) {
it('getGroupsStored should call the api twice when there is an error', function (done) {
var url = '/api/groups';
this.$httpBackend.whenRoute('GET', url).respond(401, "The resource requires authentication, which was not supplied with the request");
var getMyGroupsCalls = spyOn(this.groupsService, 'getMyGroups').and.callThrough();
var getMyGroupsStoredCalls = spyOn(this.groupsService, 'getMyGroupsStored').and.callThrough();
var getGroupsCalls = spyOn(this.groupsService, 'getGroups').and.callThrough();
var getGroupsStoredCalls = spyOn(this.groupsService, 'getGroupsStored').and.callThrough();
this.groupsService.getMyGroupsStored().then(function (response) {
fail("getMyGroups expected 401, but got " + response.status.toString());
this.groupsService.getGroupsStored().then(function (response) {
fail("getGroups expected 401, but got " + response.status.toString());
}, function (error) {
expect(error.status).toBe(401);
});
this.$httpBackend.flush();
this.groupsService.getMyGroupsStored().then(function (response) {
fail("getMyGroups expected 401, but got " + response.status.toString());
this.groupsService.getGroupsStored().then(function (response) {
fail("getGroups expected 401, but got " + response.status.toString());
}, function (error) {
expect(error.status).toBe(401);
});
this.$httpBackend.flush();
expect(getMyGroupsStoredCalls.calls.count()).toBe(2);
expect(getMyGroupsCalls.calls.count()).toBe(2);
expect(getGroupsStoredCalls.calls.count()).toBe(2);
expect(getGroupsCalls.calls.count()).toBe(2);
done();
});

View File

@@ -1418,7 +1418,7 @@ class VinylDNSSpec extends Specification with Mockito with TestApplicationData w
client,
components,
crypto)
val result = underTest.getMyGroups()(FakeRequest(GET, s"/api/groups")
val result = underTest.getGroups()(FakeRequest(GET, s"/api/groups")
.withSession("username" -> frodoUser.userName, "accessKey" -> frodoUser.accessKey))
status(result) must beEqualTo(OK)
@@ -1443,7 +1443,7 @@ class VinylDNSSpec extends Specification with Mockito with TestApplicationData w
client,
components,
crypto)
val result = underTest.getMyGroups()(FakeRequest(GET, s"/api/groups"))
val result = underTest.getGroups()(FakeRequest(GET, s"/api/groups"))
status(result) mustEqual 401
contentAsString(result) must beEqualTo(
@@ -1468,7 +1468,7 @@ class VinylDNSSpec extends Specification with Mockito with TestApplicationData w
client,
components,
crypto)
val result = underTest.getMyGroups()(
val result = underTest.getGroups()(
FakeRequest(GET, s"/api/groups")
.withSession(
"username" -> lockedFrodoUser.userName,
@@ -1500,7 +1500,7 @@ class VinylDNSSpec extends Specification with Mockito with TestApplicationData w
client,
components,
crypto)
val result = underTest.getMyGroups()(FakeRequest(GET, s"/api/groups")
val result = underTest.getGroups()(FakeRequest(GET, s"/api/groups")
.withSession("username" -> frodoUser.userName, "accessKey" -> frodoUser.accessKey))
status(result) must beEqualTo(UNAUTHORIZED)