Пример #1
0
    def testReadWriteApprovalRequestsWithFilledInUsersEmailsAndGrants(self):
        d = self.db

        # Ensure that the requestor user exists.
        d.WriteGRRUser("requestor")

        client_id = "C.0000000050000001"
        approval_request = rdf_objects.ApprovalRequest(
            approval_type=rdf_objects.ApprovalRequest.ApprovalType.
            APPROVAL_TYPE_CLIENT,
            subject_id=client_id,
            requestor_username="******",
            reason="some test reason",
            expiration_time=rdfvalue.RDFDatetime(42),
            notified_users=["user1", "user2", "user3"],
            email_cc_addresses=["*****@*****.**", "*****@*****.**"],
            grants=[
                rdf_objects.ApprovalGrant(grantor_username="******"),
                rdf_objects.ApprovalGrant(grantor_username="******")
            ])

        approval_id = d.WriteApprovalRequest(approval_request)

        read_request = d.ReadApprovalRequest("requestor", approval_id)

        self.assertEqual(sorted(approval_request.notified_users),
                         sorted(read_request.notified_users))
        self.assertEqual(sorted(approval_request.email_cc_addresses),
                         sorted(read_request.email_cc_addresses))
        self.assertEqual(
            sorted(g.grantor_username for g in approval_request.grants),
            sorted(g.grantor_username for g in read_request.grants))
Пример #2
0
    def testReadApprovalRequestsIncludesGrantsIntoMultipleResults(self):
        d = self.db

        # Ensure that the requestor user exists.
        d.WriteGRRUser("requestor")

        for i in range(10):
            approval_request = rdf_objects.ApprovalRequest(
                approval_type=rdf_objects.ApprovalRequest.ApprovalType.
                APPROVAL_TYPE_CLIENT,
                subject_id="C.00000000000000%d" % i,
                requestor_username="******",
                reason="some test reason %d" % i,
                grants=[
                    rdf_objects.ApprovalGrant(grantor_username="******" %
                                              i),
                    rdf_objects.ApprovalGrant(grantor_username="******" %
                                              i)
                ],
                expiration_time=rdfvalue.RDFDatetime.Now() +
                rdfvalue.Duration("1d"))
            d.WriteApprovalRequest(approval_request)

        approvals = sorted(d.ReadApprovalRequests(
            "requestor",
            rdf_objects.ApprovalRequest.ApprovalType.APPROVAL_TYPE_CLIENT),
                           key=lambda a: a.reason)

        self.assertEqual(len(approvals), 10)

        for i, approval in enumerate(approvals):
            self.assertEqual(
                sorted(g.grantor_username for g in approval.grants),
                ["grantor_%d_1" % i, "grantor_%d_2" % i])
Пример #3
0
    def testReturnsIfApprovalIsNotExpiredAndHasTwoGrants(self):
        approval_request = self._CreateRequest(grants=[
            rdf_objects.ApprovalGrant(grantor_username=u"grantor1"),
            rdf_objects.ApprovalGrant(grantor_username=u"grantor2")
        ])

        approval_checks.CheckApprovalRequest(approval_request)
Пример #4
0
    def testWhenAuthMgrActiveChecksApproversForEachClientLabel(self, mock_mgr):
        data_store.REL_DB.AddClientLabels(self.client.client_id, u"GRR",
                                          [u"foo", u"bar"])

        approval_request = self._CreateRequest(grants=[
            rdf_objects.ApprovalGrant(grantor_username=u"grantor1"),
            rdf_objects.ApprovalGrant(grantor_username=u"grantor2")
        ])

        # Make sure approval manager is active.
        mock_mgr.IsActive.return_value = True

        approval_checks.CheckApprovalRequest(approval_request)

        self.assertEqual(len(mock_mgr.CheckApproversForLabel.mock_calls), 2)

        args = mock_mgr.CheckApproversForLabel.mock_calls[0][1]
        self.assertEqual(args,
                         (access_control.ACLToken(username=u"requestor"),
                          rdfvalue.RDFURN(self.client.client_id), u"requestor",
                          set(["grantor1", "grantor2"]), u"bar"))
        args = mock_mgr.CheckApproversForLabel.mock_calls[1][1]
        self.assertEqual(args,
                         (access_control.ACLToken(username=u"requestor"),
                          rdfvalue.RDFURN(self.client.client_id), u"requestor",
                          set(["grantor1", "grantor2"]), u"foo"))
