Example #1
0
    def init_empty_target_mapping(self, exp_uid, n):
        """
        Create a target doc that indicates a targetless experiment, the default state upon initialization.
        This doc is formatted as follows:
        {'targetless': True, 'exp_uid': exp_uid}

        Inputs: 
            (string) exp_uid, (int) n
        Outputs:
            (dict) {}

        Usage: ::\n
        didSucceed = targetmapper.init_empty_target_mapping(exp_uid)
        """
        # Initilize target document and insert into MongoDB
        doc = {'targetless': True, 'exp_uid': exp_uid}
        didSucceed, message = db.setDoc(self.database_id, self.bucket_id, None, doc)
        # If target doc could not be created, throw an error
        if not didSucceed:
            raise DatabaseException("Failed to init_empty_target_mapping: %s"%(message))           
        # Get all docs related to the specified exp_uid
        mongotized_target_blob,didSucceed,message = db.getDocsByPattern(self.database_id, self.bucket_id, {'exp_uid': exp_uid})
        # If the newly initialized DB docs can't be found, throw an error
        if not didSucceed:
            raise DatabaseException("Failed to init_empty_target_mapping: %s"%(message))
        # Pop target_dict out of list
        target_blob_dict = mongotized_target_blob.pop(0)
        # Return target_blob_dict of all targets corresponding to current exp_uid
        return {}       
Example #2
0
    def get_targetID_given_index(self, exp_uid, index):
        """
        Get the client supplied target_id given an internal NEXT target index

        Inputs:
            (string) exp_uid, (int) index
        Outputs:
            (string) target_id

        Usage: ::\n
        didSucceed = targetmapper.get_targetID_given_index(exp_uid, index)
        """
        target_data,didSucceed,message = db.getDocsByPattern(self.database_id, self.bucket_id, {'exp_uid': exp_uid, 'targetless': True})
        # Pass back message if getDocsByPattern fails
        if not didSucceed:
            raise DatabaseException("Failed to get_targetID_given_index: %s"%(message))
        # This line is key. If no doc exists with the specified exp_uid and targetless = True, then targetless = False
        if not target_data:
            return index

        # Get an individual target form the DB given exp_uid and index
        got_target,didSucceed,message = db.getDocsByPattern(self.database_id, self.bucket_id, {'exp_uid': exp_uid, 'index': index})
        # If doc cannot be retreived, throw an error
        if not didSucceed:
            raise DatabaseException("Failed to get_targetID_given_index: %s"%(message))

        # I'm not sure if getDocsByPattern will return list if only 1 doc is retrevied. If this fails, remove this line.
        got_target = got_target.pop(0)
        # Get target_id out of target dictionary        
        target_id = got_target['target_id']
        return target_id
Example #3
0
    def get_target_data(self, exp_uid, index):
        """
        Get an individual targets metadata given that targets index.

        Inputs: 
            (string) exp_uid, index
        Outputs:
            (dict) target_data

        Usage: ::\n
        didSucceed = targetmapper.init_empty_target_mapping(exp_uid, n)
        """
        target_data,didSucceed,message = db.getDocsByPattern(self.database_id, self.bucket_id, {'exp_uid': exp_uid, 'targetless': False})
        # Pass back message if getDocsByPattern fails
        if not didSucceed:
            raise DatabaseException("Failed to get_target_data: %s"%(message))
        # This line is key. If no doc exists with the specified exp_uid and targetless = True, then targetless = False
        if not target_data:
            return {'target_id':index,
                    'primary_description':index,
                    'primary_type':'text',
                    'alt_description':index,
                    'alt_type':'text'}
        # Get an individual target form the DB given exp_uid and index
        target_data,didSucceed,message = db.getDocsByPattern(self.database_id, self.bucket_id, {'exp_uid': exp_uid, 'index':index})
        # If doc cannot be retreived, throw an error
        if not didSucceed:
            raise DatabaseException("Failed to get_target_data: %s"%(message))
        # Pop target_dict out of list and return
        target_data_dict = target_data.pop(0)
        return target_data_dict
Example #4
0
    def get_exp_key(self, site_id, site_key, exp_uid):
        """
        Get the key associated to an experiment. Verifies the site and that the experiment belongs to this site.
        
        Inputs: 
            (string) site_id, (string) site_key, (string) exp_uid

        Outputs:
            (string) exp_key

        Usage: ::\n
        exp_key = keychain.get_exp_key(site_id, site_key, exp_uid)
        """
        #Verify that these are proper credentials for this site
        if not self.verify_site_key(site_id, site_key):
            return "Invalid Credentials"

        # Verify that the experiment actually belongs to this site
        if not self.verify_site_exp_ownership(site_id, exp_uid):
            return "This experiment does not belong to this site or does not exist."

        docs, didSucceed, message = db.getDocsByPattern(
            self.database_id, self.bucket_id, {'object_id': exp_uid})
        if not didSucceed:
            raise DatabaseException(
                "Failed to access database in the keychain. %s" % (message))
        return docs[0]["_id"]
