Example #1
0
def loadDeployment(deploymentData):
    """Returns a Deployment object for the given data"""
    #check that the deploymentData is valid
    if not ("deploymentId" in deploymentData and type(deploymentData["deploymentId"])==str and len(deploymentData["deploymentId"])>0):
        raise errors.BadRequestError("Deployment must have attribute 'deploymentId' (type=str and length>0)")
    if not ("name" in deploymentData and type(deploymentData["name"])==str and len(deploymentData["name"])>0):
        raise errors.BadRequestError("Deployment must have attribute 'name' (type=str and length>0)")
    if not ("status" in deploymentData and type(deploymentData["status"])==str and len(deploymentData["status"])>0):
        raise errors.BadRequestError("Deployment must have attribute 'status' (type=str and length>0)")
    if not ("dateCreated" in deploymentData and type(deploymentData["dateCreated"])==str and len(deploymentData["dateCreated"])>0):
        raise errors.BadRequestError("Deployment must have attribute 'dateCreated' (type=str and length>0)")
    if not ("dateModified" in deploymentData and type(deploymentData["dateModified"])==str and len(deploymentData["dateModified"])>0):
        raise errors.BadRequestError("Deployment must have attribute 'dateCreated' (type=str and length>0)")
    if not ("archived" in deploymentData and type(deploymentData["archived"])==bool):
        raise errors.BadRequestError("Deployment must have attribute 'archived' (type=bool)")
    if not ("goalSampleSize" in deploymentData and type(deploymentData["goalSampleSize"]) in [int, Decimal] and deploymentData["goalSampleSize"]>0):
        raise errors.BadRequestError("Deployment must have attribute 'goalSampleSize' (type=int and value>0)")
    if not ("currentSampleSize" in deploymentData and type(deploymentData["currentSampleSize"]) in [int, Decimal] and deploymentData["currentSampleSize"]>=0):
        raise errors.BadRequestError("Deployment must have attribute 'currentSampleSize' (type=int and value>=0)")
    if not ("facility" in deploymentData and type(deploymentData["facility"]) in [str, dict] and len(deploymentData["facility"])>0):
        raise errors.BadRequestError("Deployment must have attribute 'facility' (type=str or dict and length>0)")
    #construct the deployment
    d = Deployment()
    d.deploymentId = deploymentData["deploymentId"]
    d.name = deploymentData["name"]
    if "description" in deploymentData:
        d.description = deploymentData["description"]
    d.status = deploymentData["status"]
    d.dateCreated = deploymentData["dateCreated"]
    d.dateModified = deploymentData["dateModified"]
    d.archived = deploymentData["archived"]
    d.goalSampleSize = int(deploymentData["goalSampleSize"])
    d.currentSampleSize = int(deploymentData["currentSampleSize"])
    d.facility = facility_db_access.loadFacility(deploymentData["facility"])
    return d
Example #2
0
  def _process_request_body(self):
    """Parse the request body."""
    try:
      request = json.loads(self.request.body)

      self._code = request.get('code')
      if not self._code:
        raise errors.BadRequestError('`code` attribute is required')

      self._timezone_offset = request.get(
          'timezoneOffset', DEFAULT_TIMEZONE_OFFSET)
    except ValueError:
      raise errors.BadRequestError('Unsupported request body')
def createDeploymentForStudy(studyId, deployment):
    s = getStudy(studyId)
    if not (s.status in ["DESIGNED", "DEPLOYED", "PAUSED"]):
        raise errors.BadRequestError(
            "Deployments can only be created for DESIGNED, DEPLOYED, and PAUSED studies"
        )
    if not facility_db_access.facilityContainsAllEquipment(
            deployment.facility, s.equipmentList):
        raise errors.BadRequestError(
            "Deployment 'facility' must have all of the equpiment required by its Study"
        )
    s.deploymentList.append(deployment)
    s.modifyDate()
    StudyTable.put_item(Item=s.toDynamo())
    return deployment
