mirror of
https://github.com/VinylDNS/vinyldns
synced 2025-08-30 22:05:21 +00:00
Open list groups access (#809)
This commit is contained in:
@@ -9,6 +9,7 @@ from vinyldns_context import VinylDNSTestContext
|
|||||||
class ListGroupsSearchContext(object):
|
class ListGroupsSearchContext(object):
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.client = VinylDNSClient(VinylDNSTestContext.vinyldns_url, access_key='listGroupAccessKey', secret_key='listGroupSecretKey')
|
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
|
self.tear_down() # ensures that the environment is clean before starting
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@@ -29,6 +30,15 @@ class ListGroupsSearchContext(object):
|
|||||||
pass
|
pass
|
||||||
raise
|
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):
|
def tear_down(self):
|
||||||
clear_zones(self.client)
|
clear_zones(self.client)
|
||||||
clear_groups(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)
|
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['groups'], has_length(50))
|
||||||
assert_that(results, is_not(has_key('groupNameFilter')))
|
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
|
Test passing in an account will return an empty set
|
||||||
"""
|
"""
|
||||||
results = list_my_groups_context.client.list_my_groups(status=200)
|
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('groupNameFilter')))
|
||||||
assert_that(results, is_not(has_key('startFrom')))
|
assert_that(results, is_not(has_key('startFrom')))
|
||||||
assert_that(results, is_not(has_key('nextId')))
|
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)
|
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, has_key('groups'))
|
||||||
assert_that(results, is_not(has_key('groupNameFilter')))
|
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)
|
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, has_key('groups'))
|
||||||
assert_that(results, is_not(has_key('groupNameFilter')))
|
assert_that(results, is_not(has_key('groupNameFilter')))
|
||||||
assert_that(results, is_not(has_key('startFrom')))
|
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)
|
results = list_my_groups_context.client.list_my_groups(max_items=20, start_from=results['nextId'], status=200)
|
||||||
|
|
||||||
if 'nextId' in results:
|
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, has_key('groups'))
|
||||||
assert_that(results, is_not(has_key('groupNameFilter')))
|
assert_that(results, is_not(has_key('groupNameFilter')))
|
||||||
assert_that(results['startFrom'], is_(prev['nextId']))
|
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))
|
assert_that(results['maxItems'], is_(20))
|
||||||
|
|
||||||
else:
|
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, has_key('groups'))
|
||||||
assert_that(results, is_not(has_key('groupNameFilter')))
|
assert_that(results, is_not(has_key('groupNameFilter')))
|
||||||
assert_that(results['startFrom'], is_(prev['nextId']))
|
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)
|
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['groups'], has_length(10))
|
||||||
assert_that(results['groupNameFilter'], is_('test-list-my-groups-01'))
|
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']:
|
for g in results['groups']:
|
||||||
assert_that(g['status'], is_not('Deleted'))
|
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)
|
||||||
|
@@ -226,12 +226,13 @@ class VinylDNSClient(object):
|
|||||||
|
|
||||||
return data
|
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
|
Retrieves my groups
|
||||||
:param start_from: the start key of the page
|
:param start_from: the start key of the page
|
||||||
:param max_items: the page limit
|
:param max_items: the page limit
|
||||||
:param group_name_filter: only returns groups whose names contain filter string
|
: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
|
:return: the content of the response
|
||||||
"""
|
"""
|
||||||
|
|
||||||
@@ -242,6 +243,8 @@ class VinylDNSClient(object):
|
|||||||
args.append(u'startFrom={0}'.format(start_from))
|
args.append(u'startFrom={0}'.format(start_from))
|
||||||
if max_items is not None:
|
if max_items is not None:
|
||||||
args.append(u'maxItems={0}'.format(max_items))
|
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)
|
url = urljoin(self.index_url, u'/groups') + u'?' + u'&'.join(args)
|
||||||
response, data = self.make_request(url, u'GET', self.headers, **kwargs)
|
response, data = self.make_request(url, u'GET', self.headers, **kwargs)
|
||||||
|
@@ -140,7 +140,8 @@ final case class ListMyGroupsResponse(
|
|||||||
groupNameFilter: Option[String] = None,
|
groupNameFilter: Option[String] = None,
|
||||||
startFrom: Option[String] = None,
|
startFrom: Option[String] = None,
|
||||||
nextId: Option[String] = None,
|
nextId: Option[String] = None,
|
||||||
maxItems: Int)
|
maxItems: Int,
|
||||||
|
ignoreAccess: Boolean)
|
||||||
|
|
||||||
final case class GroupNotFoundError(msg: String) extends Throwable(msg)
|
final case class GroupNotFoundError(msg: String) extends Throwable(msg)
|
||||||
|
|
||||||
|
@@ -135,16 +135,17 @@ class MembershipService(
|
|||||||
groupNameFilter: Option[String],
|
groupNameFilter: Option[String],
|
||||||
startFrom: Option[String],
|
startFrom: Option[String],
|
||||||
maxItems: Int,
|
maxItems: Int,
|
||||||
authPrincipal: AuthPrincipal): Result[ListMyGroupsResponse] = {
|
authPrincipal: AuthPrincipal,
|
||||||
|
ignoreAccess: Boolean): Result[ListMyGroupsResponse] = {
|
||||||
val groupsCall =
|
val groupsCall =
|
||||||
if (authPrincipal.isSystemAdmin) {
|
if (authPrincipal.isSystemAdmin || ignoreAccess) {
|
||||||
groupRepo.getAllGroups()
|
groupRepo.getAllGroups()
|
||||||
} else {
|
} else {
|
||||||
groupRepo.getGroups(authPrincipal.memberGroupIds.toSet)
|
groupRepo.getGroups(authPrincipal.memberGroupIds.toSet)
|
||||||
}
|
}
|
||||||
|
|
||||||
groupsCall.map { grp =>
|
groupsCall.map { grp =>
|
||||||
pageListGroupsResponse(grp.toList, groupNameFilter, startFrom, maxItems)
|
pageListGroupsResponse(grp.toList, groupNameFilter, startFrom, maxItems, ignoreAccess)
|
||||||
}
|
}
|
||||||
}.toResult
|
}.toResult
|
||||||
|
|
||||||
@@ -152,7 +153,8 @@ class MembershipService(
|
|||||||
allGroups: Seq[Group],
|
allGroups: Seq[Group],
|
||||||
groupNameFilter: Option[String],
|
groupNameFilter: Option[String],
|
||||||
startFrom: Option[String],
|
startFrom: Option[String],
|
||||||
maxItems: Int): ListMyGroupsResponse = {
|
maxItems: Int,
|
||||||
|
ignoreAccess: Boolean): ListMyGroupsResponse = {
|
||||||
val allMyGroups = allGroups
|
val allMyGroups = allGroups
|
||||||
.filter(_.status == GroupStatus.Active)
|
.filter(_.status == GroupStatus.Active)
|
||||||
.sortBy(_.id)
|
.sortBy(_.id)
|
||||||
@@ -165,7 +167,7 @@ class MembershipService(
|
|||||||
val nextId = if (filtered.length > maxItems) Some(filtered(maxItems - 1).id) else None
|
val nextId = if (filtered.length > maxItems) Some(filtered(maxItems - 1).id) else None
|
||||||
val groups = filtered.take(maxItems)
|
val groups = filtered.take(maxItems)
|
||||||
|
|
||||||
ListMyGroupsResponse(groups, groupNameFilter, startFrom, nextId, maxItems)
|
ListMyGroupsResponse(groups, groupNameFilter, startFrom, nextId, maxItems, ignoreAccess)
|
||||||
}
|
}
|
||||||
|
|
||||||
def getGroupActivity(
|
def getGroupActivity(
|
||||||
|
@@ -42,7 +42,8 @@ trait MembershipServiceAlgebra {
|
|||||||
groupNameFilter: Option[String],
|
groupNameFilter: Option[String],
|
||||||
startFrom: Option[String],
|
startFrom: Option[String],
|
||||||
maxItems: Int,
|
maxItems: Int,
|
||||||
authPrincipal: AuthPrincipal): Result[ListMyGroupsResponse]
|
authPrincipal: AuthPrincipal,
|
||||||
|
ignoreAccess: Boolean): Result[ListMyGroupsResponse]
|
||||||
|
|
||||||
def listMembers(
|
def listMembers(
|
||||||
groupId: String,
|
groupId: String,
|
||||||
|
@@ -69,8 +69,16 @@ class MembershipRoute(
|
|||||||
}
|
}
|
||||||
} ~
|
} ~
|
||||||
(get & monitor("Endpoint.listMyGroups")) {
|
(get & monitor("Endpoint.listMyGroups")) {
|
||||||
parameters("startFrom".?, "maxItems".as[Int].?(DEFAULT_MAX_ITEMS), "groupNameFilter".?) {
|
parameters(
|
||||||
(startFrom: Option[String], maxItems: Int, groupNameFilter: Option[String]) =>
|
"startFrom".?,
|
||||||
|
"maxItems".as[Int].?(DEFAULT_MAX_ITEMS),
|
||||||
|
"groupNameFilter".?,
|
||||||
|
"ignoreAccess".as[Boolean].?(false)) {
|
||||||
|
(
|
||||||
|
startFrom: Option[String],
|
||||||
|
maxItems: Int,
|
||||||
|
groupNameFilter: Option[String],
|
||||||
|
ignoreAccess: Boolean) =>
|
||||||
{
|
{
|
||||||
handleRejections(invalidQueryHandler) {
|
handleRejections(invalidQueryHandler) {
|
||||||
validate(
|
validate(
|
||||||
@@ -81,8 +89,9 @@ class MembershipRoute(
|
|||||||
""".stripMargin
|
""".stripMargin
|
||||||
) {
|
) {
|
||||||
authenticateAndExecute(membershipService
|
authenticateAndExecute(membershipService
|
||||||
.listMyGroups(groupNameFilter, startFrom, maxItems, _)) { groups =>
|
.listMyGroups(groupNameFilter, startFrom, maxItems, _, ignoreAccess)) {
|
||||||
complete(StatusCodes.OK, groups)
|
groups =>
|
||||||
|
complete(StatusCodes.OK, groups)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -529,14 +529,15 @@ class MembershipServiceSpec
|
|||||||
.when(mockGroupRepo)
|
.when(mockGroupRepo)
|
||||||
.getGroups(any[Set[String]])
|
.getGroups(any[Set[String]])
|
||||||
val result: ListMyGroupsResponse =
|
val result: ListMyGroupsResponse =
|
||||||
rightResultOf(underTest.listMyGroups(None, None, 100, listOfDummyGroupsAuth).value)
|
rightResultOf(underTest.listMyGroups(None, None, 100, listOfDummyGroupsAuth, false).value)
|
||||||
verify(mockGroupRepo, never()).getAllGroups()
|
verify(mockGroupRepo, never()).getAllGroups()
|
||||||
result shouldBe ListMyGroupsResponse(
|
result shouldBe ListMyGroupsResponse(
|
||||||
groups = listOfDummyGroupInfo.take(100),
|
groups = listOfDummyGroupInfo.take(100),
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
nextId = Some(listOfDummyGroups(99).id),
|
nextId = Some(listOfDummyGroups(99).id),
|
||||||
maxItems = 100)
|
maxItems = 100,
|
||||||
|
ignoreAccess = false)
|
||||||
}
|
}
|
||||||
"return only return groups whose name matches the filter" in {
|
"return only return groups whose name matches the filter" in {
|
||||||
doReturn(IO.pure(listOfDummyGroups.toSet))
|
doReturn(IO.pure(listOfDummyGroups.toSet))
|
||||||
@@ -548,14 +549,16 @@ class MembershipServiceSpec
|
|||||||
groupNameFilter = Some("name-dummy01"),
|
groupNameFilter = Some("name-dummy01"),
|
||||||
startFrom = None,
|
startFrom = None,
|
||||||
maxItems = 100,
|
maxItems = 100,
|
||||||
listOfDummyGroupsAuth)
|
listOfDummyGroupsAuth,
|
||||||
|
false)
|
||||||
.value)
|
.value)
|
||||||
result shouldBe ListMyGroupsResponse(
|
result shouldBe ListMyGroupsResponse(
|
||||||
groups = listOfDummyGroupInfo.slice(10, 20),
|
groups = listOfDummyGroupInfo.slice(10, 20),
|
||||||
groupNameFilter = Some("name-dummy01"),
|
groupNameFilter = Some("name-dummy01"),
|
||||||
startFrom = None,
|
startFrom = None,
|
||||||
nextId = None,
|
nextId = None,
|
||||||
maxItems = 100)
|
maxItems = 100,
|
||||||
|
ignoreAccess = false)
|
||||||
}
|
}
|
||||||
"return only return groups after startFrom" in {
|
"return only return groups after startFrom" in {
|
||||||
doReturn(IO.pure(listOfDummyGroups.toSet))
|
doReturn(IO.pure(listOfDummyGroups.toSet))
|
||||||
@@ -567,14 +570,16 @@ class MembershipServiceSpec
|
|||||||
groupNameFilter = None,
|
groupNameFilter = None,
|
||||||
startFrom = Some(listOfDummyGroups(99).id),
|
startFrom = Some(listOfDummyGroups(99).id),
|
||||||
maxItems = 100,
|
maxItems = 100,
|
||||||
listOfDummyGroupsAuth)
|
listOfDummyGroupsAuth,
|
||||||
|
ignoreAccess = false)
|
||||||
.value)
|
.value)
|
||||||
result shouldBe ListMyGroupsResponse(
|
result shouldBe ListMyGroupsResponse(
|
||||||
groups = listOfDummyGroupInfo.slice(100, 200),
|
groups = listOfDummyGroupInfo.slice(100, 200),
|
||||||
groupNameFilter = None,
|
groupNameFilter = None,
|
||||||
startFrom = Some(listOfDummyGroups(99).id),
|
startFrom = Some(listOfDummyGroups(99).id),
|
||||||
nextId = None,
|
nextId = None,
|
||||||
maxItems = 100)
|
maxItems = 100,
|
||||||
|
ignoreAccess = false)
|
||||||
}
|
}
|
||||||
"return only return maxItems groups" in {
|
"return only return maxItems groups" in {
|
||||||
doReturn(IO.pure(listOfDummyGroups.toSet))
|
doReturn(IO.pure(listOfDummyGroups.toSet))
|
||||||
@@ -586,35 +591,65 @@ class MembershipServiceSpec
|
|||||||
groupNameFilter = None,
|
groupNameFilter = None,
|
||||||
startFrom = None,
|
startFrom = None,
|
||||||
maxItems = 10,
|
maxItems = 10,
|
||||||
listOfDummyGroupsAuth)
|
listOfDummyGroupsAuth,
|
||||||
|
ignoreAccess = false)
|
||||||
.value)
|
.value)
|
||||||
result shouldBe ListMyGroupsResponse(
|
result shouldBe ListMyGroupsResponse(
|
||||||
groups = listOfDummyGroupInfo.slice(0, 10),
|
groups = listOfDummyGroupInfo.slice(0, 10),
|
||||||
groupNameFilter = None,
|
groupNameFilter = None,
|
||||||
startFrom = None,
|
startFrom = None,
|
||||||
nextId = Some(listOfDummyGroups(9).id),
|
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 {
|
"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]])
|
doReturn(IO.pure(Set())).when(mockGroupRepo).getGroups(any[Set[String]])
|
||||||
val result: ListMyGroupsResponse =
|
val result: ListMyGroupsResponse =
|
||||||
rightResultOf(underTest.listMyGroups(None, None, 100, notAuth).value)
|
rightResultOf(underTest.listMyGroups(None, None, 100, notAuth, false).value)
|
||||||
result shouldBe ListMyGroupsResponse(Seq(), None, None, None, 100)
|
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()
|
doReturn(IO.pure(Set(okGroup, dummyGroup))).when(mockGroupRepo).getAllGroups()
|
||||||
val result: ListMyGroupsResponse =
|
val result: ListMyGroupsResponse =
|
||||||
rightResultOf(underTest.listMyGroups(None, None, 100, superUserAuth).value)
|
rightResultOf(underTest.listMyGroups(None, None, 100, notAuth, true).value)
|
||||||
verify(mockGroupRepo).getAllGroups()
|
verify(mockGroupRepo).getAllGroups()
|
||||||
result.groups should contain theSameElementsAs Seq(
|
result.groups should contain theSameElementsAs Seq(
|
||||||
GroupInfo(dummyGroup),
|
GroupInfo(dummyGroup),
|
||||||
GroupInfo(okGroup))
|
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())
|
val supportAuth = AuthPrincipal(okUser.copy(isSupport = true), Seq())
|
||||||
doReturn(IO.pure(Set(okGroup, dummyGroup))).when(mockGroupRepo).getAllGroups()
|
doReturn(IO.pure(Set(okGroup, dummyGroup))).when(mockGroupRepo).getAllGroups()
|
||||||
val result: ListMyGroupsResponse =
|
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()
|
verify(mockGroupRepo).getAllGroups()
|
||||||
result.groups should contain theSameElementsAs Seq(
|
result.groups should contain theSameElementsAs Seq(
|
||||||
GroupInfo(dummyGroup),
|
GroupInfo(dummyGroup),
|
||||||
@@ -626,8 +661,8 @@ class MembershipServiceSpec
|
|||||||
.when(mockGroupRepo)
|
.when(mockGroupRepo)
|
||||||
.getGroups(any[Set[String]])
|
.getGroups(any[Set[String]])
|
||||||
val result: ListMyGroupsResponse =
|
val result: ListMyGroupsResponse =
|
||||||
rightResultOf(underTest.listMyGroups(None, None, 100, deletedGroupAuth).value)
|
rightResultOf(underTest.listMyGroups(None, None, 100, deletedGroupAuth, false).value)
|
||||||
result shouldBe ListMyGroupsResponse(Seq(), None, None, None, 100)
|
result shouldBe ListMyGroupsResponse(Seq(), None, None, None, 100, false)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -188,15 +188,16 @@ class MembershipRoutingSpec
|
|||||||
"return a 200 response with the groups when no optional parameters are used" in {
|
"return a 200 response with the groups when no optional parameters are used" in {
|
||||||
val twoUserGroupInfo = GroupInfo(twoUserGroup)
|
val twoUserGroupInfo = GroupInfo(twoUserGroup)
|
||||||
doReturn(
|
doReturn(
|
||||||
result(ListMyGroupsResponse(Seq(okGroupInfo, twoUserGroupInfo), None, None, None, 100)))
|
result(
|
||||||
|
ListMyGroupsResponse(Seq(okGroupInfo, twoUserGroupInfo), None, None, None, 100, false)))
|
||||||
.when(membershipService)
|
.when(membershipService)
|
||||||
.listMyGroups(None, None, 100, okAuth)
|
.listMyGroups(None, None, 100, okAuth, false)
|
||||||
Get("/groups") ~> Route.seal(membershipRoute) ~> check {
|
Get("/groups") ~> Route.seal(membershipRoute) ~> check {
|
||||||
status shouldBe StatusCodes.OK
|
status shouldBe StatusCodes.OK
|
||||||
|
|
||||||
val result = responseAs[ListMyGroupsResponse]
|
val result = responseAs[ListMyGroupsResponse]
|
||||||
val expected =
|
val expected =
|
||||||
ListMyGroupsResponse(Seq(okGroupInfo, twoUserGroupInfo), None, None, None, 100)
|
ListMyGroupsResponse(Seq(okGroupInfo, twoUserGroupInfo), None, None, None, 100, false)
|
||||||
|
|
||||||
result shouldBe expected
|
result shouldBe expected
|
||||||
}
|
}
|
||||||
@@ -209,13 +210,15 @@ class MembershipRoutingSpec
|
|||||||
groupNameFilter = Some("ok"),
|
groupNameFilter = Some("ok"),
|
||||||
startFrom = Some("anyString"),
|
startFrom = Some("anyString"),
|
||||||
nextId = None,
|
nextId = None,
|
||||||
maxItems = 100)))
|
maxItems = 100,
|
||||||
|
ignoreAccess = false)))
|
||||||
.when(membershipService)
|
.when(membershipService)
|
||||||
.listMyGroups(
|
.listMyGroups(
|
||||||
groupNameFilter = Some("ok"),
|
groupNameFilter = Some("ok"),
|
||||||
startFrom = Some("anyString"),
|
startFrom = Some("anyString"),
|
||||||
maxItems = 100,
|
maxItems = 100,
|
||||||
okAuth)
|
okAuth,
|
||||||
|
ignoreAccess = false)
|
||||||
Get("/groups?startFrom=anyString&maxItems=100&groupNameFilter=ok") ~> Route.seal(
|
Get("/groups?startFrom=anyString&maxItems=100&groupNameFilter=ok") ~> Route.seal(
|
||||||
membershipRoute) ~> check {
|
membershipRoute) ~> check {
|
||||||
status shouldBe StatusCodes.OK
|
status shouldBe StatusCodes.OK
|
||||||
@@ -226,7 +229,8 @@ class MembershipRoutingSpec
|
|||||||
groupNameFilter = Some("ok"),
|
groupNameFilter = Some("ok"),
|
||||||
startFrom = Some("anyString"),
|
startFrom = Some("anyString"),
|
||||||
maxItems = 100,
|
maxItems = 100,
|
||||||
nextId = None)
|
nextId = None,
|
||||||
|
ignoreAccess = false)
|
||||||
|
|
||||||
result shouldBe expected
|
result shouldBe expected
|
||||||
}
|
}
|
||||||
@@ -244,7 +248,7 @@ class MembershipRoutingSpec
|
|||||||
"return a 500 response when fails" in {
|
"return a 500 response when fails" in {
|
||||||
doReturn(result(new IllegalArgumentException("fail")))
|
doReturn(result(new IllegalArgumentException("fail")))
|
||||||
.when(membershipService)
|
.when(membershipService)
|
||||||
.listMyGroups(None, None, 100, okAuth)
|
.listMyGroups(None, None, 100, okAuth, false)
|
||||||
|
|
||||||
Get("/groups") ~> Route.seal(membershipRoute) ~> check {
|
Get("/groups") ~> Route.seal(membershipRoute) ~> check {
|
||||||
status shouldBe StatusCodes.InternalServerError
|
status shouldBe StatusCodes.InternalServerError
|
||||||
|
@@ -67,6 +67,7 @@ object VinylDNS {
|
|||||||
lastName: Option[String],
|
lastName: Option[String],
|
||||||
email: Option[String],
|
email: Option[String],
|
||||||
isSuper: Boolean,
|
isSuper: Boolean,
|
||||||
|
isSupport: Boolean,
|
||||||
id: String,
|
id: String,
|
||||||
lockStatus: LockStatus)
|
lockStatus: LockStatus)
|
||||||
object UserInfo {
|
object UserInfo {
|
||||||
@@ -77,6 +78,7 @@ object VinylDNS {
|
|||||||
lastName = user.lastName,
|
lastName = user.lastName,
|
||||||
email = user.email,
|
email = user.email,
|
||||||
isSuper = user.isSuper,
|
isSuper = user.isSuper,
|
||||||
|
isSupport = user.isSupport,
|
||||||
id = user.id,
|
id = user.id,
|
||||||
lockStatus = user.lockStatus
|
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]]()
|
val queryParameters = new HashMap[String, java.util.List[String]]()
|
||||||
for {
|
for {
|
||||||
(name, values) <- request.queryString
|
(name, values) <- request.queryString
|
||||||
|
@@ -22,7 +22,17 @@
|
|||||||
<notification ng-model="alert"></notification>
|
<notification ng-model="alert"></notification>
|
||||||
</div>
|
</div>
|
||||||
</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">
|
<div class="col-md-12">
|
||||||
|
|
||||||
<!-- SIMPLE DATATABLE -->
|
<!-- SIMPLE DATATABLE -->
|
||||||
@@ -63,7 +73,7 @@
|
|||||||
<td class="wrap-long-text">{{group.description}}</td>
|
<td class="wrap-long-text">{{group.description}}</td>
|
||||||
<td>
|
<td>
|
||||||
<div class="table-form-group">
|
<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>
|
View</a>
|
||||||
<a ng-if="groupAdmin(group)" class="btn btn-warning btn-rounded" ng-click="editGroup(group);">
|
<a ng-if="groupAdmin(group)" class="btn btn-warning btn-rounded" ng-click="editGroup(group);">
|
||||||
Edit</a>
|
Edit</a>
|
||||||
@@ -80,6 +90,11 @@
|
|||||||
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<!-- END VERTICAL TABS -->
|
||||||
|
|
||||||
</div>
|
</div>
|
||||||
<!-- END PAGE CONTENT WRAPPER -->
|
<!-- END PAGE CONTENT WRAPPER -->
|
||||||
|
|
||||||
|
@@ -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/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)
|
GET /api/groups/:gid @controllers.VinylDNS.getGroup(gid: String)
|
||||||
POST /api/groups @controllers.VinylDNS.newGroup
|
POST /api/groups @controllers.VinylDNS.newGroup
|
||||||
PUT /api/groups/:gid @controllers.VinylDNS.updateGroup(gid: String)
|
PUT /api/groups/:gid @controllers.VinylDNS.updateGroup(gid: String)
|
||||||
|
@@ -19,7 +19,7 @@
|
|||||||
|
|
||||||
angular.module('batch-change')
|
angular.module('batch-change')
|
||||||
.controller('BatchChangeNewController', function($scope, $log, $location, $timeout, $q, batchChangeService, utilityService, groupsService){
|
.controller('BatchChangeNewController', function($scope, $log, $location, $timeout, $q, batchChangeService, utilityService, groupsService){
|
||||||
groupsService.getMyGroups()
|
groupsService.getGroups()
|
||||||
.then(function (results) {
|
.then(function (results) {
|
||||||
$scope.myGroups = results['data']['groups'];
|
$scope.myGroups = results['data']['groups'];
|
||||||
if ($scope.myGroups.length == 1) {
|
if ($scope.myGroups.length == 1) {
|
||||||
@@ -27,7 +27,7 @@
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
.catch(function (error) {
|
.catch(function (error) {
|
||||||
handleError(error, 'groupsService::getMyGroups-failure');
|
handleError(error, 'groupsService::getGroups-failure');
|
||||||
});
|
});
|
||||||
|
|
||||||
$scope.batch = {};
|
$scope.batch = {};
|
||||||
|
@@ -153,7 +153,7 @@ describe('BatchChange', function(){
|
|||||||
deferred = $q.defer();
|
deferred = $q.defer();
|
||||||
|
|
||||||
spyOn(batchChangeService, 'createBatchChange').and.returnValue(deferred.promise);
|
spyOn(batchChangeService, 'createBatchChange').and.returnValue(deferred.promise);
|
||||||
groupsService.getMyGroups = function() {
|
groupsService.getGroups = function() {
|
||||||
return $q.when({
|
return $q.when({
|
||||||
data: {
|
data: {
|
||||||
groups: "all my groups"
|
groups: "all my groups"
|
||||||
|
@@ -23,6 +23,7 @@ angular.module('controller.groups', []).controller('GroupsController', function
|
|||||||
$scope.groups = { items: [] };
|
$scope.groups = { items: [] };
|
||||||
$scope.groupsLoaded = false;
|
$scope.groupsLoaded = false;
|
||||||
$scope.alerts = [];
|
$scope.alerts = [];
|
||||||
|
$scope.ignoreAccess = false;
|
||||||
|
|
||||||
function handleError(error, type) {
|
function handleError(error, type) {
|
||||||
var alert = utilityService.failure(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 () {
|
$scope.refresh = function () {
|
||||||
//get users groups
|
|
||||||
function success(result) {
|
function success(result) {
|
||||||
$log.log('getMyGroups:refresh-success', result);
|
$log.log('getGroups:refresh-success', result);
|
||||||
//update groups
|
//update groups
|
||||||
$scope.groups.items = result.groups;
|
$scope.groups.items = result.groups;
|
||||||
$scope.groupsLoaded = true;
|
$scope.groupsLoaded = true;
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
return getMyGroups()
|
getGroups($scope.ignoreAccess)
|
||||||
.then(success)
|
.then(success)
|
||||||
.catch(function (error) {
|
.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;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
function getMyGroups() {
|
function getGroups() {
|
||||||
function success(response) {
|
function success(response) {
|
||||||
$log.log('groupsService::getMyGroups-success');
|
$log.log('groupsService::getGroups-success');
|
||||||
return response.data;
|
return response.data;
|
||||||
}
|
}
|
||||||
return groupsService
|
return groupsService
|
||||||
.getMyGroups()
|
.getGroups($scope.ignoreAccess)
|
||||||
.then(success)
|
.then(success)
|
||||||
.catch(function (error){
|
.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;
|
return x.id === $scope.profile.id;
|
||||||
});
|
});
|
||||||
var isSuper = $scope.profile.isSuper;
|
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
|
//get user data on groups view load
|
||||||
|
@@ -31,7 +31,7 @@ describe('Controller: GroupsController', function () {
|
|||||||
profileService.getAuthenticatedUserData = function() {
|
profileService.getAuthenticatedUserData = function() {
|
||||||
return $q.when('data')
|
return $q.when('data')
|
||||||
};
|
};
|
||||||
this.groupsService.getMyGroups = function() {
|
this.groupsService.getGroups = function() {
|
||||||
return $q.when({
|
return $q.when({
|
||||||
data: {
|
data: {
|
||||||
group: 'mock group'
|
group: 'mock group'
|
||||||
@@ -57,14 +57,14 @@ describe('Controller: GroupsController', function () {
|
|||||||
groups: "all my groups"
|
groups: "all my groups"
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
var getMyGroups = spyOn(this.groupsService, 'getMyGroups')
|
var getGroups = spyOn(this.groupsService, 'getGroups')
|
||||||
.and.stub()
|
.and.stub()
|
||||||
.and.returnValue(this.q.when(response));
|
.and.returnValue(this.q.when(response));
|
||||||
|
|
||||||
this.scope.refresh();
|
this.scope.refresh();
|
||||||
this.scope.$digest();
|
this.scope.$digest();
|
||||||
|
|
||||||
expect(getMyGroups.calls.count()).toBe(1);
|
expect(getGroups.calls.count()).toBe(1);
|
||||||
expect(this.scope.groups.items).toBe("all my groups");
|
expect(this.scope.groups.items).toBe("all my groups");
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@@ -18,7 +18,7 @@ angular.module('controller.manageZones', [])
|
|||||||
.controller('ManageZonesController', function ($scope, $timeout, $log, recordsService, zonesService, groupsService,
|
.controller('ManageZonesController', function ($scope, $timeout, $log, recordsService, zonesService, groupsService,
|
||||||
profileService, utilityService) {
|
profileService, utilityService) {
|
||||||
|
|
||||||
groupsService.getMyGroupsStored()
|
groupsService.getGroupsStored()
|
||||||
.then(function (results) {
|
.then(function (results) {
|
||||||
$scope.myGroups = results.groups;
|
$scope.myGroups = results.groups;
|
||||||
})
|
})
|
||||||
|
@@ -33,7 +33,7 @@ describe('Controller: ManageZonesController', function () {
|
|||||||
this.recordsService = recordsService;
|
this.recordsService = recordsService;
|
||||||
this.profileService = profileService;
|
this.profileService = profileService;
|
||||||
this.q = $q;
|
this.q = $q;
|
||||||
this.groupsService.getMyGroups = function () {
|
this.groupsService.getGroups = function () {
|
||||||
return $q.when({
|
return $q.when({
|
||||||
data: {
|
data: {
|
||||||
groups: "all my groups"
|
groups: "all my groups"
|
||||||
|
@@ -350,7 +350,7 @@ angular.module('controller.records', [])
|
|||||||
|
|
||||||
function getMembership(){
|
function getMembership(){
|
||||||
groupsService
|
groupsService
|
||||||
.getMyGroupsStored()
|
.getGroupsStored()
|
||||||
.then(
|
.then(
|
||||||
function (results) {
|
function (results) {
|
||||||
$scope.myGroups = results.groups;
|
$scope.myGroups = results.groups;
|
||||||
@@ -358,7 +358,7 @@ angular.module('controller.records', [])
|
|||||||
determineAdmin()
|
determineAdmin()
|
||||||
})
|
})
|
||||||
.catch(function (error){
|
.catch(function (error){
|
||||||
handleError(error, 'groupsService::getMyGroupsStored-failure');
|
handleError(error, 'groupsService::getGroupsStored-failure');
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -126,7 +126,7 @@ describe('Controller: RecordsController', function () {
|
|||||||
spyOn(this.recordsService, 'getZone')
|
spyOn(this.recordsService, 'getZone')
|
||||||
.and.stub()
|
.and.stub()
|
||||||
.and.returnValue(this.q.when({ data: {zone: mockZone}}));
|
.and.returnValue(this.q.when({ data: {zone: mockZone}}));
|
||||||
spyOn(this.groupsService, 'getMyGroups')
|
spyOn(this.groupsService, 'getGroups')
|
||||||
.and.stub()
|
.and.stub()
|
||||||
.and.returnValue(this.q.when(mockGroups));
|
.and.returnValue(this.q.when(mockGroups));
|
||||||
this.$httpBackend.when('GET', '/api/users/currentuser').respond({});
|
this.$httpBackend.when('GET', '/api/users/currentuser').respond({});
|
||||||
@@ -166,7 +166,7 @@ describe('Controller: RecordsController', function () {
|
|||||||
spyOn(this.recordsService, 'getZone')
|
spyOn(this.recordsService, 'getZone')
|
||||||
.and.stub()
|
.and.stub()
|
||||||
.and.returnValue(this.q.when({ data: {zone: mockZone}}));
|
.and.returnValue(this.q.when({ data: {zone: mockZone}}));
|
||||||
spyOn(this.groupsService, 'getMyGroups')
|
spyOn(this.groupsService, 'getGroups')
|
||||||
.and.stub()
|
.and.stub()
|
||||||
.and.returnValue(this.q.when(mockGroups));
|
.and.returnValue(this.q.when(mockGroups));
|
||||||
this.$httpBackend.when('GET', '/api/users/currentuser').respond({});
|
this.$httpBackend.when('GET', '/api/users/currentuser').respond({});
|
||||||
@@ -206,7 +206,7 @@ describe('Controller: RecordsController', function () {
|
|||||||
spyOn(this.recordsService, 'getZone')
|
spyOn(this.recordsService, 'getZone')
|
||||||
.and.stub()
|
.and.stub()
|
||||||
.and.returnValue(this.q.when({ data: {zone: mockZone}}));
|
.and.returnValue(this.q.when({ data: {zone: mockZone}}));
|
||||||
spyOn(this.groupsService, 'getMyGroups')
|
spyOn(this.groupsService, 'getGroups')
|
||||||
.and.stub()
|
.and.stub()
|
||||||
.and.returnValue(this.q.when(mockGroups));
|
.and.returnValue(this.q.when(mockGroups));
|
||||||
this.$httpBackend.when('GET', '/api/users/currentuser').respond({});
|
this.$httpBackend.when('GET', '/api/users/currentuser').respond({});
|
||||||
@@ -246,7 +246,7 @@ describe('Controller: RecordsController', function () {
|
|||||||
spyOn(this.recordsService, 'getZone')
|
spyOn(this.recordsService, 'getZone')
|
||||||
.and.stub()
|
.and.stub()
|
||||||
.and.returnValue(this.q.when({ data: {zone: mockZone}}));
|
.and.returnValue(this.q.when({ data: {zone: mockZone}}));
|
||||||
spyOn(this.groupsService, 'getMyGroups')
|
spyOn(this.groupsService, 'getGroups')
|
||||||
.and.stub()
|
.and.stub()
|
||||||
.and.returnValue(this.q.when(mockGroups));
|
.and.returnValue(this.q.when(mockGroups));
|
||||||
this.$httpBackend.when('GET', '/api/users/currentuser').respond({});
|
this.$httpBackend.when('GET', '/api/users/currentuser').respond({});
|
||||||
|
@@ -50,7 +50,7 @@ angular.module('controller.zones', [])
|
|||||||
$scope.currentZone.transferConnection = {};
|
$scope.currentZone.transferConnection = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
groupsService.getMyGroups().then(function (results) {
|
groupsService.getGroups().then(function (results) {
|
||||||
if (results.data) {
|
if (results.data) {
|
||||||
$scope.myGroups = results.data.groups;
|
$scope.myGroups = results.data.groups;
|
||||||
$scope.myGroupIds = results.data.groups.map(function(grp) {return grp['id']});
|
$scope.myGroupIds = results.data.groups.map(function(grp) {return grp['id']});
|
||||||
|
@@ -38,7 +38,7 @@ describe('Controller: ZonesController', function () {
|
|||||||
profileService.getAuthenticatedUserData = function() {
|
profileService.getAuthenticatedUserData = function() {
|
||||||
return $q.when({data: {}});
|
return $q.when({data: {}});
|
||||||
};
|
};
|
||||||
groupsService.getMyGroups = function() {
|
groupsService.getGroups = function() {
|
||||||
return $q.when({
|
return $q.when({
|
||||||
data: {
|
data: {
|
||||||
groups: [{id: "all my groups"}]
|
groups: [{id: "all my groups"}]
|
||||||
|
@@ -70,9 +70,9 @@ angular.module('service.groups', [])
|
|||||||
return $http.delete(url, {headers: utilityService.getCsrfHeader()});
|
return $http.delete(url, {headers: utilityService.getCsrfHeader()});
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getMyGroups = function () {
|
this.getGroups = function (ignoreAccess) {
|
||||||
var url = '/api/groups';
|
var url = '/api/groups';
|
||||||
url = this.urlBuilder(url, { maxItems: 1000});
|
url = this.urlBuilder(url, { maxItems: 1000, ignoreAccess: ignoreAccess});
|
||||||
return $http.get(url);
|
return $http.get(url);
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -82,9 +82,9 @@ angular.module('service.groups', [])
|
|||||||
return $http.get(url);
|
return $http.get(url);
|
||||||
};
|
};
|
||||||
|
|
||||||
this.getMyGroupsStored = function () {
|
this.getGroupsStored = function () {
|
||||||
if (_refreshMyGroups || _myGroupsPromise == undefined) {
|
if (_refreshMyGroups || _myGroupsPromise == undefined) {
|
||||||
_myGroupsPromise = this.getMyGroups().then(
|
_myGroupsPromise = this.getGroups().then(
|
||||||
function(response) {
|
function(response) {
|
||||||
_refreshMyGroups = false;
|
_refreshMyGroups = false;
|
||||||
return response.data;
|
return response.data;
|
||||||
|
@@ -432,26 +432,26 @@ describe('Service: groupsService', function () {
|
|||||||
this.$httpBackend.flush();
|
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';
|
var url = '/api/groups';
|
||||||
this.$httpBackend.whenRoute('GET', url).respond(200, getJSONFixture('mockGroupList.json'));
|
this.$httpBackend.whenRoute('GET', url).respond(200, getJSONFixture('mockGroupList.json'));
|
||||||
this.groupsService.getMyGroups()
|
this.groupsService.getGroups()
|
||||||
.then(function (response) {
|
.then(function (response) {
|
||||||
expect(response.status).toBe(200);
|
expect(response.status).toBe(200);
|
||||||
done();
|
done();
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
fail('getMyGroups expected 200, but got ' + response.status.toString());
|
fail('getGroups expected 200, but got ' + response.status.toString());
|
||||||
done();
|
done();
|
||||||
});
|
});
|
||||||
this.$httpBackend.flush();
|
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';
|
var url = '/api/groups';
|
||||||
this.$httpBackend.whenRoute('GET', url).respond(401, "The resource requires authentication, which was not supplied with the request");
|
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) {
|
.then(function (response) {
|
||||||
fail("getMyGroups expected 401, but got " + response.status.toString());
|
fail("getGroups expected 401, but got " + response.status.toString());
|
||||||
done();
|
done();
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
expect(error.status).toBe(401);
|
expect(error.status).toBe(401);
|
||||||
@@ -460,14 +460,14 @@ describe('Service: groupsService', function () {
|
|||||||
this.$httpBackend.flush();
|
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 url = '/api/groups';
|
||||||
var groupsResult = getJSONFixture('mockGroupList.json');
|
var groupsResult = getJSONFixture('mockGroupList.json');
|
||||||
this.$httpBackend.whenRoute('GET', url).respond(200, groupsResult);
|
this.$httpBackend.whenRoute('GET', url).respond(200, groupsResult);
|
||||||
var getMyGroupsCalls = spyOn(this.groupsService, 'getMyGroups').and.callThrough();
|
var getGroupsCalls = spyOn(this.groupsService, 'getGroups').and.callThrough();
|
||||||
var getMyGroupsStoredCalls = spyOn(this.groupsService, 'getMyGroupsStored').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);
|
expect(response).toEqual(groupsResult);
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
fail('getGroup expected 202 with json, but got' + error.status.toString());
|
fail('getGroup expected 202 with json, but got' + error.status.toString());
|
||||||
@@ -475,42 +475,42 @@ describe('Service: groupsService', function () {
|
|||||||
|
|
||||||
this.$httpBackend.flush();
|
this.$httpBackend.flush();
|
||||||
|
|
||||||
this.groupsService.getMyGroupsStored().then(function (response) {
|
this.groupsService.getGroupsStored().then(function (response) {
|
||||||
expect(response).toEqual(groupsResult);
|
expect(response).toEqual(groupsResult);
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
fail('getGroup expected 202 with json, but got' + error.status.toString());
|
fail('getGroup expected 202 with json, but got' + error.status.toString());
|
||||||
});
|
});
|
||||||
|
|
||||||
expect(getMyGroupsStoredCalls.calls.count()).toBe(2);
|
expect(getGroupsStoredCalls.calls.count()).toBe(2);
|
||||||
expect(getMyGroupsCalls.calls.count()).toBe(1);
|
expect(getGroupsCalls.calls.count()).toBe(1);
|
||||||
done();
|
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';
|
var url = '/api/groups';
|
||||||
this.$httpBackend.whenRoute('GET', url).respond(401, "The resource requires authentication, which was not supplied with the request");
|
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 getGroupsCalls = spyOn(this.groupsService, 'getGroups').and.callThrough();
|
||||||
var getMyGroupsStoredCalls = spyOn(this.groupsService, 'getMyGroupsStored').and.callThrough();
|
var getGroupsStoredCalls = spyOn(this.groupsService, 'getGroupsStored').and.callThrough();
|
||||||
|
|
||||||
this.groupsService.getMyGroupsStored().then(function (response) {
|
this.groupsService.getGroupsStored().then(function (response) {
|
||||||
fail("getMyGroups expected 401, but got " + response.status.toString());
|
fail("getGroups expected 401, but got " + response.status.toString());
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
expect(error.status).toBe(401);
|
expect(error.status).toBe(401);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$httpBackend.flush();
|
this.$httpBackend.flush();
|
||||||
|
|
||||||
this.groupsService.getMyGroupsStored().then(function (response) {
|
this.groupsService.getGroupsStored().then(function (response) {
|
||||||
fail("getMyGroups expected 401, but got " + response.status.toString());
|
fail("getGroups expected 401, but got " + response.status.toString());
|
||||||
}, function (error) {
|
}, function (error) {
|
||||||
expect(error.status).toBe(401);
|
expect(error.status).toBe(401);
|
||||||
});
|
});
|
||||||
|
|
||||||
this.$httpBackend.flush();
|
this.$httpBackend.flush();
|
||||||
|
|
||||||
expect(getMyGroupsStoredCalls.calls.count()).toBe(2);
|
expect(getGroupsStoredCalls.calls.count()).toBe(2);
|
||||||
expect(getMyGroupsCalls.calls.count()).toBe(2);
|
expect(getGroupsCalls.calls.count()).toBe(2);
|
||||||
done();
|
done();
|
||||||
|
|
||||||
});
|
});
|
||||||
|
@@ -1418,7 +1418,7 @@ class VinylDNSSpec extends Specification with Mockito with TestApplicationData w
|
|||||||
client,
|
client,
|
||||||
components,
|
components,
|
||||||
crypto)
|
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))
|
.withSession("username" -> frodoUser.userName, "accessKey" -> frodoUser.accessKey))
|
||||||
|
|
||||||
status(result) must beEqualTo(OK)
|
status(result) must beEqualTo(OK)
|
||||||
@@ -1443,7 +1443,7 @@ class VinylDNSSpec extends Specification with Mockito with TestApplicationData w
|
|||||||
client,
|
client,
|
||||||
components,
|
components,
|
||||||
crypto)
|
crypto)
|
||||||
val result = underTest.getMyGroups()(FakeRequest(GET, s"/api/groups"))
|
val result = underTest.getGroups()(FakeRequest(GET, s"/api/groups"))
|
||||||
|
|
||||||
status(result) mustEqual 401
|
status(result) mustEqual 401
|
||||||
contentAsString(result) must beEqualTo(
|
contentAsString(result) must beEqualTo(
|
||||||
@@ -1468,7 +1468,7 @@ class VinylDNSSpec extends Specification with Mockito with TestApplicationData w
|
|||||||
client,
|
client,
|
||||||
components,
|
components,
|
||||||
crypto)
|
crypto)
|
||||||
val result = underTest.getMyGroups()(
|
val result = underTest.getGroups()(
|
||||||
FakeRequest(GET, s"/api/groups")
|
FakeRequest(GET, s"/api/groups")
|
||||||
.withSession(
|
.withSession(
|
||||||
"username" -> lockedFrodoUser.userName,
|
"username" -> lockedFrodoUser.userName,
|
||||||
@@ -1500,7 +1500,7 @@ class VinylDNSSpec extends Specification with Mockito with TestApplicationData w
|
|||||||
client,
|
client,
|
||||||
components,
|
components,
|
||||||
crypto)
|
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))
|
.withSession("username" -> frodoUser.userName, "accessKey" -> frodoUser.accessKey))
|
||||||
|
|
||||||
status(result) must beEqualTo(UNAUTHORIZED)
|
status(result) must beEqualTo(UNAUTHORIZED)
|
||||||
|
Reference in New Issue
Block a user