Пример #5
0
    def testDeleteUserDeletesApprovalGrantsForGrantor(self):
        d = self.db
        d.WriteGRRUser("requestor")
        d.WriteGRRUser("grantor")
        d.WriteGRRUser("grantor2")

        client_id = "C.0000000050000001"
        approval_request = rdf_objects.ApprovalRequest(
            approval_type=rdf_objects.ApprovalRequest.ApprovalType.
            APPROVAL_TYPE_CLIENT,
            subject_id=client_id,
            requestor_username="******",
            reason="some test reason",
            expiration_time=rdfvalue.RDFDatetime.FromSecondsSinceEpoch(42),
            notified_users=["user1", "user2", "user3"],
            email_cc_addresses=["*****@*****.**", "*****@*****.**"],
            grants=[
                rdf_objects.ApprovalGrant(grantor_username="******"),
                rdf_objects.ApprovalGrant(grantor_username="******"),
            ])

        approval_id = d.WriteApprovalRequest(approval_request)
        d.DeleteGRRUser("grantor")
        result = d.ReadApprovalRequest("requestor", approval_id)
        self.assertLen(result.grants, 1)
        self.assertEqual(result.grants[0].grantor_username, "grantor2")
Пример #6
0
    def testReadApprovalRequestsForSubjectIncludesGrantsIntoSingleResult(self):
        client_id = "C.0000000050000001"
        d = self.db

        # Ensure that the requestor user exists.
        d.WriteGRRUser("requestor")

        approval_request = rdf_objects.ApprovalRequest(
            approval_type=rdf_objects.ApprovalRequest.ApprovalType.
            APPROVAL_TYPE_CLIENT,
            subject_id=client_id,
            requestor_username="******",
            reason="some test reason",
            grants=[
                rdf_objects.ApprovalGrant(grantor_username="******"),
                rdf_objects.ApprovalGrant(grantor_username="******")
            ],
            expiration_time=rdfvalue.RDFDatetime.Now() +
            rdfvalue.Duration("1d"))
        approval_id = d.WriteApprovalRequest(approval_request)

        approvals = list(
            d.ReadApprovalRequests(
                "requestor",
                rdf_objects.ApprovalRequest.ApprovalType.APPROVAL_TYPE_CLIENT,
                subject_id=client_id))

        self.assertEqual(len(approvals), 1)
        self.assertEqual(approvals[0].approval_id, approval_id)

        self.assertEqual(
            sorted(g.grantor_username for g in approvals[0].grants),
            ["grantor1", "grantor2"])
Пример #7
0
  def testRaisesWhenNoGrantsFromAdmins(self):
    approval_request = self._CreateRequest(grants=[
        rdf_objects.ApprovalGrant(grantor_username=u"grantor1"),
        rdf_objects.ApprovalGrant(grantor_username=u"grantor2")
    ])

    with self.assertRaisesRegex(access_control.UnauthorizedAccess,
                                "Need at least 1 admin approver for access"):
      approval_checks.CheckApprovalRequest(approval_request)
Пример #8
0
    def testReturnsIfApprovalIsNotExpiredAndHasTwoGrantsIncludingAdmin(self):
        self.CreateAdminUser("grantor2")

        approval_request = self._CreateRequest(grants=[
            rdf_objects.ApprovalGrant(grantor_username="******"),
            rdf_objects.ApprovalGrant(grantor_username="******")
        ])

        approval_checks.CheckApprovalRequest(approval_request)
Пример #9
0
    def testWhenAuthMgrActiveReturnsIfClientHasNoLabels(self, mock_mgr):
        approval_request = self._CreateRequest(grants=[
            rdf_objects.ApprovalGrant(grantor_username=u"grantor1"),
            rdf_objects.ApprovalGrant(grantor_username=u"grantor2")
        ])

        # Make sure approval manager is active.
        mock_mgr.IsActive.return_value = True

        approval_checks.CheckApprovalRequest(approval_request)