def downloadFile(studyId, fileName):
    study = study_db_access.getStudy(studyId)
    if fileName not in study.resourceList:
        raise errors.BadRequestError("No file named " +fileName+ " for study " + studyId)
    key = studyId+fileName
    file = s3.get_object(Bucket=BUCKET_NAME, Key=key)
    return file
Example #5
0
 def _get_user(self):
   userid = util.verify_token(self.request.headers.get('Authorization'))
   if not userid:
     raise errors.BadRequestError('Unknown client ID')
   self._user = UserSettings.get_by_key_name(userid)
   if not self._user:
     raise errors.NotFoundError('Unknown user')
Example #6
0
def createDeployment(studyId, deploymentData):
    #check that deploymentData is valid
    if not ("name" in deploymentData and type(deploymentData["name"])==str and len(deploymentData["name"])>0):
        raise errors.BadRequestError("Deployment must have attribute 'name' (type=str and length>0)")
    if not ("goalSampleSize" in deploymentData and type(deploymentData["goalSampleSize"]) in [int, Decimal] and deploymentData["goalSampleSize"]>0):
        raise errors.BadRequestError("Deployment must have attribute 'goalSampleSize' (type=int and value>0)")
    if not ("facility" in deploymentData and type(deploymentData["facility"]) in [str, dict] and len(deploymentData["facility"])>0):
        raise errors.BadRequestError("Deployment must have attribute 'facility' (type=str or dict and length>0)")
    #construct the deployment
    d = Deployment()
    d.name = deploymentData["name"]
    if "description" in deploymentData:
        d.description = deploymentData["description"]
    d.goalSampleSize = int(deploymentData["goalSampleSize"])
    d.facility = facility_db_access.loadFacility(deploymentData["facility"])
    #create the deployment (by updating its parent study)
    return study_db_access.createDeploymentForStudy(studyId, d)
Example #7
0
def createPermissionForStudy(studyId):
    validateUser(studyId)
    permissionData = request.get_json()
    if not ("userId" in permissionData and type(permissionData["userId"])==str and len(permissionData["userId"])>0):
        raise errors.BadRequestError("Permission must have attribute 'userId' (type=str and length>0)")
    userId = permissionData["userId"]
    userPermission = permission_db_access.createAdminForStudy(userId, studyId)
    return toJson(userPermission)
def updateStudy(studyId, studyData):
    oldStudy = getStudy(studyId)
    newStudy = loadStudy(studyData)
    #check that the study can be updated
    if not (oldStudy.studyId == newStudy.studyId):
        raise errors.BadRequestError(
            "studyId of the study to be updated must mach the studyId of the endpoint"
        )
    if not (oldStudy.dateModified == newStudy.dateModified):
        raise errors.BadRequestError(
            "dateModifed on the study to be updated does not match the dateModified in the database."
        )
    if not (newStudy.status
            in ["CREATED", "DESIGNED", "DEPLOYED", "PAUSED", "TERMINATED"]):
        raise errors.BadRequestError(
            "status must be CREATED, DESIGNED, DEPLOYED, PAUSED, or TERMINATED"
        )
    #The archived flag can always be updated regardless of status
    oldStudy.archived = newStudy.archived
    if (oldStudy.status == "CREATED"):
        if not (newStudy.status in ["CREATED", "DESIGNED", "TERMINATED"]):
            raise errors.BadRequestError(
                "status of a CREATED study can only be updated to DESIGNED or TERMINATED"
            )
        oldStudy.name = newStudy.name
        oldStudy.description = newStudy.description
        oldStudy.equipmentList = newStudy.equipmentList
        oldStudy.resourceList = newStudy.resourceList
    if (oldStudy.status == "DESIGNED"):
        if not (newStudy.status in ["DESIGNED", "DEPLOYED", "TERMINATED"]):
            raise errors.BadRequestError(
                "status of a DESIGNED study can only be updated to DEPLOYED or TERMINATED"
            )
    if (oldStudy.status == "DEPLOYED"):
        if not (newStudy.status in ["DEPLOYED", "PAUSED", "TERMINATED"]):
            raise errors.BadRequestError(
                "status of a DEPLOYED study can only be updated to PAUSED or TERMINATED"
            )
    if (oldStudy.status == "PAUSED"):
        if not (newStudy.status in ["DEPLOYED", "PAUSED", "TERMINATED"]):
            raise errors.BadRequestError(
                "status of a PAUSED study can only be updated to DEPLOYED or TERMINATED"
            )
    if (oldStudy.status == "TERMINATED"):
        if not (newStudy.status == "TERMINATED"):
            raise errors.BadRequestError(
                "Cannot change the status of a TERMINATED study")
    if (newStudy.status == "TERMINATED"):
        for d in oldStudy.deploymentList:
            if not d.status == "TERMINATED":
                d.status = "TERMINATED"
                d.modifyDate()
    oldStudy.status = newStudy.status
    oldStudy.modifyDate()
    StudyTable.put_item(Item=oldStudy.toDynamo())
    return oldStudy
