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