Skip to content

Commit

Permalink
Merge pull request #1121 from Aravindh-Raju/aravindhr/validate-group-…
Browse files Browse the repository at this point in the history
…fields

Validate Group Fields in API
  • Loading branch information
nspadaccino committed Sep 12, 2022
2 parents 7f9f4ee + 5f910cc commit ce716a3
Show file tree
Hide file tree
Showing 5 changed files with 63 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ final case class GroupNotFoundError(msg: String) extends Throwable(msg)

final case class GroupAlreadyExistsError(msg: String) extends Throwable(msg)

final case class GroupValidationError(msg: String) extends Throwable(msg)

final case class UserNotFoundError(msg: String) extends Throwable(msg)

final case class InvalidGroupError(msg: String) extends Throwable(msg)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ class MembershipService(
val adminMembers = inputGroup.adminUserIds
val nonAdminMembers = inputGroup.memberIds.diff(adminMembers)
for {
_ <- groupValidation(newGroup)
_ <- hasMembersAndAdmins(newGroup).toResult
_ <- groupWithSameNameDoesNotExist(newGroup.name)
_ <- usersExist(newGroup.memberIds)
Expand All @@ -76,6 +77,7 @@ class MembershipService(
for {
existingGroup <- getExistingGroup(groupId)
newGroup = existingGroup.withUpdates(name, email, description, memberIds, adminUserIds)
_ <- groupValidation(newGroup)
_ <- canEditGroup(existingGroup, authPrincipal).toResult
addedAdmins = newGroup.adminUserIds.diff(existingGroup.adminUserIds)
// new non-admin members ++ admins converted to non-admins
Expand Down Expand Up @@ -277,6 +279,16 @@ class MembershipService(
.orFail(GroupNotFoundError(s"Group with ID $groupId was not found"))
.toResult[Group]

// Validate group details. Group name and email cannot be empty
def groupValidation(group: Group): Result[Unit] = {
Option(group) match {
case Some(value) if Option(value.name).forall(_.trim.isEmpty) || Option(value.email).forall(_.trim.isEmpty) =>
GroupValidationError(GroupValidationErrorMsg).asLeft
case _ =>
().asRight
}
}.toResult

def groupWithSameNameDoesNotExist(name: String): Result[Unit] =
groupRepo
.getGroupByName(name)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,7 @@ class MembershipRoute(
case GroupNotFoundError(msg) => complete(StatusCodes.NotFound, msg)
case NotAuthorizedError(msg) => complete(StatusCodes.Forbidden, msg)
case GroupAlreadyExistsError(msg) => complete(StatusCodes.Conflict, msg)
case GroupValidationError(msg) => complete(StatusCodes.BadRequest, msg)
case InvalidGroupError(msg) => complete(StatusCodes.BadRequest, msg)
case UserNotFoundError(msg) => complete(StatusCodes.NotFound, msg)
case InvalidGroupRequestError(msg) => complete(StatusCodes.BadRequest, msg)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ class MembershipServiceSpec
"create a new group" should {
"save the group and add the members when the group is valid" in {
doReturn(IO.pure(Some(okUser))).when(mockUserRepo).getUser("ok")
doReturn(().toResult).when(underTest).groupValidation(groupInfo)
doReturn(().toResult).when(underTest).groupWithSameNameDoesNotExist(groupInfo.name)
doReturn(().toResult).when(underTest).usersExist(groupInfo.memberIds)
doReturn(IO.pure(okGroup)).when(mockGroupRepo).save(any[DB], any[Group])
Expand Down Expand Up @@ -141,6 +142,7 @@ class MembershipServiceSpec

"save the groupChange in the groupChangeRepo" in {
doReturn(IO.pure(Some(okUser))).when(mockUserRepo).getUser("ok")
doReturn(().toResult).when(underTest).groupValidation(groupInfo)
doReturn(().toResult).when(underTest).groupWithSameNameDoesNotExist(groupInfo.name)
doReturn(().toResult).when(underTest).usersExist(groupInfo.memberIds)
doReturn(IO.pure(okGroup)).when(mockGroupRepo).save(any[DB], any[Group])
Expand Down Expand Up @@ -168,7 +170,7 @@ class MembershipServiceSpec
adminUserIds = Set(okUserInfo.id, dummyUserInfo.id)
)
val expectedMembersAdded = Set(okUserInfo.id, dummyUserInfo.id)

doReturn(().toResult).when(underTest).groupValidation(info)
doReturn(().toResult).when(underTest).groupWithSameNameDoesNotExist(info.name)
doReturn(().toResult).when(underTest).usersExist(any[Set[String]])
doReturn(IO.pure(okGroup)).when(mockGroupRepo).save(any[DB], any[Group])
Expand Down Expand Up @@ -196,6 +198,7 @@ class MembershipServiceSpec
"set the current user as a member" in {
val info = groupInfo.copy(memberIds = Set.empty, adminUserIds = Set.empty)
doReturn(IO.pure(Some(okUser))).when(mockUserRepo).getUser("ok")
doReturn(().toResult).when(underTest).groupValidation(info)
doReturn(().toResult).when(underTest).groupWithSameNameDoesNotExist(info.name)
doReturn(().toResult).when(underTest).usersExist(Set(okAuth.userId))
doReturn(IO.pure(okGroup)).when(mockGroupRepo).save(any[DB], any[Group])
Expand Down Expand Up @@ -224,6 +227,7 @@ class MembershipServiceSpec

"return an error if users do not exist" in {
doReturn(IO.pure(Some(okUser))).when(mockUserRepo).getUser("ok")
doReturn(().toResult).when(underTest).groupValidation(groupInfo)
doReturn(().toResult).when(underTest).groupWithSameNameDoesNotExist(groupInfo.name)
doReturn(result(UserNotFoundError("fail")))
.when(underTest)
Expand All @@ -239,6 +243,7 @@ class MembershipServiceSpec

"return an error if fail while saving the group" in {
doReturn(IO.pure(Some(okUser))).when(mockUserRepo).getUser("ok")
doReturn(().toResult).when(underTest).groupValidation(groupInfo)
doReturn(().toResult).when(underTest).groupWithSameNameDoesNotExist(groupInfo.name)
doReturn(().toResult).when(underTest).usersExist(groupInfo.memberIds)
doReturn(IO.raiseError(new RuntimeException("fail"))).when(mockGroupRepo).save(any[DB], any[Group])
Expand All @@ -253,6 +258,7 @@ class MembershipServiceSpec

"return an error if fail while adding the members" in {
doReturn(IO.pure(Some(okUser))).when(mockUserRepo).getUser("ok")
doReturn(().toResult).when(underTest).groupValidation(groupInfo)
doReturn(().toResult).when(underTest).groupWithSameNameDoesNotExist(groupInfo.name)
doReturn(().toResult).when(underTest).usersExist(groupInfo.memberIds)
doReturn(IO.pure(okGroup)).when(mockGroupRepo).save(any[DB], any[Group])
Expand All @@ -264,6 +270,20 @@ class MembershipServiceSpec
val error = leftResultOf(underTest.createGroup(groupInfo, okAuth).value)
error shouldBe a[RuntimeException]
}

"return an error if group name and/or email is empty" in {
doReturn(IO.pure(Some(okUser))).when(mockUserRepo).getUser("ok")
doReturn(result(GroupValidationError("fail")))
.when(underTest)
.groupValidation(groupInfo.copy(name = "", email = ""))

val error = leftResultOf(underTest.createGroup(groupInfo.copy(name = "", email = ""), okAuth).value)
error shouldBe a[GroupValidationError]

verify(mockGroupRepo, never()).save(any[DB], any[Group])
verify(mockMembershipRepo, never())
.saveMembers(any[DB], anyString, any[Set[String]], isAdmin = anyBoolean)
}
}

"update an existing group" should {
Expand Down Expand Up @@ -388,6 +408,31 @@ class MembershipServiceSpec
error shouldBe a[GroupAlreadyExistsError]
}

"return an error if group name and/or email is empty" in {
doReturn(IO.pure(Some(existingGroup)))
.when(mockGroupRepo)
.getGroup(existingGroup.id)
doReturn(().toResult).when(underTest).usersExist(any[Set[String]])
doReturn(result(GroupValidationError("fail")))
.when(underTest)
.groupValidation(existingGroup.copy(name = "", email = ""))

val error = leftResultOf(
underTest
.updateGroup(
updatedInfo.id,
name = "",
email = "",
updatedInfo.description,
updatedInfo.memberIds,
updatedInfo.adminUserIds,
okAuth
)
.value
)
error shouldBe a[GroupValidationError]
}

"return an error if the group is not found" in {
doReturn(IO.pure(None)).when(mockGroupRepo).getGroup(existingGroup.id)

Expand Down
2 changes: 2 additions & 0 deletions modules/core/src/main/scala/vinyldns/core/Messages.scala
Original file line number Diff line number Diff line change
Expand Up @@ -79,4 +79,6 @@ object Messages {
val NotAuthorizedErrorMsg =
"User \"%s\" is not authorized. Contact %s owner group: %s at %s to make DNS changes."

// Error displayed when group name or email is empty
val GroupValidationErrorMsg = "Group name and email cannot be empty."
}

0 comments on commit ce716a3

Please sign in to comment.