def uploadFile(studyId, file):
    study = study_db_access.getStudy(studyId)
    if not study.status == "CREATED":
        raise errors.BadRequestError("Files can only uploaded for CREATED studies")
    fileName =file.filename
    key = studyId+fileName
    s3.upload_fileobj(file, BUCKET_NAME, key)
    study.resourceList.append(fileName)
    study_db_access.updateStudy(studyId, study.toDynamo())
    return fileName
Example #10
0
 def _process_request_body(self):
   """Parse the request body."""
   try:
     data = json.loads(self.request.body)
     self._user.night_mode = data.get('nightMode', self._user.night_mode)
     self._user.frequency = data.get('frequency', self._user.frequency)
     self._user.timezone_offset = data.get(
         'timezoneOffset', self._user.timezone_offset)
     self._user.put()
   except ValueError:
     raise errors.BadRequestError('Unsupported request body')
def updateDeploymentForStudy(studyId, deployment):
    s = getStudy(studyId)
    if not (s.status in ["DESIGNED", "DEPLOYED", "PAUSED"]):
        raise errors.BadRequestError(
            "Deployments can only be updated for DESIGNED, DEPLOYED, and PAUSED studies"
        )
    if not facility_db_access.facilityContainsAllEquipment(
            deployment.facility, s.equipmentList):
        raise errors.BadRequestError(
            "Deployment 'facility' must have all of the equpiment required by its Study"
        )
    allDeploymentsArePausedOrTerminated = True
    for i in range(len(s.deploymentList)):
        if s.deploymentList[i].deploymentId == deployment.deploymentId:
            s.deploymentList[i] = deployment
        if s.deploymentList[i].status not in ["PAUSED", "TERMINATED"]:
            allDeploymentsArePausedOrTerminated = False
    if allDeploymentsArePausedOrTerminated and s.status == "DEPLOYED":
        s.status = "PAUSED"
    s.modifyDate()
    StudyTable.put_item(Item=s.toDynamo())
    return deployment
