def record_pha_setup(request, record, pha):
  """Set up a PHA in a record ahead of time

  FIXME: eventually, when there are permission restrictions on a PHA, make sure that
  any permission restrictions on the current PHA are transitioned accordingly
  """

  content = request.raw_post_data

  # if there is a document, create it
  if content:
    # is there already a setup doc
    setup_docs = Document.objects.filter(record=record, pha=pha, external_id='SETUP')
    if len(setup_docs) == 0:
      new_doc = _document_create( record      = record,
                                  creator     = request.principal,
                                  pha         = pha,
                                  content     = content,
                                  external_id = Document.prepare_external_id('SETUP', pha, pha_specific=True, record_specific=True))

  # preauthorize the token.
  from indivo.accesscontrol.oauth_servers import OAUTH_SERVER
  access_token = OAUTH_SERVER.generate_and_preauthorize_access_token(pha, record=record)

  # return the token
  return HttpResponse(access_token.to_string(), mimetype="application/x-www-form-urlencoded")
Exemple #2
0
def record_pha_setup(request, record, pha):
    """ Bind an app to a record without user authorization.

  This call should be used to set up new records with apps required
  for this instance of Indivo to run (i.e. syncer apps that connect to 
  data sources). It can only be made by admins, since it skips the
  normal app authorization process.

  ``request.POST`` may contain raw content that will be used
  as a setup document for the record.

  Will return :http:statuscode:`200` with a valid access token for the
  app bound to the record on success.
  
  """

    # TODO: eventually, when there are permission restrictions on a PHA,
    # make sure that any permission restrictions on the current PHA are
    # transitioned accordingly.

    content = request.raw_post_data

    # if there is a document, create it
    if content:
        # is there already a setup doc
        setup_docs = Document.objects.filter(record=record,
                                             pha=pha,
                                             external_id='SETUP')
        if len(setup_docs) == 0:
            new_doc = _document_create(
                record=record,
                creator=request.principal,
                pha=pha,
                content=content,
                external_id=Document.prepare_external_id('SETUP',
                                                         pha,
                                                         pha_specific=True,
                                                         record_specific=True))

    # preauthorize the token.
    from indivo.accesscontrol.oauth_servers import OAUTH_SERVER
    access_token = OAUTH_SERVER.generate_and_preauthorize_access_token(
        pha, record=record)

    # return the token
    return HttpResponse(access_token.to_string(),
                        mimetype="application/x-www-form-urlencoded")
Exemple #3
0
def autonomous_access_token(request, pha, record):
    """ Fetch an access token for an autonomous app to access a record.

    This call *assumes* that the app has already been enabled on the record, and 
    that the user has already authorized it (this must be checked in the access control 
    for the function). Otherwise, this will automatically enable the app on the record
    (a BAD idea).

    This call should be made by autonomous apps to get access tokens for records which
    have already enabled them (presumably after a call to app_record_list).

    Will return :http:statuscode:`200` with a valid access token for the app bound to the
    record on success.
   
    """

    from indivo.accesscontrol.oauth_servers import OAUTH_SERVER
    access_token = OAUTH_SERVER.generate_and_preauthorize_access_token(pha, record=record)
    return HttpResponse(access_token.to_string(), mimetype="application/x-www-form-urlencoded")
Exemple #4
0
def record_pha_setup(request, record, pha):
    """ Bind an app to a record without user authorization.

  This call should be used to set up new records with apps required
  for this instance of Indivo to run (i.e. syncer apps that connect to 
  data sources). It can only be made by admins, since it skips the
  normal app authorization process.

  ``request.POST`` may contain raw content that will be used
  as a setup document for the record.

  Will return :http:statuscode:`200` with a valid access token for the
  app bound to the record on success.
  
  """

    # TODO: eventually, when there are permission restrictions on a PHA,
    # make sure that any permission restrictions on the current PHA are
    # transitioned accordingly.

    content = request.raw_post_data

    # if there is a document, create it
    if content:
        # is there already a setup doc
        setup_docs = Document.objects.filter(record=record, pha=pha, external_id="SETUP")
        if len(setup_docs) == 0:
            new_doc = _document_create(
                record=record,
                creator=request.principal,
                pha=pha,
                content=content,
                external_id=Document.prepare_external_id("SETUP", pha, pha_specific=True, record_specific=True),
            )

    # preauthorize the token.
    from indivo.accesscontrol.oauth_servers import OAUTH_SERVER

    access_token = OAUTH_SERVER.generate_and_preauthorize_access_token(pha, record=record)

    # return the token
    return HttpResponse(access_token.to_string(), mimetype="application/x-www-form-urlencoded")
Exemple #5
0
def autonomous_access_token(request, pha, record):
    """ Fetch an access token for an autonomous app to access a record.

    This call *assumes* that the app has already been enabled on the record, and 
    that the user has already authorized it (this must be checked in the access control 
    for the function). Otherwise, this will automatically enable the app on the record
    (a BAD idea).

    This call should be made by autonomous apps to get access tokens for records which
    have already enabled them (presumably after a call to app_record_list).

    Will return :http:statuscode:`200` with a valid access token for the app bound to the
    record on success.
   
    """

    from indivo.accesscontrol.oauth_servers import OAUTH_SERVER
    access_token = OAUTH_SERVER.generate_and_preauthorize_access_token(
        pha, record=record)
    return HttpResponse(access_token.to_string(),
                        mimetype="application/x-www-form-urlencoded")
