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))
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])
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)
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"))
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")
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"])
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)
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)
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)
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)
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)
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
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)
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)
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)
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)
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
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