Example #12
0
class OAuthCodeExchangeHandler(webapp2.RequestHandler):
  """Request handler for OAuth 2.0 code exchange."""

  @errors.error_aware
  def post(self):
    """Handle code exchange."""
    self._process_request_body()
    self._exchange_code()
    user = self._create_user()
    util.write_response(self, user.to_dict())

  def _process_request_body(self):
    """Parse the request body."""
    try:
      request = json.loads(self.request.body)

      self._code = request.get('code')
      if not self._code:
        raise errors.BadRequestError('`code` attribute is required')

      self._timezone_offset = request.get(
          'timezoneOffset', DEFAULT_TIMEZONE_OFFSET)
    except ValueError:
      raise errors.BadRequestError('Unsupported request body')

  def _exchange_code(self):
    """Retrieve credentials for the current user."""
    oauth_flow = self._create_oauth_flow()
    # Perform the exchange of the code.
    try:
      creds = oauth_flow.step2_exchange(self._code)
    except FlowExchangeError, e:
      raise errors.InternalServerError('Unable to exchange code: ', e.message)

    # Verify that the token has been issued for our application.
    self._userid = util.verify_token(creds.access_token)
    if not self._userid:
      raise errors.BadRequestError('Unknown client ID')

    # Verify that we can retrieve valid refresh token for the current user.
    if creds.refresh_token:
      # Store the credentials in the data store using the userid as the key.
      StorageByKeyName(
          model.UserSettings, self._userid, 'credentials').put(creds)
    else:
      # Look for existing credentials in our datastore.
      creds = StorageByKeyName(
          model.UserSettings, self._userid, 'credentials').get()
      if not creds or not creds.refresh_token:
        raise errors.UnauthorizedError('No refresh token')
    return creds
Example #13
0
def createEquipment(equipmentData):
    #check that equipmentData is valid
    if not ("name" in equipmentData and type(equipmentData["name"]) == str
            and len(equipmentData["name"]) > 0):
        raise errors.BadRequestError(
            "Equipment must have attribute 'name' (type=str and length>0)")
    #construct the equipment
    e = Equipment()
    e.name = equipmentData["name"]
    if "abbreviation" in equipmentData:
        e.abbreviation = equipmentData["abbreviation"]
    #create the equipment
    EquipmentTable.put_item(Item=e.toDynamo())
    return e
Example #14
0
def createFacility(facilityData):
    #check that facilityData is valid
    if not ("name" in deploymentData and type(deploymentData["name"]) == str
            and len(deploymentData["name"]) > 0):
        raise errors.BadRequestError(
            "Facility must have attribute 'name' (type=str and length>0)")
    #construct the facility
    f = Facility()
    f.name = facilityData["name"]
    if "equipmentList" in facilityData:
        f.equipmentList = equipment_db_access.loadEquipmentList(
            facilityData["equipmentList"])
    #create the facility
    FacilityTable.put_item(Item=f.toDynamo())
    return f
def createStudy(studyData):
    #check that the studyData is valid
    if not ("name" in studyData and type(studyData["name"]) == str
            and len(studyData["name"]) > 0):
        raise errors.BadRequestError(
            "Study must have attribute 'name' (type=str and length>0)")
    #construct the study
    s = Study()
    s.name = studyData["name"]
    if "description" in studyData:
        s.description = studyData["description"]
    if "equipmentList" in studyData:
        s.equipmentList = equipment_db_access.loadEquipmentList(
            studyData["equipmentList"])
    #create the study
    StudyTable.put_item(Item=s.toDynamo())
    return s