Exemple #6
0
def get_connect_credentials(request, account, pha):
    """ Get oAuth credentials for an app to run in Connect or SMART REST mode.

    Generates access tokens for *pha* to run against the *record_id* specified in ``request.POST``, authorized by
    *account*. Generates 2 tokens: one for SMART Connect use, and one for SMART REST use.

    If the app is not yet enabled for the record/carenet, this will return a :http:statuscode:`403`.
    
    """

    carenet = record = None
    carenet_id = request.POST.get('carenet_id', None)
    record_id = request.POST.get('record_id', None)

    if carenet_id:
        try:
            carenet = Carenet.objects.get(id=carenet_id)
        except Carenet.DoesNotExist:
            raise Http404
        except Carenet.MultipleObjectsReturned:
            raise Exception(
                "Multiple carenets with same id--database is corrupt")

    elif record_id:
        try:
            record = Record.objects.get(id=record_id)
        except Record.DoesNotExist:
            raise Http404
        except Record.MultipleObjectsReturned:
            raise Exception(
                "Multiple records with same id--database is corrupt")

    # Make sure that the app is enabled
    if (record and not PHAShare.objects.filter(record=record, with_pha=pha).exists()) or \
            (carenet and not CarenetPHA.objects.filter(carenet=carenet, pha=pha).exists()):
        raise PermissionDenied(
            "Cannot generate credentials before app is enabled")

    # Generate the tokens
    from indivo.accesscontrol.oauth_servers import OAUTH_SERVER
    rest_token = OAUTH_SERVER.generate_and_preauthorize_access_token(
        pha, record=record, carenet=carenet, account=account)
    connect_token = OAUTH_SERVER.generate_and_preauthorize_access_token(
        pha, record=record, carenet=carenet, account=account)
    connect_token.connect_auth_p = True
    connect_token.save()

    # Generate a 2-legged oauth header for the rest token, based on the pha's start_url
    url = utils.url_interpolate(pha.start_url_template, {
        'record_id': record_id or '',
        'carenet_id': carenet_id or ''
    })
    request = HTTPRequest("GET", url, HTTPRequest.FORM_URLENCODED_TYPE, '', {})
    oauth_params = {
        'smart_container_api_base': settings.SITE_URL_PREFIX,
        'smart_oauth_token': rest_token.token,
        'smart_oauth_token_secret': rest_token.token_secret,
        'smart_user_id': account.email,
        'smart_app_id': pha.email,
        'smart_record_id': record_id,
    }
    oauth_request = OAuthRequest(
        consumer=pha,
        token=None,  # no access tokens: 2-legged request
        http_request=request,
        oauth_parameters=oauth_params)
    oauth_request.sign()
    auth_header = oauth_request.to_header()["Authorization"]

    return render_template('connect_credentials', {
        'connect_token': connect_token,
        'rest_token': rest_token,
        'api_base': settings.SITE_URL_PREFIX,
        'oauth_header': auth_header,
        'app_email': pha.email
    },
                           type='xml')
Exemple #7
0
def get_connect_credentials(request, account, pha):
    """ Get oAuth credentials for an app to run in Connect or SMART REST mode.

    Generates access tokens for *pha* to run against the *record_id* specified in ``request.POST``, authorized by
    *account*. Generates 2 tokens: one for SMART Connect use, and one for SMART REST use.

    If the app is not yet enabled for the record/carenet, this will return a :http:statuscode:`403`.
    
    """

    carenet = record = None
    carenet_id = request.POST.get('carenet_id', None)
    record_id = request.POST.get('record_id', None)

    if carenet_id:
        try:
            carenet=Carenet.objects.get(id=carenet_id)
        except Carenet.DoesNotExist:
            raise Http404
        except Carenet.MultipleObjectsReturned:
            raise Exception("Multiple carenets with same id--database is corrupt")

    elif record_id:
        try:
            record = Record.objects.get(id=record_id)
        except Record.DoesNotExist:
            raise Http404
        except Record.MultipleObjectsReturned:
            raise Exception("Multiple records with same id--database is corrupt")

    # Make sure that the app is enabled
    if (record and not PHAShare.objects.filter(record=record, with_pha=pha).exists()) or \
            (carenet and not CarenetPHA.objects.filter(carenet=carenet, pha=pha).exists()):
        raise PermissionDenied("Cannot generate credentials before app is enabled")

    # Generate the tokens
    from indivo.accesscontrol.oauth_servers import OAUTH_SERVER
    rest_token = OAUTH_SERVER.generate_and_preauthorize_access_token(pha, record=record, 
                                                                     carenet=carenet, account=account)
    connect_token = OAUTH_SERVER.generate_and_preauthorize_access_token(pha, record=record, 
                                                                        carenet=carenet, account=account)
    connect_token.connect_auth_p = True
    connect_token.save()

    # Generate a 2-legged oauth header for the rest token, based on the pha's start_url
    url = utils.url_interpolate(pha.start_url_template, {'record_id':record_id or '', 'carenet_id':carenet_id or ''})
    request = HTTPRequest("GET", url, HTTPRequest.FORM_URLENCODED_TYPE, '', {})
    oauth_params = {
        'smart_container_api_base': settings.SITE_URL_PREFIX,
        'smart_oauth_token': rest_token.token,
        'smart_oauth_token_secret': rest_token.token_secret,
        'smart_user_id': account.email,
        'smart_app_id': pha.email,
        'smart_record_id': record_id,
        }
    oauth_request = OAuthRequest(consumer=pha,
                                 token=None, # no access tokens: 2-legged request
                                 http_request=request,
                                 oauth_parameters=oauth_params)
    oauth_request.sign()
    auth_header = oauth_request.to_header()["Authorization"]

    return render_template('connect_credentials', 
                           { 'connect_token': connect_token,
                             'rest_token': rest_token,
                             'api_base': settings.SITE_URL_PREFIX,
                             'oauth_header': auth_header,
                             'app_email':pha.email}, 
                           type='xml')