Пример #10
0
  def testRaisesIfApprovalExpired(self):
    approval_request = self._CreateRequest(
        expiration_time=rdfvalue.RDFDatetime.Now() - rdfvalue.Duration("1m"),
        grants=[
            rdf_objects.ApprovalGrant(grantor_username=u"grantor1"),
            rdf_objects.ApprovalGrant(grantor_username=u"grantor2")
        ])

    with self.assertRaisesRegexp(access_control.UnauthorizedAccess,
                                 "Approval request is expired"):
      approval_checks.CheckApprovalRequest(approval_request)
Пример #11
0
  def testRaisesIfApprovalExpired(self):
    # Make sure that approval is otherwise valid.
    self.CreateAdminUser(u"grantor2")

    approval_request = self._CreateRequest(
        expiration_time=rdfvalue.RDFDatetime.Now() -
        rdfvalue.Duration.From(1, rdfvalue.MINUTES),
        grants=[
            rdf_objects.ApprovalGrant(grantor_username=u"grantor1"),
            rdf_objects.ApprovalGrant(grantor_username=u"grantor2")
        ])

    with self.assertRaisesRegex(access_control.UnauthorizedAccess,
                                "Approval request is expired"):
      approval_checks.CheckApprovalRequest(approval_request)
Пример #12
0
def _ResponseToApprovalsWithGrants(response):
    """Converts a generator with approval rows into ApprovalRequest objects."""
    prev_triplet = None
    cur_approval_request = None
    for (approval_id_int, approval_timestamp, approval_request_bytes,
         grantor_username, grant_timestamp) in response:

        cur_triplet = (approval_id_int, approval_timestamp,
                       approval_request_bytes)

        if cur_triplet != prev_triplet:
            prev_triplet = cur_triplet

            if cur_approval_request:
                yield cur_approval_request

            cur_approval_request = mysql_utils.StringToRDFProto(
                rdf_objects.ApprovalRequest, approval_request_bytes)
            cur_approval_request.approval_id = _IntToApprovalID(
                approval_id_int)
            cur_approval_request.timestamp = mysql_utils.TimestampToRDFDatetime(
                approval_timestamp)

        if grantor_username and grant_timestamp:
            cur_approval_request.grants.append(
                rdf_objects.ApprovalGrant(
                    grantor_username=grantor_username,
                    timestamp=mysql_utils.TimestampToRDFDatetime(
                        grant_timestamp)))

    if cur_approval_request:
        yield cur_approval_request
Пример #13
0
    def testDeleteUserDeletesApprovalRequests(self):
        d = self.db
        d.WriteGRRUser("requestor")
        d.WriteGRRUser("grantor")

        client_id = "C.0000000050000001"
        approval_request = rdf_objects.ApprovalRequest(
            approval_type=rdf_objects.ApprovalRequest.ApprovalType.
            APPROVAL_TYPE_CLIENT,
            subject_id=client_id,
            requestor_username="******",
            reason="some test reason",
            expiration_time=rdfvalue.RDFDatetime.FromSecondsSinceEpoch(42),
            grants=[
                rdf_objects.ApprovalGrant(grantor_username="******"),
            ])

        approval_id = d.WriteApprovalRequest(approval_request)
        self.assertTrue(approval_id)
        d.ReadApprovalRequest("requestor", approval_id)

        d.DeleteGRRUser("requestor")

        with self.assertRaises(db.UnknownApprovalRequestError):
            d.ReadApprovalRequest("requestor", approval_id)
Пример #14
0
    def testRaisesWhenJustOneGrant(self):
        approval_request = self._CreateRequest(
            grants=[rdf_objects.ApprovalGrant(grantor_username=u"grantor")])

        with self.assertRaisesRegexp(
                access_control.UnauthorizedAccess,
                "Need at least 1 additional approver for access"):
            approval_checks.CheckApprovalRequest(approval_request)