Example #16
0
def updateDeployment(studyId, deploymentId, deploymentData):
    oldDeployment = getDeployment(studyId, deploymentId)
    newDeployment = loadDeployment(deploymentData)
    #check that the deployment can be updated
    if not (oldDeployment.deploymentId==newDeployment.deploymentId):
        raise errors.BadRequestError("deploymentId of the deployment to be updated must mach the deploymentId of the endpoint")
    if not (oldDeployment.dateModified==newDeployment.dateModified):
        raise errors.BadRequestError("dateModifed on the deployment to be updated does not match the dateModified in the database.")
    if not (newDeployment.status in ["CREATED", "DESIGNED", "DEPLOYED", "PAUSED", "TERMINATED"]):
        raise errors.BadRequestError("status must be CREATED, DESIGNED, DEPLOYED, PAUSED, or TERMINATED")
    #The archived flag can always be updated regardless of status
    oldDeployment.archived = newDeployment.archived
    if (oldDeployment.status=="CREATED"):
        if not (newDeployment.status in ["CREATED", "DESIGNED", "TERMINATED"]):
            raise errors.BadRequestError("status of a CREATED deployment can only be updated to DESIGNED or TERMINATED")
        oldDeployment.name = newDeployment.name
        oldDeployment.description = newDeployment.description
        oldDeployment.goalSampleSize = newDeployment.goalSampleSize
        oldDeployment.facility = newDeployment.facility
    if (oldDeployment.status=="DESIGNED"):
        if not (newDeployment.status in ["DESIGNED", "DEPLOYED", "TERMINATED"]):
            raise errors.BadRequestError("status of a DESIGNED deployment can only be updated to DEPLOYED or TERMINATED")
    if (oldDeployment.status=="DEPLOYED"):
        if not (newDeployment.status in ["DEPLOYED", "PAUSED", "TERMINATED"]):
            raise errors.BadRequestError("status of a DEPLOYED deployment can only be updated to PAUSED or TERMINATED")
        if study_db_access.getStudy(studyId).status=="DEPLOYED":
            oldDeployment.currentSampleSize = newDeployment.currentSampleSize
    if (oldDeployment.status=="PAUSED"):
        if not (newDeployment.status in ["DEPLOYED", "PAUSED", "TERMINATED"]):
            raise errors.BadRequestError("status of a PAUSED study can only be updated to DEPLOYED or TERMINATED")
    if (oldDeployment.status=="TERMINATED"):
        if not (newDeployment.status=="TERMINATED"):
            raise errors.BadRequestError("Cannot change the status of a TERMINATED study")
    oldDeployment.status = newDeployment.status
    #if the goalSampleSize has been reached, automatically pause the deployment
    if (oldDeployment.currentSampleSize>=oldDeployment.goalSampleSize and oldDeployment.status not in ["PAUSED", "TERMINATED"]):
        oldDeployment.status = "PAUSED"
    oldDeployment.modifyDate()
    return study_db_access.updateDeploymentForStudy(studyId, oldDeployment)
def loadStudy(studyData):
    """Returns a Study object for the given data"""
    #check that the studyData is valid
    if not ("studyId" in studyData and type(studyData["studyId"]) == str
            and len(studyData["studyId"]) > 0):
        raise errors.BadRequestError(
            "Study must have attribute 'studyId' (type=str and length>0)")
    if not ("name" in studyData and type(studyData["name"]) == str
            and len(studyData["name"]) > 0):
        raise errors.BadRequestError(
            "Study must have attribute 'name' (type=str and length>0)")
    if not ("status" in studyData and type(studyData["status"]) == str
            and len(studyData["status"]) > 0):
        raise errors.BadRequestError(
            "Study must have attribute 'status' (type=str and length>0)")
    if not ("dateCreated" in studyData and type(studyData["dateCreated"])
            == str and len(studyData["dateCreated"]) > 0):
        raise errors.BadRequestError(
            "Study must have attribute 'dateCreated' (type=str and length>0)")
    if not ("dateModified" in studyData and type(studyData["dateModified"])
            == str and len(studyData["dateModified"]) > 0):
        raise errors.BadRequestError(
            "Study must have attribute 'dateModified' (type=str and length>0)")
    if not ("archived" in studyData and type(studyData["archived"]) == bool):
        raise errors.BadRequestError(
            "Study must have attribute 'archived' (type=bool)")
    #construct the study
    s = Study()
    s.studyId = studyData["studyId"]
    s.name = studyData["name"]
    if "description" in studyData:
        s.description = studyData["description"]
    s.status = studyData["status"]
    s.dateCreated = studyData["dateCreated"]
    s.dateModified = studyData["dateModified"]
    s.archived = studyData["archived"]
    if "deploymentList" in studyData:
        s.deploymentList = deployment_db_access.loadDeploymentList(
            studyData["deploymentList"])
    if "equipmentList" in studyData:
        s.equipmentList = equipment_db_access.loadEquipmentList(
            studyData["equipmentList"])
    if "resourceList" in studyData:
        s.resourceList = studyData["resourceList"]
    return s