Example #5
0
    def create_perm_key(self, exp_uid, exp_key):
        """
        Create a permanent key associated to an experiment for a widget. Verifies the experiment id and key. 
        
        
        Inputs: 
           (string) exp_uid, (string) exp_key

        Outputs:
            (string) perm_key

        Usage: ::\n
        perm_key = keychain.get_perm_key(exp_uid, exp_key)
        """
        #Verify that these are proper credentials for this experiment
        if not self.verify_site_key(exp_uid, exp_key):
            return "Invalid Credentials"

        perm_key = '%030x' % random.randrange(16**30)

        doc = {'object_id': exp_uid, 'type': 'perm', 'duration': 0, 'tries': 0}
        didSucceed, message = db.setDoc(self.database_id, self.bucket_id,
                                        perm_key, doc)
        if not didSucceed:
            raise DatabaseException(
                "Failed to access database in the keychain. %s" % (message))
        return perm_key
Example #6
0
    def get_perm_key(self, exp_uid, exp_key):
        """
        Get a permanent key associated to an experiment for a widget. Verifies the experiment id and key. 
        
        
        Inputs: 
           (string) exp_uid, (string) exp_key

        Outputs:
            (string) perm_key

        Usage: ::\n
        perm_key = keychain.get_perm_key(exp_uid, exp_key)
        """

        #Verify that these are proper credentials for this experiment
        if not self.verify_exp_key(exp_uid, exp_key):
            return "Invalid Credentials"

        docs, didSucceed, message = db.getDocsByPattern(
            self.database_id, self.bucket_id, {
                'object_id': exp_uid,
                'type': 'perm'
            })
        if not didSucceed:
            raise DatabaseException(
                "Failed to access database in the keychain. %s" % (message))

        return docs[0]["_id"]
Example #7
0
    def create_exp_key(self, site_id, site_key, exp_uid):
        """
        Create an experiment key given a site_key. Verifies the site and that the experiment belongs to this site. 

        Inputs: 
            (string) site_id, (string) site_key, (string) exp_uid

        Outputs:
            (string) exp_key

        Usage: ::\n
        exp_key = keychain.create_exp_key(site_id, site_key, exp_uid)
        """

        # Verify that these are proper credentials for this site
        if not self.verify_site_key(site_id, site_key):
            return "Invalid credentials"

        # Verify that the experiment actually belongs to this site
        if not self.verify_site_exp_ownership(site_id, exp_uid):
            return "This experiment does not belong to this site or does not exist."

        exp_key = '%030x' % random.randrange(16**30)
        doc = {'object_id': exp_uid, 'type': 'exp', 'duration': 0, 'tries': 0}
        didSucceed, message = db.setDoc(self.database_id, self.bucket_id,
                                        exp_key, doc)

        if not didSucceed:
            raise DatabaseException(
                "Failed to access database in the keychain. %s" % (message))
        return exp_key
Example #8
0
    def get_target_mapping(self, exp_uid):
        """
        Get the full target mapping. This be useful for pages that want to show/load the entire target set.

        Inputs: 
            (string) exp_uid
        Outputs:
            (boolean) target_data

        Usage: ::\n
        didSucceed = targetmapper.init_empty_target_mapping(exp_uid, n)
        """
        # Get all docs for specified exp_uid
        mongotized_target_blob,didSucceed,message = db.getDocsByPattern(self.database_id, self.bucket_id, {'exp_uid': exp_uid})
        # If no docs with exp_uid can be retreived, throw an error
        if not didSucceed:
            raise DatabaseException("Failed to get_target_mapping: %s"%(message))
        # Pop target_blob_dict out of list
        for i in range(len(mongotized_target_blob)):
            if 'targetless' in mongotized_target_blob[i].keys():
                mongotized_target_blob.pop(i)
                break
        
        target_blob_dict = mongotized_target_blob
        return target_blob_dict
Example #9
0
    def get_exp_key(self, exp_uid):
        """
        Get the key associated to an experiment.
        
        Inputs: 
            (string) exp_uid

        Outputs:
            (string) exp_key

        Usage: ::\n
        exp_key = keychain.get_exp_key(exp_uid)
        """
        docs, didSucceed, message = db.getDocsByPattern(
            self.database_id, self.bucket_id, {'object_id': exp_uid})
        if not didSucceed:
            raise DatabaseException(
                "Failed to access database in the keychain. %s" % (message))
        return docs[0]["_id"]