Пример #15
0
    def testWhenAuthMgrActiveRaisesIfAuthMgrRaises(self, mock_mgr):
        data_store.REL_DB.AddClientLabels(self.client_id, u"GRR", [u"foo"])

        approval_request = self._CreateRequest(grants=[
            rdf_objects.ApprovalGrant(grantor_username=u"grantor1"),
            rdf_objects.ApprovalGrant(grantor_username=u"grantor2")
        ])

        # Make sure approval manager is active.
        mock_mgr.IsActive.return_value = True

        # CheckApproversForLabel should raise.
        error = access_control.UnauthorizedAccess("some error")
        mock_mgr.CheckApproversForLabel.side_effect = error

        with self.assertRaisesRegexp(access_control.UnauthorizedAccess,
                                     "some error"):
            approval_checks.CheckApprovalRequest(approval_request)
Пример #16
0
 def GrantApproval(self, requestor_username, approval_id, grantor_username):
   """Grants approval for a given request using given username."""
   try:
     approval = self.approvals_by_username[requestor_username][approval_id]
     approval.grants.append(
         rdf_objects.ApprovalGrant(
             grantor_username=grantor_username,
             timestamp=rdfvalue.RDFDatetime.Now()))
   except KeyError:
     raise db.UnknownApprovalRequestError("Can't find approval with id: %s" %
                                          approval_id)
Пример #17
0
    def ReadApprovalRequest(self,
                            requestor_username,
                            approval_id,
                            cursor=None):
        """Reads an approval request object with a given id."""

        query = ("""
        SELECT
            ar.approval_id,
            UNIX_TIMESTAMP(ar.timestamp),
            ar.approval_request,
            u.username,
            UNIX_TIMESTAMP(ag.timestamp)
        FROM approval_request ar
        LEFT JOIN approval_grant ag USING (username_hash, approval_id)
        LEFT JOIN grr_users u ON u.username_hash = ag.grantor_username_hash
        WHERE ar.approval_id = %s AND ar.username_hash = %s
        """)

        cursor.execute(query, [
            _ApprovalIDToInt(approval_id),
            mysql_utils.Hash(requestor_username)
        ])
        res = cursor.fetchall()
        if not res:
            raise db.UnknownApprovalRequestError("Approval '%s' not found." %
                                                 approval_id)

        approval_id_int, timestamp, approval_request_bytes, _, _ = res[0]

        approval_request = mysql_utils.StringToRDFProto(
            rdf_objects.ApprovalRequest, approval_request_bytes)
        approval_request.approval_id = _IntToApprovalID(approval_id_int)
        approval_request.timestamp = mysql_utils.TimestampToRDFDatetime(
            timestamp)

        for _, _, _, grantor_username, timestamp in res:
            if not grantor_username:
                continue

            # Note: serialized approval_request objects are guaranteed to not
            # have any grants.
            approval_request.grants.append(
                rdf_objects.ApprovalGrant(
                    grantor_username=grantor_username,
                    timestamp=mysql_utils.TimestampToRDFDatetime(timestamp)))

        return approval_request
Пример #18
0
    def ReadApprovalRequest(self,
                            requestor_username,
                            approval_id,
                            cursor=None):
        """Reads an approval request object with a given id."""

        query = (
            "SELECT approval_request.approval_id, approval_request.timestamp, "
            "approval_request.approval_request, "
            "approval_grant.grantor_username, approval_grant.timestamp "
            "FROM approval_request "
            "LEFT JOIN approval_grant USING (username, approval_id) "
            "WHERE approval_request.approval_id=%s "
            "AND approval_request.username=%s")

        cursor.execute(query,
                       [_ApprovalIDToInt(approval_id), requestor_username])
        res = cursor.fetchall()
        if not res:
            raise db.UnknownApprovalRequestError("Approval '%s' not found." %
                                                 approval_id)

        approval_id_int, timestamp, approval_request_bytes, _, _ = res[0]

        approval_request = mysql_utils.StringToRDFProto(
            rdf_objects.ApprovalRequest, approval_request_bytes)
        approval_request.approval_id = _IntToApprovalID(approval_id_int)
        approval_request.timestamp = mysql_utils.MysqlToRDFDatetime(timestamp)

        for _, _, _, grantor_username, timestamp in res:
            if not grantor_username:
                continue

            # Note: serialized approval_request objects are guaranteed to not
            # have any grants.
            approval_request.grants.append(
                rdf_objects.ApprovalGrant(
                    grantor_username=grantor_username,
                    timestamp=mysql_utils.MysqlToRDFDatetime(timestamp)))

        return approval_request