Esempio n. 1
0
    def PUT(self, request, **kwargs):
        if not can_manage_external_tools():
            return self.json_response('{"error":"Unauthorized"}', status=401)

        canvas_id = kwargs['canvas_id']
        try:
            json_data = json.loads(request.body).get('external_tool', {})
            self.validate(json_data)
        except Exception as ex:
            logger.error('PUT ExternalTool error: %s' % ex)
            return self.json_response('{"error": "%s"}' % ex, status=400)

        try:
            external_tool = ExternalTool.objects.get(canvas_id=canvas_id)
            curr_data = external_tool.json_data()
            keystore = BLTIKeyStore.objects.get(
                consumer_key=curr_data['consumer_key'])
        except ExternalTool.DoesNotExist:
            return self.json_response(
                '{"error":"external_tool %s not found"}' % canvas_id,
                status=404)
        except BLTIKeyStore.DoesNotExist:
            keystore = BLTIKeyStore()

        # PUT does not update canvas_id or account_id
        external_tool.config = json.dumps(json_data['config'])
        external_tool.changed_by = UserService().get_original_user()
        external_tool.changed_date = datetime.utcnow().replace(tzinfo=utc)
        external_tool.save()

        keystore.consumer_key = json_data['config']['consumer_key']

        shared_secret = json_data['config']['shared_secret']
        if (shared_secret is None or not len(shared_secret)):
            del json_data['config']['shared_secret']
        else:
            keystore.shared_secret = shared_secret

        try:
            new_config = ExternalTools().update_external_tool_in_account(
                external_tool.account.account_id, json_data['config']['id'],
                json_data['config'])

            external_tool.canvas_id = new_config.get('id')
            external_tool.config = json.dumps(new_config)
            external_tool.provisioned_date = datetime.utcnow().replace(
                tzinfo=utc)
            external_tool.save()
            if keystore.shared_secret:
                keystore.save()

            logger.info('%s updated External Tool "%s"' % (
                external_tool.changed_by, external_tool.canvas_id))

        except DataFailureException as err:
            return self.json_response(
                '{"error":"%s: %s"}' % (err.status, err.msg), status=500)

        return self.json_response(json.dumps({
            'external_tool': external_tool.json_data()}))
Esempio n. 2
0
    def POST(self, request, **kwargs):
        if not can_manage_external_tools():
            return self.json_response('{"error":"Unauthorized"}', status=401)

        try:
            json_data = json.loads(request.body).get('external_tool', {})
            self.validate(json_data)
        except Exception as ex:
            logger.error('POST ExternalTool error: %s' % ex)
            return self.json_response('{"error": "%s"}' % ex, status=400)

        account_id = json_data['account_id']
        canvas_id = json_data['config'].get('id')

        try:
            external_tool = ExternalTool.objects.get(canvas_id=canvas_id)
            return self.json_response(
                '{"error": "External tool %s already exists"}' % ex,
                status=400)
        except ExternalTool.DoesNotExist:
            pass

        try:
            account = ExternalToolAccount.objects.get(account_id=account_id)
        except ExternalToolAccount.DoesNotExist:
            account = ExternalToolAccount(account_id=account_id)
            try:
                canvas_account = Accounts().get_account(account_id)
                account.name = canvas_account.name
                account.sis_account_id = canvas_account.sis_account_id
            except DataFailureException as ex:
                pass
            account.save()

        external_tool = ExternalTool(canvas_id=canvas_id)
        external_tool.account = account
        external_tool.config = json.dumps(json_data['config'])
        external_tool.changed_by = UserService().get_original_user()
        external_tool.changed_date = datetime.utcnow().replace(tzinfo=utc)

        try:
            keystore = BLTIKeyStore.objects.get(
                consumer_key=json_data['config']['consumer_key'])
            # Re-using an existing key/secret (clone?)
            json_data['config']['shared_secret'] = keystore.shared_secret

        except BLTIKeyStore.DoesNotExist:
            keystore = BLTIKeyStore()
            keystore.consumer_key = json_data['config']['consumer_key']

            shared_secret = json_data['config']['shared_secret']
            if (shared_secret is None or not len(shared_secret)):
                if not canvas_id:
                    # New external tool, generate a secret
                    shared_secret = external_tool.generate_shared_secret()
                    keystore.shared_secret = shared_secret
                    json_data['config']['shared_secret'] = shared_secret
                else:
                    # Existing external tool, don't overwrite the secret
                    del json_data['config']['shared_secret']

            keystore.save()

        try:
            if not canvas_id:
                new_config = ExternalTools().create_external_tool_in_account(
                    account_id, json_data['config'])

                logger.info('%s created External Tool "%s"' % (
                    external_tool.changed_by, new_config.get('id')))

            else:
                new_config = ExternalTools().update_external_tool_in_account(
                    account_id, canvas_id, json_data['config'])

                logger.info('%s updated External Tool "%s"' % (
                    external_tool.changed_by, new_config.get('id')))

            external_tool.canvas_id = new_config.get('id')
            external_tool.config = json.dumps(new_config)
            external_tool.provisioned_date = datetime.utcnow().replace(
                tzinfo=utc)
            external_tool.save()

        except DataFailureException as err:
            return self.json_response(
                '{"error":"%s: %s"}' % (err.status, err.msg), status=500)

        return self.json_response(json.dumps({
            'external_tool': external_tool.json_data()}))