Example #10
0
    def create_exp_key(self, exp_uid):
        """
        Create an experiment key given a site_key. Verifies the site and that the experiment belongs to this site. 

        Inputs: 
            (string) exp_uid

        Outputs:
            (string) exp_key

        Usage: ::\n
        exp_key = keychain.create_exp_key(exp_uid)
        """
        exp_key = '%030x' % random.randrange(16**30)
        doc = {'object_id': exp_uid, 'type': 'exp', 'duration': 0, 'tries': 0}
        didSucceed, message = db.setDoc(self.database_id, self.bucket_id,
                                        exp_key, doc)

        if not didSucceed:
            raise DatabaseException(
                "Failed to access database in the keychain. %s" % (message))
        return exp_key
Example #11
0
    def verify_exp_key(self, exp_uid, exp_key):
        """
        Verify a key belongs to an experiment. 

        Inputs:
	    (string) exp_key, (string) exp_uid

        Outputs:
            (bool)

        Usage: ::\n
        	if not verify_exp_key(exp_uid, exp_key):
            		return "Invalid Credentials"

        """
        value, didSucceed, message = db.get(self.database_id, self.bucket_id,
                                            exp_key, 'object_id')
        if not didSucceed:
            raise DatabaseException(
                "Failed to access database in the keychain. %s" % (message))
        if value == exp_uid:
            return True
        return False
Example #12
0
    def verify_site_exp_ownership(self, site_id, exp_uid):
        """
        Verify that a site owns an experiment.

        Inputs: 
        	(string) client_id, (string) site_id
        
        Outputs:
        	(bool)
        
        Usage: ::\n
        	keychain.verify_client_site_ownership(client_id, site_id)
        """
        # Verify that the experiment actually belongs to this site
        value, didSucceed, message = db.get(self.database_id, "experiments",
                                            exp_uid, "site_id")
        if not didSucceed:
            raise DatabaseException(
                "Failed to access database in the keychain. %s" % (message))

        if value == site_id:
            return True
        return False
Example #13
0
    def create_temp_keys(self, exp_uid, exp_key, n=1, tries=100, duration=60):
        """
        Create temporary keys for widget access. Verifies the exp key and uid. 

        A number of tires and a duration(minutes) can be specified.
        
        Inputs: 
           (string) exp_uid, (string) exp_key, (int) tries (default 1), (int) duration (default 60)

        Outputs:
            (string) temp_key

        Usage: ::\n
        perm_key = keychain.get_temp_key(exp_uid, exp_key, tries=5, duration=10)
        """

        #Verify that these are proper credentials for this experiment
        if not self.verify_site_key(exp_uid, exp_key):
            return "Invalid Credentials"

        temp_keys = []
        for i in range(n):
            temp_key = '%030x' % random.randrange(16**30)
            doc = {
                'object_id': exp_uid,
                'type': 'temp',
                'duration': duration,
                'tries': 2 * tries
            }
            didSucceed, message = db.setDoc(self.database_id, self.bucket_id,
                                            temp_key, doc)
            temp_keys.append(temp_key)
            if not didSucceed:
                raise DatabaseException(
                    "Failed to access database in the keychain. %s" %
                    (message))
        return temp_keys
Example #14
0
    def create_site_key(self, site_id):
        """
        Create a site key. 

        Inputs: 
            (string) site_id

        Outputs:
            (string) site_key

        Usage: ::\n
        site_key = keychain.create_site_key(site_id)
        """

        site_key = '%030x' % random.randrange(16**30)
        doc = {'object_id': site_id, 'type': 'site', 'duration': 0, 'tries': 0}

        didSucceed, message = db.setDoc(self.database_id, self.bucket_id,
                                        site_key, doc)
        if not didSucceed:
            raise DatabaseException(
                "Failed to access database in the keychain. %s" % (message))

        return site_key
Example #15
0
    def verify_widget_key(self, exp_uid, key):
        """
        Verify a widget key belongs to an experiment. 
        
        If the key is permanent, it is just verified. 

        If the key is temporary, the number of tries is decreased by 1, and the "access_time" is adjusted. If this causes the key to expire, the key is deleted from the database.
        
        Inputs:
        	(string) key, (string) exp_uid

        Outputs:
        	(bool)

        Usage: ::\n
        	if not verify_exp_key(exp_uid, key):
            		return "Invalid Credentials"

        """

        doc, didSucceed, message = db.getDoc(self.database_id, self.bucket_id,
                                             key)
        print "keychain.py/verify_widget_key", doc

        if not didSucceed:
            raise DatabaseException(
                "Failed to access database in the keychain. %s" % (message))
        hasTries = False
        hasTime = False

        print "tries", doc["tries"]

        if doc['object_id'] == exp_uid:
            if doc['type'] == 'perm':
                return True
            elif doc['type'] == 'temp':
                curr_time = time.time()
                if doc['tries'] > 0:
                    hasTries = True

                if 'start_time' in doc.keys() and doc['duration'] > 0:
                    if curr_time - doc[
                            'last_access_time'] < 60000 * doc['duration']:
                        hasTime = True
                    else:
                        hasTime = False
                elif doc['duration'] > 0:
                    didSucceed, message = db.set(self.database_id,
                                                 self.bucket_id, key,
                                                 'start_time', curr_time)
                    if not didSucceed:
                        raise DatabaseException(
                            "Failed to access database in the keychain. %s" %
                            (message))
                    hasTime = True

                # Update the key if we have tries and time left
                if hasTries and hasTime:
                    if doc['tries'] <= 0:
                        return False
                        #db.delete(self.database_id, self.bucket_id, key)
                    else:
                        didSucceed, message = db.set(self.database_id,
                                                     self.bucket_id, key,
                                                     'tries', doc['tries'] - 1)
                        if not didSucceed:
                            raise DatabaseException(
                                "Failed to access database in the keychain. %s"
                                % (message))
                        didSucceed, message = db.set(self.database_id,
                                                     self.bucket_id, key,
                                                     'last_access_time',
                                                     curr_time)
                        if not didSucceed:
                            raise DatabaseException(
                                "Failed to access database in the keychain. %s"
                                % (message))
                        return True
                # This key is stale. It should be deleted.
                else:
                    #db.delete(self.database_id, self.bucket_id, key)
                    return False
        return False
Example #16
0
    def create_target_mapping(self, exp_uid, target_blob):
        """
        Update the default target docs in the DB if a user uploads a target set.
        Target_blob should be a list of targets, with each individual target having the following format. All feilds are REQUIRED.
            target_id: a unique target identifier init by the client
            index: the next_backend target object index
            primary_description (possibly image URI, or text)
            primary_type (img/text/audio/etc, tells how to display primary_description in widget)
            alternative_description (text descriptor, perhaps a caption for the image or subtitle for primary_description)
            features (list of floats, this will also be saved in the backend but its best to save this here as well I think. disk space is effectively infinite)

        Inputs: 
            (string) exp_uid, (list) target_blob
        Outputs:
            (boolean) didSucceed

        Usage: ::\n
        didSucceed = targetmapper.create_target_mapping(exp_uid, target_blob)
        {'target_id': superhappy, 'index': 23, 'primary_description': s3.com/superhappy, 'primary_type': img, 'alt_description': a super happy person, 'features': features}
        """
        #Verify that target_blob object has valid target mapping format
        #if not self.verify_target_map_format(exp_uid, target_blob):
        #    print "Invalid TargetMap Format. Please check your target upload CSV file and include all of the required feilds."
        #    return "Invalid TargetMap Format. Please check your target upload CSV file and include all of the required feilds."

        # Delete target doc indicating targetless initialization
        didSucceed,message = db.deleteDocsByPattern(self.database_id,self.bucket_id,{'exp_uid': exp_uid, 'targetless': True})
        if not didSucceed:
            raise DatabaseException("Failed to create_target_mapping: %s"%(message))
        # Recreate target document to denote target mapping has been created
        doc = {'targetless': False, 'exp_uid': exp_uid}
        didSucceed, message = db.setDoc(self.database_id, self.bucket_id, None, doc)
        if not didSucceed:
            raise DatabaseException("Failed to create_target_mapping: %s"%(message))

        # Iteratively initilize target documents and insert into MongoDB
        for ii in range(len(target_blob)):
            # Parse target specific args out of target_blob at index ii
            target_tmp = target_blob[ii]
            target_id = target_tmp['target_id']
            index = ii
            primary_description = target_tmp['primary_description']            
            primary_type = target_tmp['primary_type']
            alt_type = target_tmp['alt_type']
            alt_description = target_tmp['alt_description']
            # Structure target document for MongoDB
            doc = {'index': index,
                   'target_id': target_id,
                   'primary_description': primary_description,
                   'primary_type': primary_type,
                   'alt_description': alt_description,
                   'alt_type': alt_type,
                   'exp_uid': exp_uid}
            didSucceed, message = db.setDoc(self.database_id, self.bucket_id, None, doc)

            # If target not successfully created, throw an error
            if not didSucceed:
                raise DatabaseException("Failed to create_target_mapping: %s"%(message))
             
        # Get all docs related to the specified exp_uid
        mongotized_target_blob,didSucceed,message = db.getDocsByPattern(self.database_id, self.bucket_id, {'exp_uid': exp_uid})
        
        # If the newly initialized DB docs can't be found, throw an error
        if not didSucceed:
            raise DatabaseException("Failed to create_target_mapping: %s"%(message))
        # Pop target_dict out of list
        target_blob_dict = mongotized_target_blob.pop(0)

        # Return target_blob_dict of all targets corresponding to current exp_uid
        return target_blob_dict