def _validate_resource_info(provider, data, file_=None):

    # Check if the resource already exists
    existing = True
    current_organization = provider.userprofile.current_organization
    try:
        Resource.objects.get(name=data['name'], provider=current_organization)
    except:
        existing = False

    if existing:
        raise ConflictError('The resource ' + data['name'] + ' already exists. Please upgrade the resource if you want to provide new content')

    # Check contents
    if 'name' not in data or 'version' not in data or\
            'description' not in data or 'content_type' not in data or\
            'resource_type' not in data:
        raise ValueError('Invalid request: Missing required field')

    # Create version object to validate resource version format
    Version(data['version'])

    # Check name format
    if not is_valid_id(data['name']):
        raise ValueError('Invalid name format')

    return ({
        'name': data['name'],
        'version': data['version'],
        'description': data['description'],
        'content_type': data['content_type'],
        'resource_type': data['resource_type'],
        'open': data.get('open', False)
    }, current_organization)
Example #2
0
    def create(self, request):

        if not request.user.is_staff:  # Only an admin could register a new repository
            return build_response(request, 403, 'Forbidden')

        # Get request info
        name = None
        host = None
        try:
            content = json.loads(request.raw_post_data)
            name = content['name']
            host = content['host']
        except:
            msg = "Request body is not valid JSON data"
            return build_response(request, 400, msg)

        # Check data formats
        if not is_valid_id(name):
            return build_response(request, 400, 'Invalid name format')

        if not is_valid_url(host):
            return build_response(request, 400, 'Invalid URL format')

        # Register repository
        try:
            register_repository(name, host)
        except Exception, e:
            return build_response(request, 400, e.message)
Example #3
0
    def create(self, request):
        if not request.user.is_staff:  # Only an admin could register the store in a marketplace
            return build_response(request, 403, 'Forbidden')

        name = None
        host = None

        # Get contents from the request
        try:
            content = json.loads(request.raw_post_data)
            name = content['name']
            host = content['host']
        except:
            msg = "Request body is not valid JSON data"
            return build_response(request, 400, msg)

        # Check data formats
        if not is_valid_id(name):
            return build_response(request, 400, 'Invalid name format')

        if not is_valid_url(host):
            return build_response(request, 400, 'Invalid URL format')
        
        code = 201
        msg = 'Created'
        try:
            # Register the store in the selected marketplace
            register_on_market(name, host, get_current_site(request).domain)
        except Exception, e:
            if e.message == 'Bad Gateway':
                code = 502
                msg = e.message
            else:
                code = 400
                msg = 'Bad request'
    def _validate_plugin_form(self, form_info):
        """
        Validates the structure of the form definition of a plugin
        included in the package.json file
        """
        reason = None
        valid_types = ['text', 'textarea', 'checkbox', 'select']

        for k, v in form_info.iteritems():
            # Validate component
            if not isinstance(v, dict):
                reason = 'Invalid form field: ' + k + ' entry is not an object'
                break

            # Validate type value
            if 'type' not in v:
                reason = 'Invalid form field: Missing type in ' + k + ' entry'
                break

            if not v['type'] in valid_types:
                reason = 'Invalid form field: type ' + v['type'] + ' in ' + k + ' entry is not a valid type'
                break

            # Validate name format
            if not is_valid_id(k):
                reason = 'Invalid form field: ' + k + ' is not a valid name'
                break

            # Validate specific fields
            if v['type'] == 'checkbox' and 'default' in v and not isinstance(v['default'], bool):
                reason = 'Invalid form field: default field in ' + k + ' entry must be a boolean'
                break

        return reason
    def _validate_plugin_form(self, form_info):
        """
        Validates the structure of the form definition of a plugin
        included in the package.json file
        """
        reason = None
        valid_types = ['text', 'textarea', 'checkbox', 'select']

        for k, v in form_info.iteritems():
            # Validate component
            if not isinstance(v, dict):
                reason = 'Invalid form field: ' + k + ' entry is not an object'
                break

            # Validate type value
            if 'type' not in v:
                reason = 'Invalid form field: Missing type in ' + k + ' entry'
                break

            if not v['type'] in valid_types:
                reason = 'Invalid form field: type ' + v['type'] + ' in ' + k + ' entry is not a valid type'
                break

            # Validate name format
            if not is_valid_id(k):
                reason = 'Invalid form field: ' + k + ' is not a valid name'
                break

            # Validate specific fields
            if v['type'] == 'checkbox' and 'default' in v and not isinstance(v['default'], bool):
                reason = 'Invalid form field: default field in ' + k + ' entry must be a boolean'
                break

        return reason
Example #6
0
    def create(self, request):

        if not request.user.is_staff:
            return build_response(request, 403, 'Forbidden')

        try:
            data = json.loads(request.raw_post_data)

            if not len(data['name']) > 4 or not is_valid_id(data['name']):
                raise Exception('Invalid name format')

            if 'notification_url' in data:
                if data['notification_url'] and not is_valid_url(data['notification_url']):
                    raise Exception('Invalid notification URL format')
            else:
                data['notification_url'] = ''

            tax_address = {}
            if 'tax_address' in data:
                tax_address = {
                    'street': data['tax_address']['street'],
                    'postal': data['tax_address']['postal'],
                    'city': data['tax_address']['city'],
                    'country': data['tax_address']['country']
                }

            payment_info = {}
            if 'payment_info' in data:
                if not is_valid_credit_card(data['payment_info']['number']):
                    raise Exception()

                payment_info = {
                    'type': data['payment_info']['type'],
                    'number': data['payment_info']['number'],
                    'expire_month': data['payment_info']['expire_month'],
                    'expire_year': data['payment_info']['expire_year'],
                    'cvv2': data['payment_info']['cvv2']
                }
            Organization.objects.create(
                name=data['name'],
                notification_url=data['notification_url'],
                tax_address=tax_address,
                payment_info=payment_info,
                private=False
            )
        except Exception as e:
            msg = e.message
            if not msg.startswith('Invalid'):
                msg = 'Invalid content'
            return build_response(request, 400, msg)

        return build_response(request, 201, 'Created')
Example #7
0
    def create(self, request):
        # Check if the user is an admin
        if not request.user.is_staff:
            return build_response(request, 403, 'Forbidden')

        # Get data
        data = json.loads(request.raw_post_data)
        if not 'currency' in data:
            return build_response(request, 400, 'Invalid JSON content')

        # Check currency regex
        if not is_valid_id(data['currency']):
            return build_response(request, 400, 'Invalid currency format')

        # Get the context
        context = Context.objects.all()[0]

        # Check if the allowed_currencies list is empty
        first = False
        if not 'allowed' in context.allowed_currencies:
            first = True
            context.allowed_currencies['allowed'] = []

        error = False
        # Check that the new currency is not already included
        for curr in context.allowed_currencies['allowed']:
            if curr['currency'].lower() == data['currency'].lower():
                error = True
                break

        if error:
            return build_response(request, 400, 'The currency already exists')

        # Check if it is the default currency
        if ('default' in data and data['default']) or first:
            # Note the this will override previous default currency
            context.allowed_currencies['default'] = data['currency']

        # Include new currency
        context.allowed_currencies['allowed'].append({
            'currency':
            data['currency'],
            'in_use':
            False
        })
        context.save()
        return build_response(request, 201, 'Created')
Example #8
0
    def create(self, request):
        # Check if the user is an admin
        if not request.user.is_staff:
            return build_response(request, 403, 'Forbidden')

        # Get data
        data = json.loads(request.body)
        if not 'currency' in data:
            return build_response(request, 400, 'Invalid JSON content')

        # Check currency regex
        if not is_valid_id(data['currency']):
            return build_response(request, 400, 'Invalid currency format')

        # Get the context
        context = Context.objects.all()[0]

        # Check if the allowed_currencies list is empty
        first = False
        if not 'allowed' in context.allowed_currencies:
            first = True
            context.allowed_currencies['allowed'] = []

        error = False
        # Check that the new currency is not already included
        for curr in context.allowed_currencies['allowed']:
            if curr['currency'].lower() == data['currency'].lower():
                error = True
                break

        if error:
            return build_response(request, 400, 'The currency already exists')

        # Check if it is the default currency
        if ('default' in data and data['default']) or first:
            # Note the this will override previous default currency
            context.allowed_currencies['default'] = data['currency']

        # Include new currency
        context.allowed_currencies['allowed'].append({
            'currency': data['currency'],
            'in_use': False
        })
        context.save()
        return build_response(request, 201, 'Created')
def _validate_resource_info(provider, data, file_=None):

    # Check if the resource already exists
    existing = True
    current_organization = provider.userprofile.current_organization
    try:
        Resource.objects.get(name=data['name'], provider=current_organization)
    except:
        existing = False

    if existing:
        raise ConflictError(
            'The resource ' + data['name'] +
            ' already exists. Please upgrade the resource if you want to provide new content'
        )

    # Check contents
    if 'name' not in data or 'version' not in data or\
            'description' not in data or 'content_type' not in data or\
            'resource_type' not in data:
        raise ValueError('Invalid request: Missing required field')

    # Create version object to validate resource version format
    Version(data['version'])

    # Check name format
    if not is_valid_id(data['name']):
        raise ValueError('Invalid name format')

    return ({
        'name': data['name'],
        'version': data['version'],
        'description': data['description'],
        'content_type': data['content_type'],
        'resource_type': data['resource_type'],
        'open': data.get('open', False)
    }, current_organization)
Example #10
0
    def create(self, request):

        if not request.user.is_staff:  # Only an admin can register the store in a marketplace
            return build_response(request, 403, 'You are not allowed to register WStore in a Marketplace')

        name = None
        host = None
        api_version = None

        # Get contents from the request
        try:
            content = json.loads(request.raw_post_data)
            name = content['name']
            host = content['host']
            api_version = content['api_version']
        except:
            msg = "Request body is not valid JSON data"
            return build_response(request, 400, msg)

        # Check data formats
        if not is_valid_id(name):
            return build_response(request, 400, 'Invalid name format')

        if not is_valid_url(host):
            return build_response(request, 400, 'Invalid URL format')

        if not api_version.isdigit():
            return build_response(request, 400, 'Invalid API version')

        api_version = int(api_version)

        if api_version != 1 and api_version != 2:
            return build_response(request, 400, 'Invalid API version')

        credentials = None
        # Validate credentials if required
        if api_version == 1 or not settings.OILAUTH:
            if 'credentials' not in content:
                return build_response(request, 400, 'Missing required field credentials')

            if 'username' not in content['credentials']:
                return build_response(request, 400, 'Missing required field username in credentials')

            if 'passwd' not in content['credentials']:
                return build_response(request, 400, 'Missing required field passwd in credentials')

            credentials = content['credentials']

        code = 201
        msg = 'Created'
        try:
            # Register the store in the selected marketplace
            register_on_market(request.user, name, host, api_version, credentials, get_current_site(request).domain)
        except HTTPError:
            code = 502
            msg = "The Marketplace has failed registering the store"
        except ConflictError as e:
            code = 409
            msg = unicode(e)
        except Exception as e:
            code = 500
            msg = unicode(e)

        return build_response(request, code, msg)
Example #11
0
def create_offering(provider, json_data):

    profile = provider.userprofile
    data = {}
    if not 'name' in json_data or not 'version' in json_data:
        raise ValueError('Missing required fields')

    data['name'] = json_data['name']
    data['version'] = json_data['version']

    if not re.match(re.compile(r'^(?:[1-9]\d*\.|0\.)*(?:[1-9]\d*|0)$'), data['version']):
        raise ValueError('Invalid version format')

    if not is_valid_id(data['name']):
        raise ValueError('Invalid name format')

    # Get organization
    organization = profile.current_organization

    # Check if the offering already exists
    existing = True

    try:
        Offering.objects.get(name=data['name'], owner_organization=organization, version=data['version'])
    except:
        existing = False

    if existing:
        raise Exception('The offering already exists')

    # Check if the version of the offering is lower than an existing one
    offerings = Offering.objects.filter(owner_organization=organization, name=data['name'])
    for off in offerings:
        if is_lower_version(data['version'], off.version):
            raise ValueError('A bigger version of the current offering exists')

    is_open = json_data.get('open', False)

    # If using the idm, get the applications from the request
    if settings.OILAUTH:

        # Validate application structure
        data['applications'] = []

        for app in json_data['applications']:
            data['applications'].append({
                'name': app['name'],
                'url': app['url'],
                'id': app['id'],
                'description': app['description']
            })

    data['related_images'] = []

    # Check the URL to notify the provider
    notification_url = ''

    if 'notification_url' in json_data:
        if json_data['notification_url'] == 'default':
            notification_url = organization.notification_url
            if not notification_url:
                raise ValueError('There is not a default notification URL defined for the organization ' + organization.name + '. To configure a default notification URL provide it in the settings menu')
        else:
            # Check the notification URL
            if not is_valid_url(json_data['notification_url']):
                raise ValueError("Invalid notification URL format: It doesn't seem to be an URL")

            notification_url = json_data['notification_url']

    # Create the directory for app media
    dir_name = organization.name + '__' + data['name'] + '__' + data['version']
    path = os.path.join(settings.MEDIA_ROOT, dir_name)
    os.makedirs(path)

    if not 'image' in json_data:
        raise ValueError('Missing required field: Logo')

    if not isinstance(json_data['image'], dict):
        raise TypeError('Invalid image type')

    image = json_data['image']

    if not 'name' in image or not 'data' in image:
        raise ValueError('Missing required field in image')

    # Save the application image or logo
    f = open(os.path.join(path, image['name']), "wb")
    dec = base64.b64decode(image['data'])
    f.write(dec)
    f.close()

    data['image_url'] = settings.MEDIA_URL + dir_name + '/' + image['name']
    # Save screen shots
    if 'related_images' in json_data:
        for image in json_data['related_images']:

            # images must be encoded in base64 format
            f = open(os.path.join(path, image['name']), "wb")
            dec = base64.b64decode(image['data'])
            f.write(dec)
            f.close()

            data['related_images'].append(settings.MEDIA_URL + dir_name + '/' + image['name'])

    # Save USDL document
    # If the USDL itself is provided

    if 'offering_description' in json_data:
        usdl_info = json_data['offering_description']

        repository = Repository.objects.get(name=json_data['repository'])
        repository_adaptor = RepositoryAdaptor(repository.host, 'storeOfferingCollection')
        offering_id = organization.name + '__' + data['name'] + '__' + data['version']

        usdl = usdl_info['data']
        data['description_url'] = repository_adaptor.upload(usdl_info['content_type'], usdl_info['data'], name=offering_id)

    # If the USDL is already uploaded in the repository
    elif 'description_url' in json_data:

        # Check that the link to USDL is unique since could be used to
        # purchase offerings from Marketplace
        usdl_info = {}
        usdl_url = json_data['description_url']
        off = Offering.objects.filter(description_url=usdl_url)

        if len(off) != 0:
            raise ValueError('The provided USDL description is already registered')

        # Download the USDL from the repository
        repository_adaptor = RepositoryAdaptor(usdl_url)
        accept = "text/plain; application/rdf+xml; text/turtle; text/n3"

        usdl = repository_adaptor.download(content_type=accept)
        usdl_info['content_type'] = usdl['content_type']

        usdl = usdl['data']
        data['description_url'] = usdl_url

    # If the USDL is going to be created
    elif 'offering_info' in json_data:

        _validate_offering_info(json_data['offering_info'])

        offering_info = json_data['offering_info']
        offering_info['image_url'] = data['image_url']
        offering_info['name'] = data['name']

        repository = Repository.objects.get(name=json_data['repository'])

        offering_info['base_uri'] = repository.host

        usdl = _create_basic_usdl(offering_info)
        usdl_info = {
            'content_type': 'application/rdf+xml'
        }

        repository_adaptor = RepositoryAdaptor(repository.host, 'storeOfferingCollection')
        offering_id = organization.name + '__' + data['name'] + '__' + data['version']
        data['description_url'] = repository_adaptor.upload(usdl_info['content_type'], usdl, name=offering_id)
    else:
        raise Exception('No USDL description provided')

    # Validate the USDL
    data['open'] = is_open
    data['organization'] = organization
    valid = validate_usdl(usdl, usdl_info['content_type'], data)

    if not valid[0]:
        raise Exception(valid[1])

    # Check new currencies used
    if len(valid) > 2:
        new_curr = valid[2]

        # Set the currency as used
        cont = Context.objects.all()[0]
        currency = None
        # Search the currency
        for c in cont.allowed_currencies['allowed']:
            if c['currency'].lower() == new_curr.lower():
                currency = c
                break

        cont.allowed_currencies['allowed'].remove(currency)
        currency['in_use'] = True
        cont.allowed_currencies['allowed'].append(currency)
        cont.save()

    # Serialize and store USDL info in json-ld format
    graph = rdflib.Graph()
    rdf_format = usdl_info['content_type']

    if rdf_format == 'text/turtle' or rdf_format == 'text/plain':
            rdf_format = 'n3'
    elif rdf_format == 'application/json':
            rdf_format = 'json-ld'

    graph.parse(data=usdl, format=rdf_format)
    data['offering_description'] = graph.serialize(format='json-ld', auto_compact=True)

    # Create the offering
    offering = Offering.objects.create(
        name=data['name'],
        owner_organization=organization,
        owner_admin_user=provider,
        version=data['version'],
        state='uploaded',
        description_url=data['description_url'],
        resources=[],
        comments=[],
        tags=[],
        image_url=data['image_url'],
        related_images=data['related_images'],
        offering_description=json.loads(data['offering_description']),
        notification_url=notification_url,
        creation_date=datetime.now(),
        open=is_open
    )

    if settings.OILAUTH:
        offering.applications = data['applications']
        offering.save()

    if 'resources' in json_data and len(json_data['resources']) > 0:
        bind_resources(offering, json_data['resources'], profile.user)

    # Load offering document to the search index
    index_path = os.path.join(settings.BASEDIR, 'wstore')
    index_path = os.path.join(index_path, 'search')
    index_path = os.path.join(index_path, 'indexes')

    search_engine = SearchEngine(index_path)
    search_engine.create_index(offering)
def create_offering(provider, data):
    """
    Creates a new offering including the media files and
    the repository uploads
    """
    profile = provider.userprofile

    # Validate basic fields
    if 'name' not in data or 'version' not in data or 'offering_description' not in data \
            or 'image' not in data:

        missing_fields = ''

        if 'name' not in data:
            missing_fields += ' name'

        if 'version' not in data:
            missing_fields += ' version'

        if 'offering_description' not in data:
            missing_fields += ' offering_description'

        if 'image' not in data:
            missing_fields += ' image'

        raise ValueError('Missing required fields:' + missing_fields)

    if not re.match(re.compile(r'^(?:[1-9]\d*\.|0\.)*(?:[1-9]\d*|0)$'), data['version']):
        raise ValueError('Invalid version format')

    if not is_valid_id(data['name']):
        raise ValueError('Invalid name format')

    # Get organization
    organization = profile.current_organization

    # Check if the offering already exists
    if len(Offering.objects.filter(name=data['name'], owner_organization=organization, version=data['version'])) > 0:
        raise ConflictError('The offering ' + data['name'] + ' version ' + data['version'] + ' already exists')

    # Check if the version of the offering is lower than an existing one
    offerings = Offering.objects.filter(owner_organization=organization, name=data['name'])
    for off in offerings:
        if is_lower_version(data['version'], off.version):
            raise ValueError('A bigger version of the current offering exists')

    is_open = data.get('open', False)

    # If using the idm, get the applications from the request
    if settings.OILAUTH and 'applications' in data:
        # Validate application structure
        for app in data['applications']:
            if 'name' not in app or 'url' not in app or 'id' not in app or 'description' not in app:
                raise ValueError('Missing a required field in application definition')

    # Check the URL to notify the provider
    notification_url = ''
    if 'notification_url' in data:
        if data['notification_url'] == 'default':
            notification_url = organization.notification_url
            if not notification_url:
                raise ValueError('There is not a default notification URL defined for the organization ' + organization.name + '. To configure a default notification URL provide it in the settings menu')
        else:
            # Check the notification URL
            if not is_valid_url(data['notification_url']):
                raise ValueError("Invalid notification URL format: It doesn't seem to be an URL")

            notification_url = data['notification_url']

    # Create the directory for app media
    dir_name = organization.name + '__' + data['name'] + '__' + data['version']
    path = os.path.join(settings.MEDIA_ROOT, dir_name)
    os.makedirs(path)

    # Validate image format
    if not isinstance(data['image'], dict):
        raise TypeError('Invalid image type')

    data['image_url'] = _create_image(dir_name, path, data['image'])

    # Save screen shots
    screenshots = []
    if 'related_images' in data:
        for image in data['related_images']:
            screenshots.append(_create_image(dir_name, path, image))
    else:
        data['related_images'] = []

    # Validate the USDL
    data['open'] = is_open
    data['organization'] = organization

    # Create offering USDL
    offering_info = deepcopy(data['offering_description'])
    offering_info['image_url'] = data['image_url']
    offering_info['name'] = data['name']
    offering_info['version'] = data['version']
    offering_info['organization'] = organization.name
    offering_info['base_id'] = 'pk'

    created = datetime.now()
    offering_info['created'] = unicode(created)
    offering_info['modified'] = unicode(created)

    data['offering_description']['modified'] = unicode(created)

    usdl_generator = USDLGenerator()
    usdl_generator.validate_info(offering_info, organization, open_=is_open)

    # Create the offering
    offering = Offering(
        name=data['name'],
        owner_organization=organization,
        owner_admin_user=provider,
        version=data['version'],
        state='uploaded',
        resources=[],
        comments=[],
        tags=[],
        image_url=data['image_url'],
        related_images=screenshots,
        notification_url=notification_url,
        creation_date=created,
        open=is_open,
        offering_description=data['offering_description']
    )

    if settings.OILAUTH and 'applications' in data:
        offering.applications = data['applications']

    offering.save()

    offering.offering_description['base_id'] = offering.pk
    offering.save()

    if 'resources' in data and len(data['resources']) > 0:
        bind_resources(offering, data['resources'], profile.user)

    # Load offering document to the search index
    index_path = os.path.join(settings.BASEDIR, 'wstore')
    index_path = os.path.join(index_path, 'search')
    index_path = os.path.join(index_path, 'indexes')

    search_engine = SearchEngine(index_path)
    search_engine.create_index(offering)
Example #13
0
    def create(self, request):

        if settings.OILAUTH:
            return build_response(
                request, 403,
                'It is not possible to create users (use Account enabler instead)'
            )

        if not request.user.is_staff:
            return build_response(request, 403, 'Forbidden')

        data = json.loads(request.raw_post_data)

        # Validate Info
        if (not 'roles' in data) or (not 'username' in data) or (not 'first_name') in data \
        or (not 'last_name' in data) or (not 'password' in data):
            return build_response(request, 400, 'Missing required field')

        # Check username format
        if not len(data['username']) > 4 or not is_valid_id(data['username']):
            return build_response(request, 400, 'Invalid username format')

        # Create the user
        try:
            user = User.objects.create(username=data['username'],
                                       first_name=data['first_name'],
                                       last_name=data['last_name'])

            # Create the password
            user.set_password(data['password'])

            if 'admin' in data['roles']:
                user.is_staff = True

            user.save()

            # Get the user profile
            user_profile = UserProfile.objects.get(user=user)
            user_profile.complete_name = data['first_name'] + ' ' + data[
                'last_name']

            if 'notification_url' in data:
                # Check notification URL format
                if data['notification_url'] and not is_valid_url(
                        data['notification_url']):
                    raise Exception('Invalid notification URL format')

                user_profile.current_organization.notification_url = data[
                    'notification_url']
                user_profile.current_organization.save()

            if 'provider' in data['roles']:
                # Append the provider role to the user organization
                # The user profile is just created so only the private organization exists

                org = user_profile.organizations[0]
                org['roles'].append('provider')
                user_profile.save()
                user_profile.organizations = [org]

            if 'tax_address' in data:
                user_profile.tax_address = {
                    'street': data['tax_address']['street'],
                    'postal': data['tax_address']['postal'],
                    'city': data['tax_address']['city'],
                    'country': data['tax_address']['country']
                }
            if 'payment_info' in data:
                if not is_valid_credit_card(data['payment_info']['number']):
                    raise Exception()

                user_profile.payment_info = {
                    'type': data['payment_info']['type'],
                    'number': data['payment_info']['number'],
                    'expire_month': data['payment_info']['expire_month'],
                    'expire_year': data['payment_info']['expire_year'],
                    'cvv2': data['payment_info']['cvv2']
                }

            user_profile.save()

        except Exception as e:
            return build_response(request, 400, unicode(e))

        return build_response(request, 201, 'Created')
def register_resource(provider, data, file_=None):

    # Check if the resource already exists
    existing = True
    current_organization = provider.userprofile.current_organization
    try:
        Resource.objects.get(name=data["name"], provider=current_organization)
    except:
        existing = False

    if existing:
        raise ValueError(
            "The resource "
            + data["name"]
            + " already exists. Please upgrade the resource if you want to provide new content"
        )

    # Check contents
    if not "name" in data or not "version" in data or not "description" in data or not "content_type" in data:
        raise ValueError("Invalid request: Missing required field")

    # Check version format
    if not re.match(re.compile(r"^(?:[1-9]\d*\.|0\.)*(?:[1-9]\d*|0)$"), data["version"]):
        raise ValueError("Invalid version format")

    # Check name format
    if not is_valid_id(data["name"]):
        raise ValueError("Invalid name format")

    resource_data = {
        "name": data["name"],
        "version": data["version"],
        "description": data["description"],
        "content_type": data["content_type"],
    }

    if not file_:
        if "content" in data:
            resource_data["content_path"] = _save_resource_file(
                current_organization.name, data["name"], data["version"], data["content"]
            )
            resource_data["link"] = ""

        elif "link" in data:
            # Add the download link
            # Check link format
            if not is_valid_url(data["link"]):
                raise ValueError("Invalid resource link format")

            resource_data["link"] = data["link"]
            resource_data["content_path"] = ""
        else:
            raise ValueError("Invalid request: Missing resource content")

    else:
        resource_data["content_path"] = _save_resource_file(
            current_organization.name, data["name"], data["version"], file_
        )
        resource_data["link"] = ""

    Resource.objects.create(
        name=resource_data["name"],
        provider=current_organization,
        version=resource_data["version"],
        description=resource_data["description"],
        download_link=resource_data["link"],
        resource_path=resource_data["content_path"],
        content_type=resource_data["content_type"],
        state="created",
        open=data.get("open", False),
    )
Example #15
0
    def create(self, request):

        # Only the admin can register new RSS instances
        if not request.user.is_staff:
            return build_response(request, 403, 'Forbidden')

        data = json.loads(request.raw_post_data)

        if not 'name' in data or not 'host':
            return build_response(request, 400, 'Invalid JSON content')

        # Check name regex
        if not is_valid_id(data['name']):
            return build_response(request, 400, 'Invalid name format')

        # Check url regex
        if not is_valid_url(data['host']):
            return build_response(request, 400, 'Invalid URL format')

        # Check if the information provided is not already registered
        if len(RSS.objects.filter(name=data['name'])) > 0 or \
        len(RSS.objects.filter(host=data['host'])) > 0:
            return build_response(request, 400, 'Invalid JSON content')

        limits = {}
        cont = Context.objects.all()[0]

        # Check request limits
        if 'limits' in data:
            try:
                limits = _check_limits(data['limits'])
            except Exception as e:
                return build_response(request, 400, e.message)

        if not len(limits):
            # Set default limits
            limits = {
                'currency': cont.allowed_currencies['default'],
                'perTransaction': 10000,
                'weekly': 100000,
                'daily': 10000,
                'monthly': 100000
            }

        # Create the new entry
        rss = RSS.objects.create(
            name=data['name'],
            host=data['host'],
            expenditure_limits=limits)

        exp_manager = ExpenditureManager(rss, request.user.userprofile.access_token)
        # Create default expenditure limits
        call_result = _make_expenditure_request(exp_manager, exp_manager.set_provider_limit, request.user)

        if call_result[0]:
            # Remove created RSS entry
            rss.delete()
            # Return error response
            return build_response(request, call_result[1], call_result[2])

        # The request has been success so the used credentials are valid
        # Store the credentials for future access
        rss.access_token = request.user.userprofile.access_token
        rss.refresh_token = request.user.userprofile.refresh_token
        rss.save()

        return build_response(request, 201, 'Created')
Example #16
0
    def create(self, request):

        if not request.user.is_active:
            return build_response(request, 403,
                                  'The user has not been activated')

        try:
            data = json.loads(request.raw_post_data)

            if 'name' not in data:
                raise Exception('Invalid JSON content')

            organization_registered = Organization.objects.filter(
                name=data['name'])
            if len(organization_registered) > 0:
                raise Exception('The ' + data['name'] +
                                ' organization is already registered.')

            if not len(data['name']) > 4 or not is_valid_id(data['name']):
                raise Exception('Enter a valid name.')

            if 'notification_url' in data:
                if data['notification_url'] and not is_valid_url(
                        data['notification_url']):
                    raise Exception('Enter a valid URL')
            else:
                data['notification_url'] = ''

            tax_address = {}
            if 'tax_address' in data:
                tax_address = {
                    'street': data['tax_address']['street'],
                    'postal': data['tax_address']['postal'],
                    'city': data['tax_address']['city'],
                    'country': data['tax_address']['country']
                }

            payment_info = {}
            if 'payment_info' in data:
                if not is_valid_credit_card(data['payment_info']['number']):
                    raise Exception('Invalid credit card info')

                payment_info = {
                    'type': data['payment_info']['type'],
                    'number': data['payment_info']['number'],
                    'expire_month': data['payment_info']['expire_month'],
                    'expire_year': data['payment_info']['expire_year'],
                    'cvv2': data['payment_info']['cvv2']
                }

            Organization.objects.create(
                name=data['name'],
                notification_url=data['notification_url'],
                tax_address=tax_address,
                payment_info=payment_info,
                private=False)

            user_included = False
            if not request.user.is_staff or (request.user.is_staff and 'is_user' in \
            data and data['is_user'] == True):
                user_included = True

            # Include the new user, if the user is not admin include the user
            # If the user is an admin, include it depending on if she has created
            # the organization as an user
            if user_included:
                user = request.user
                organization = Organization.objects.get(name=data['name'])
                user.userprofile.organizations.append({
                    'organization':
                    organization.pk,
                    'roles': []
                })
                user.userprofile.save()

                organization.managers.append(user.pk)
                organization.save()
        except Exception as e:
            msg = 'Invalid JSON content'
            if e.message:
                msg = e.message
            return build_response(request, 400, msg)

        return build_response(request, 201, 'Created')
Example #17
0
def register_resource(provider, data, file_=None):

    # Check if the resource already exists
    existing = True
    current_organization = provider.userprofile.current_organization
    try:
        Resource.objects.get(name=data['name'], provider=current_organization, version=data['version'])
    except:
        existing = False

    if existing:
        raise Exception('The resource already exists')

    if not re.match(re.compile(r'^(?:[1-9]\d*\.|0\.)*(?:[1-9]\d*|0)$'), data['version']):
        raise Exception('Invalid version format')

    if not is_valid_id(data['name']):
        raise Exception('Invalid name format')

    resource_data = {
        'name': data['name'],
        'version': data['version'],
        'description': data['description'],
        'content_type': data['content_type']
    }

    if file_ is None:
        if 'content' in data:
            resource = data['content']

            # Check file name format
            if not is_valid_file(resource['name']):
                raise Exception('Invalid file name format: Unsupported character')

            #decode the content and save the media file
            file_name = current_organization.name + '__' + data['name'] + '__' + data['version'] + '__' + resource['name']
            path = os.path.join(settings.MEDIA_ROOT, 'resources')
            file_path = os.path.join(path, file_name)
            f = open(file_path, "wb")
            dec = base64.b64decode(resource['data'])
            f.write(dec)
            f.close()
            resource_data['content_path'] = settings.MEDIA_URL + 'resources/' + file_name
            resource_data['link'] = ''

        elif 'link' in data:
            # Add the download link
            # Check link format
            if not is_valid_url(data['link']):
                raise Exception('Invalid Resource link format')

            resource_data['link'] = data['link']
            resource_data['content_path'] = ''

    else:
        #decode the content and save the media file
        # Check file name format
        if not is_valid_file(file_.name):
            raise Exception('Invalid file name format: Unsupported character')

        file_name = current_organization.name + '__' + data['name'] + '__' + data['version'] + '__' + file_.name
        path = os.path.join(settings.MEDIA_ROOT, 'resources')
        file_path = os.path.join(path, file_name)
        f = open(file_path, "wb")
        f.write(file_.read())
        f.close()
        resource_data['content_path'] = settings.MEDIA_URL + 'resources/' + file_name
        resource_data['link'] = ''

    Resource.objects.create(
        name=resource_data['name'],
        provider=current_organization,
        version=resource_data['version'],
        description=resource_data['description'],
        download_link=resource_data['link'],
        resource_path=resource_data['content_path'],
        content_type=resource_data['content_type'],
        state='created'
    )
Example #18
0
    def create(self, request):

        # Only the admin can register new RSS instances
        if not request.user.is_staff:
            return build_response(request, 403, 'Forbidden')

        data = json.loads(request.raw_post_data)

        if 'name' not in data or 'host' not in data or 'api_version' not in data:
            msg = 'RSS creation error: Missing a required field'

            if 'name' not in data:
                msg += ', name'

            if 'host' not in data:
                msg += ', host'

            if 'api_version' not in data:
                msg += ', api_version'

            return build_response(request, 400, msg)

        # Check name regex
        if not is_valid_id(data['name']):
            return build_response(request, 400, 'RSS creation error: Invalid name format')

        # Check url regex
        if not is_valid_url(data['host']):
            return build_response(request, 400, 'RSS creation error: Invalid URL format')

        # Check api_version format
        try:
            api_version = int(data['api_version'])
        except:
            return build_response(request, 400, 'RSS creation error: Invalid api_version format, must be an integer (1 or 2)')

        if api_version != 1 and api_version != 2:
            return build_response(request, 400, 'RSS creation error: Invalid api_version, must be 1 or 2')

        # Check if the information provided is not already registered
        if len(RSS.objects.all()) > 0:
            return build_response(request, 409, 'RSS creation error: There is a RSS instance already registered')

        limits = {}
        cont = Context.objects.all()[0]

        # Check request limits
        if 'limits' in data:
            try:
                limits = _check_limits(data['limits'])
            except Exception as e:
                return build_response(request, 400, unicode(e))

        if not len(limits):
            # Set default limits
            limits = {
                'currency': cont.allowed_currencies['default'],
                'perTransaction': 10000,
                'weekly': 100000,
                'daily': 10000,
                'monthly': 100000
            }

        # Check revenue sharing models
        sharing_models = []
        if 'models' in data:
            try:
                sharing_models = _check_revenue_models(data['models'])
            except Exception as e:
                return build_response(request, 400, unicode(e))
        else:
            # Set default revenue models
            sharing_models = [{
                'class': 'single-payment',
                'percentage': 10.0
            }, {
                'class': 'subscription',
                'percentage': 20.0
            }, {
                'class': 'use',
                'percentage': 30.0
            }]

        # Build revenue models
        db_revenue_models = []
        for model in sharing_models:
            db_revenue_models.append(RevenueModel(
                revenue_class=model['class'],
                percentage=Decimal(model['percentage'])
            ))

        if not data['host'].endswith('/'):
            data['host'] += '/'

        # Create the new entry
        rss = RSS.objects.create(
            name=data['name'],
            host=data['host'],
            api_version=api_version,
            expenditure_limits=limits,
            revenue_models=db_revenue_models,
            aggregator_id=request.user.email
        )

        rss_factory = RSSManagerFactory(rss)

        # Create a new provider if needed
        if api_version == 2:
            prov_manager = rss_factory.get_provider_manager(request.user.userprofile.access_token)
            provider_info = {
                'provider_id': settings.STORE_NAME.lower() + '-provider',
                'provider_name': settings.STORE_NAME + '-Provider'
            }
            call_result = _make_rss_request(prov_manager, prov_manager.register_provider, request.user, provider_info)

            if call_result[0]:
                rss.delete()
                # Return error response
                return build_response(request, call_result[1], call_result[2])

        exp_manager = rss_factory.get_expenditure_manager(request.user.userprofile.access_token)

        # Create default expenditure limits
        call_result = _make_rss_request(exp_manager, exp_manager.set_provider_limit, request.user)

        if call_result[0]:
            rss.delete()
            # Return error response
            return build_response(request, call_result[1], call_result[2])

        # Create default revenue sharing models
        if api_version == 1:
            model_manager = rss_factory.get_model_manager(rss, request.user)

            model_created = False
            for model in sharing_models:
                def call_model_creation():
                    model_manager.create_revenue_model(model)

                call_result = _make_rss_request(model_manager, call_model_creation, request.user)

                if call_result[0] and not model_created:
                    rss.delete()
                    return build_response(request, call_result[1], call_result[2])
                elif not call_result[0]:
                    model_created = True

        # The request has been success so the used credentials are valid
        # Store the credentials for future access
        rss.access_token = request.user.userprofile.access_token
        rss.refresh_token = request.user.userprofile.refresh_token
        rss.save()

        return build_response(request, 201, 'Created')
Example #19
0
    def create(self, request):

        if not request.user.is_staff:  # Only an admin can register the store in a marketplace
            return build_response(
                request, 403,
                'You are not allowed to register WStore in a Marketplace')

        name = None
        host = None
        api_version = None

        # Get contents from the request
        try:
            content = json.loads(request.raw_post_data)
            name = content['name']
            host = content['host']
            api_version = content['api_version']
        except:
            msg = "Request body is not valid JSON data"
            return build_response(request, 400, msg)

        # Check data formats
        if not is_valid_id(name):
            return build_response(request, 400, 'Invalid name format')

        if not is_valid_url(host):
            return build_response(request, 400, 'Invalid URL format')

        if not api_version.isdigit():
            return build_response(request, 400, 'Invalid API version')

        api_version = int(api_version)

        if api_version != 1 and api_version != 2:
            return build_response(request, 400, 'Invalid API version')

        credentials = None
        # Validate credentials if required
        if api_version == 1 or not settings.OILAUTH:
            if 'credentials' not in content:
                return build_response(request, 400,
                                      'Missing required field credentials')

            if 'username' not in content['credentials']:
                return build_response(
                    request, 400,
                    'Missing required field username in credentials')

            if 'passwd' not in content['credentials']:
                return build_response(
                    request, 400,
                    'Missing required field passwd in credentials')

            credentials = content['credentials']

        code = 201
        msg = 'Created'
        try:
            # Register the store in the selected marketplace
            register_on_market(request.user, name, host, api_version,
                               credentials,
                               get_current_site(request).domain)
        except HTTPError:
            code = 502
            msg = "The Marketplace has failed registering the store"
        except ConflictError as e:
            code = 409
            msg = unicode(e)
        except Exception as e:
            code = 500
            msg = unicode(e)

        return build_response(request, code, msg)
    def validate_plugin_info(self, plugin_info):
        """
        Validates the structure of the package.json file of a plugin
        """

        reason = None
        # Check plugin_info format
        if not isinstance(plugin_info, dict):
            reason = 'Plugin info must be a dict instance'

        # Validate structure
        if reason is None and "name" not in plugin_info:
            reason = 'Missing required field: name'

        # Validate types
        if reason is None and not isinstance(plugin_info['name'], str) and not isinstance(plugin_info['name'], unicode):
            reason = 'Plugin name must be an string'

        if reason is None and not is_valid_id(plugin_info['name']):
            reason = 'Invalid name format: invalid character'

        if reason is None and "author" not in plugin_info:
            reason = 'Missing required field: author'

        if reason is None and 'formats' not in plugin_info:
            reason = 'Missing required field: formats'

        if reason is None and 'module' not in plugin_info:
            reason = 'Missing required field: module'

        if reason is None and 'version' not in plugin_info:
            reason = 'Missing required field: version'

        if reason is None and not isinstance(plugin_info['author'], str) and not isinstance(plugin_info['author'], unicode):
            reason = 'Plugin author must be an string'

        if reason is None and not isinstance(plugin_info['formats'], list):
            reason = 'Plugin formats must be a list'

        # Validate formats
        if reason is None:
            valid_format, i = self._check_list_field(['FILE', 'URL'], plugin_info['formats'])

            if not valid_format or (i < 1 and i > 2):
                reason = 'Format must contain at least one format of: FILE, URL'

        # Validate overrides
        if reason is None and 'overrides' in plugin_info and not self._check_list_field(["NAME", "VERSION", "OPEN"], plugin_info['overrides'])[0]:
            reason = "Override values should be one of: NAME, VERSION and OPEN"

        if reason is None and 'media_types' in plugin_info and not isinstance(plugin_info['media_types'], list):
            reason = 'Plugin media_types must be a list'

        if reason is None and not isinstance(plugin_info['module'], str) and not isinstance(plugin_info['module'], unicode):
            reason = 'Plugin module must be an string'

        if reason is None and not is_valid_version(plugin_info['version']):
            reason = 'Invalid format in plugin version'

        if reason is None and 'form' in plugin_info:
            if not isinstance(plugin_info['form'], dict):
                reason = 'Invalid format in form field, must be an object'
            else:
                reason = self._validate_plugin_form(plugin_info['form'])

        return reason
Example #21
0
    def create(self, request):

        if not request.user.is_staff:  # Only an admin could register a new repository
            return build_response(request, 403, 'You are not authorized to register a repository')

        # Get request info
        try:
            content = json.loads(request.raw_post_data)
            is_default = content.get('is_default', False)
        except:
            msg = "Request body is not valid JSON data"
            return build_response(request, 400, msg)

        if 'name' not in content:
            return build_response(request, 400, 'Missing required field: name')

        if 'host' not in content:
            return build_response(request, 400, 'Missing required field: host')

        if 'api_version' not in content:
            return build_response(request, 400, 'Missing required field: api_version')

        if 'offering_collection' not in content:
            return build_response(request, 400, 'Missing required field: offering_collection')

        if 'resource_collection' not in content:
            return build_response(request, 400, 'Missing required field: resource_collection')

        # Check data formats
        if not is_valid_id(content['name']):
            return build_response(request, 400, 'Invalid name format')

        if not is_valid_id(content['offering_collection']) or ' ' in content['offering_collection']:
            return build_response(request, 400, 'Invalid offering_collection format: Invalid character found')

        if not is_valid_id(content['resource_collection']) or ' ' in content['resource_collection']:
            return build_response(request, 400, 'Invalid resource_collection format: Invalid character found')

        if not is_valid_url(content['host']):
            return build_response(request, 400, 'Invalid URL format')

        if not content['api_version'].isdigit():
            return build_response(request, 400, 'Invalid api_version format: must be an integer')

        api_version = int(content['api_version'])
        if api_version != 1 and api_version != 2:
            return build_response(request, 400, 'Invalid api_version: Only versions 1 and 2 are supported')

        # Register repository
        try:
            register_repository(
                content['name'],
                content['host'],
                content['offering_collection'],
                content['resource_collection'],
                api_version,
                is_default
            )
        except ConflictError as e:
            return build_response(request, 409, unicode(e))
        except Exception as e:
            return build_response(request, 500, unicode(e))

        return build_response(request, 201, 'Created')
    def _validate_plugin_form(self, form_info):
        """
        Validates the structure of the form definition of a plugin
        included in the package.json file
        """

        reason = None
       
        def _text_type(key, value, attrs):
            reasonStr = ''
            for attr in attrs:
                if attr in value and not (isinstance(value[attr], str) or isinstance(value[attr], unicode)):
                    reasonStr += '\nInvalid form field: ' + attr + ' field in ' + key + ' entry must be an string'

            return reasonStr

        def _bool_type(key, value, attrs):
            reasonStr = ''
            for attr in attrs:
                if attr in value and not isinstance(value[attr], bool):
                    reasonStr += '\nInvalid form field: ' + attr + ' field in ' + key + ' entry must be a boolean'

            return reasonStr

        def _validate_text_type(key, value):
            reasonStr = _text_type(key, value, ['default', 'placeholder', 'label'])
            reasonStr += _bool_type(key, value, ['mandatory'])
            return reasonStr if len(reasonStr) else None

        def _validate_checkbox_type(key, value):
            reasonStr = _text_type(key, value, ['label'])
            reasonStr += _bool_type(key, value, ['default', 'mandatory'])

            return reasonStr if len(reasonStr) else None

        def _validate_select_type(key, value):
            reasonStr = _text_type(key, value, ['default', 'label'])
            reasonStr += _bool_type(key, value, ['mandatory'])

            if 'options' not in value or not isinstance(value['options'], list) or not len(value['options']):
                reasonStr += '\nInvalid form field: Missing or invalid options in ' + k + ' field'
            else:
                for option in value['options']:
                    if not isinstance(option, dict) or not 'text' in option or not 'value' in option:
                        reasonStr += '\nInvalid form field: Invalid option in ' + k + ' field, wrong option type or missing field'
                    else:
                        reasonStr += _text_type(key, option, ['text', 'value'])

            return reasonStr if len(reasonStr) else None

        valid_types = {
            'text': _validate_text_type, 
            'textarea': _validate_text_type,
            'checkbox': _validate_checkbox_type,
            'select': _validate_select_type
        }

        for k, v in form_info.iteritems():
            # Validate component
            if not isinstance(v, dict):
                reason = 'Invalid form field: ' + k + ' entry is not an object'
                break

            # Validate type value
            if 'type' not in v:
                reason = 'Invalid form field: Missing type in ' + k + ' entry'
                break

            if not v['type'] in valid_types:
                reason = 'Invalid form field: type ' + v['type'] + ' in ' + k + ' entry is not a valid type'
                break

            # Validate name format
            if not is_valid_id(k):
                reason = 'Invalid form field: ' + k + ' is not a valid name'
                break

            # Validate specific fields
            reason = valid_types[v['type']](k, v)
            if reason is not None:
                break

        return reason
Example #23
0
    def create(self, request):

        if not request.user.is_active:
            return build_response(request, 403, 'The user has not been activated')

        try:
            data = json.loads(request.raw_post_data)

            if 'name' not in data:
                raise Exception('Invalid JSON content')

            organization_registered = Organization.objects.filter(name=data['name'])
            if len(organization_registered) > 0:
                raise Exception('The ' + data['name'] + ' organization is already registered.')

            if not len(data['name']) > 4 or not is_valid_id(data['name']):
                raise Exception('Enter a valid name.')

            if 'notification_url' in data:
                if data['notification_url'] and not is_valid_url(data['notification_url']):
                    raise Exception('Enter a valid URL')
            else:
                data['notification_url'] = ''

            tax_address = {}
            if 'tax_address' in data:
                tax_address = {
                    'street': data['tax_address']['street'],
                    'postal': data['tax_address']['postal'],
                    'city': data['tax_address']['city'],
                    'country': data['tax_address']['country']
                }

            payment_info = {}
            if 'payment_info' in data:
                if not is_valid_credit_card(data['payment_info']['number']):
                    raise Exception('Invalid credit card info')

                payment_info = {
                    'type': data['payment_info']['type'],
                    'number': data['payment_info']['number'],
                    'expire_month': data['payment_info']['expire_month'],
                    'expire_year': data['payment_info']['expire_year'],
                    'cvv2': data['payment_info']['cvv2']
                }

            Organization.objects.create(
                name=data['name'],
                notification_url=data['notification_url'],
                tax_address=tax_address,
                payment_info=payment_info,
                private=False
            )

            user_included = False
            if not request.user.is_staff or (request.user.is_staff and 'is_user' in \
            data and data['is_user'] == True):
                user_included = True

            # Include the new user, if the user is not admin include the user
            # If the user is an admin, include it depending on if she has created
            # the organization as an user
            if user_included:
                user = request.user
                organization = Organization.objects.get(name=data['name'])
                user.userprofile.organizations.append({
                    'organization': organization.pk,
                    'roles': []
                })
                user.userprofile.save()

                organization.managers.append(user.pk)
                organization.save()
        except Exception as e:
            msg = 'Invalid JSON content'
            if e.message:
                msg = e.message
            return build_response(request, 400, msg)

        return build_response(request, 201, 'Created')
Example #24
0
    def create(self, request):

        if settings.OILAUTH:
            return build_response(request, 403, 'It is not possible to create users (use Account enabler instead)')

        if not request.user.is_staff:
            return build_response(request, 403, 'Forbidden')

        data = json.loads(request.raw_post_data)

        # Validate Info
        if (not 'roles' in data) or (not 'username' in data) or (not 'first_name') in data \
        or (not 'last_name' in data) or (not 'password' in data):
            return build_response(request, 400, 'Missing required field')

        # Check username format
        if not len(data['username']) > 4 or not is_valid_id(data['username']):
            return build_response(request, 400, 'Invalid username format')

        # Create the user
        try:
            user = User.objects.create(username=data['username'], first_name=data['first_name'], last_name=data['last_name'])

            # Create the password
            user.set_password(data['password'])

            if 'admin' in data['roles']:
                user.is_staff = True

            user.save()

            # Get the user profile
            user_profile = UserProfile.objects.get(user=user)
            user_profile.complete_name = data['first_name'] + ' ' + data['last_name']

            if 'notification_url' in data:
                # Check notification URL format
                if data['notification_url'] and not is_valid_url(data['notification_url']):
                    raise Exception('Invalid notification URL format')

                user_profile.current_organization.notification_url = data['notification_url']
                user_profile.current_organization.save()

            if 'provider' in data['roles']:
                # Append the provider role to the user organization
                # The user profile is just created so only the private organization exists

                org = user_profile.organizations[0]
                org['roles'].append('provider')
                user_profile.save()
                user_profile.organizations = [org]

            if 'tax_address' in data:
                user_profile.tax_address = {
                    'street': data['tax_address']['street'],
                    'postal': data['tax_address']['postal'],
                    'city': data['tax_address']['city'],
                    'country': data['tax_address']['country']
                }
            if 'payment_info' in data:
                if not is_valid_credit_card(data['payment_info']['number']):
                    raise Exception()

                user_profile.payment_info = {
                    'type': data['payment_info']['type'],
                    'number': data['payment_info']['number'],
                    'expire_month': data['payment_info']['expire_month'],
                    'expire_year': data['payment_info']['expire_year'],
                    'cvv2': data['payment_info']['cvv2']
                }

            user_profile.save()

        except Exception as e:
            return build_response(request, 400, unicode(e))

        return build_response(request, 201, 'Created')
Example #25
0
    def validate_plugin_info(self, plugin_info):
        """
        Validates the structure of the package.json file of a plugin
        """

        reason = None
        # Check plugin_info format
        if not isinstance(plugin_info, dict):
            reason = 'Plugin info must be a dict instance'

        # Validate structure
        if reason is None and "name" not in plugin_info:
            reason = 'Missing required field: name'

        # Validate types
        if reason is None and not isinstance(plugin_info['name'],
                                             str) and not isinstance(
                                                 plugin_info['name'], unicode):
            reason = 'Plugin name must be an string'

        if reason is None and not is_valid_id(plugin_info['name']):
            reason = 'Invalid name format: invalid character'

        if reason is None and "author" not in plugin_info:
            reason = 'Missing required field: author'

        if reason is None and 'formats' not in plugin_info:
            reason = 'Missing required field: formats'

        if reason is None and 'module' not in plugin_info:
            reason = 'Missing required field: module'

        if reason is None and 'version' not in plugin_info:
            reason = 'Missing required field: version'

        if reason is None and not isinstance(
                plugin_info['author'], str) and not isinstance(
                    plugin_info['author'], unicode):
            reason = 'Plugin author must be an string'

        if reason is None and not isinstance(plugin_info['formats'], list):
            reason = 'Plugin formats must be a list'

        # Validate formats
        if reason is None:
            valid_format, i = self._check_list_field(['FILE', 'URL'],
                                                     plugin_info['formats'])

            if not valid_format or (i < 1 and i > 2):
                reason = 'Format must contain at least one format of: FILE, URL'

        # Validate overrides
        if reason is None and 'overrides' in plugin_info and not self._check_list_field(
            ["NAME", "VERSION", "OPEN"], plugin_info['overrides'])[0]:
            reason = "Override values should be one of: NAME, VERSION and OPEN"

        if reason is None and 'media_types' in plugin_info and not isinstance(
                plugin_info['media_types'], list):
            reason = 'Plugin media_types must be a list'

        if reason is None and not isinstance(
                plugin_info['module'], str) and not isinstance(
                    plugin_info['module'], unicode):
            reason = 'Plugin module must be an string'

        if reason is None and not is_valid_version(plugin_info['version']):
            reason = 'Invalid format in plugin version'

        if reason is None and 'form' in plugin_info:
            if not isinstance(plugin_info['form'], dict):
                reason = 'Invalid format in form field, must be an object'
            else:
                reason = self._validate_plugin_form(plugin_info['form'])

        return reason
Example #26
0
    def create(self, request):

        # Only the admin can register new RSS instances
        if not request.user.is_staff:
            return build_response(request, 403, 'Forbidden')

        data = json.loads(request.raw_post_data)

        if not 'name' in data or not 'host':
            return build_response(request, 400, 'RSS creation error: Missing a required field')

        # Check name regex
        if not is_valid_id(data['name']):
            return build_response(request, 400, 'RSS creation error: Invalid name format')

        # Check url regex
        if not is_valid_url(data['host']):
            return build_response(request, 400, 'RSS creation error: Invalid URL format')

        # Check if the information provided is not already registered
        if len(RSS.objects.filter(name=data['name'])) > 0 or \
        len(RSS.objects.filter(host=data['host'])) > 0:
            return build_response(request, 409, 'RSS creation error: The RSS instance already exists')

        limits = {}
        cont = Context.objects.all()[0]

        # Check request limits
        if 'limits' in data:
            try:
                limits = _check_limits(data['limits'])
            except Exception as e:
                return build_response(request, 400, unicode(e))

        if not len(limits):
            # Set default limits
            limits = {
                'currency': cont.allowed_currencies['default'],
                'perTransaction': 10000,
                'weekly': 100000,
                'daily': 10000,
                'monthly': 100000
            }

        # Check revenue sharing models
        sharing_models = []
        if 'models' in data:
            try:
                sharing_models = _check_revenue_models(data['models'])
            except Exception as e:
                return build_response(request, 400, unicode(e))
        else:
            # Set default revenue models
            sharing_models = [{
                'class': 'single-payment',
                'percentage': 10.0
            },{
                'class': 'subscription',
                'percentage': 20.0
            },{
                'class': 'use',
                'percentage': 30.0
            }]

        # Build revenue models
        db_revenue_models = [] 
        for model in sharing_models:
            db_revenue_models.append(RevenueModel(
                revenue_class=model['class'],
                percentage=Decimal(model['percentage'])
            ))

        # Create the new entry
        rss = RSS.objects.create(
            name=data['name'],
            host=data['host'],
            expenditure_limits=limits,
            revenue_models=db_revenue_models
        )

        exp_manager = ExpenditureManager(rss, request.user.userprofile.access_token)
        # Create default expenditure limits
        call_result = _make_rss_request(exp_manager, exp_manager.set_provider_limit, request.user)

        if call_result[0]:
            rss.delete()
            # Return error response
            return build_response(request, call_result[1], call_result[2])

        # Create default revenue sharing models
        model_manager = ModelManager(rss, request.user.userprofile.access_token)

        model_created = False
        for model in sharing_models:
            def call_model_creation():
                model_manager.create_revenue_model(model)

            call_result = _make_rss_request(model_manager, call_model_creation, request.user)

            if call_result[0] and not model_created:
                rss.delete()
                return build_response(request, call_result[1], call_result[2])
            elif not call_result[0]:
                model_created = True

        # The request has been success so the used credentials are valid
        # Store the credentials for future access
        rss.access_token = request.user.userprofile.access_token
        rss.refresh_token = request.user.userprofile.refresh_token
        rss.save()

        return build_response(request, 201, 'Created')
Example #27
0
def register_resource(provider, data, file_=None):

    # Check if the resource already exists
    existing = True
    current_organization = provider.userprofile.current_organization
    try:
        Resource.objects.get(name=data['name'], provider=current_organization)
    except:
        existing = False

    if existing:
        raise ValueError('The resource ' + data['name'] + ' already exists. Please upgrade the resource if you want to provide new content')

    # Check contents
    if not 'name' in data or not 'version' in data or\
    not 'description' in data or not 'content_type' in data:
        raise ValueError('Invalid request: Missing required field')

    # Check version format
    if not re.match(re.compile(r'^(?:[1-9]\d*\.|0\.)*(?:[1-9]\d*|0)$'), data['version']):
        raise ValueError('Invalid version format')

    # Check name format
    if not is_valid_id(data['name']):
        raise ValueError('Invalid name format')

    resource_data = {
        'name': data['name'],
        'version': data['version'],
        'description': data['description'],
        'content_type': data['content_type']
    }

    if not file_:
        if 'content' in data:
            resource_data['content_path'] = _save_resource_file(current_organization.name, data['name'], data['version'], data['content'])
            resource_data['link'] = ''

        elif 'link' in data:
            # Add the download link
            # Check link format
            if not is_valid_url(data['link']):
                raise ValueError('Invalid resource link format')

            resource_data['link'] = data['link']
            resource_data['content_path'] = ''
        else:
            raise ValueError('Invalid request: Missing resource content')

    else:
        resource_data['content_path'] = _save_resource_file(current_organization.name, data['name'], data['version'], file_)
        resource_data['link'] = ''

    Resource.objects.create(
        name=resource_data['name'],
        provider=current_organization,
        version=resource_data['version'],
        description=resource_data['description'],
        download_link=resource_data['link'],
        resource_path=resource_data['content_path'],
        content_type=resource_data['content_type'],
        state='created',
        open=data.get('open', False)
    )
Example #28
0
    def validate_plugin_info(self, plugin_info):
        """
        Validates the structure of the package.json file of a plugin
        """

        reason = None
        # Check plugin_info format
        if not isinstance(plugin_info, dict):
            reason = 'Plugin info must be a dict instance'

        # Validate structure
        if reason is None and "name" not in plugin_info:
            reason = 'Missing required field: name'

        # Validate types
        if reason is None and not isinstance(plugin_info['name'], str):
            reason = 'Plugin name must be an string'

        if reason is None and not is_valid_id(plugin_info['name']):
            reason = 'Invalid name format: invalid character'

        if reason is None and "author" not in plugin_info:
            reason = 'Missing required field: author'

        if reason is None and 'formats' not in plugin_info:
            reason = 'Missing required field: formats'

        if reason is None and 'module' not in plugin_info:
            reason = 'Missing required field: module'

        if reason is None and 'version' not in plugin_info:
            reason = 'Missing required field: version'

        if reason is None and not isinstance(plugin_info['author'], str):
            reason = 'Plugin author must be an string'

        if reason is None and not isinstance(plugin_info['formats'], list):
            reason = 'Plugin formats must be a list'

        # Validate formats
        if reason is None:
            valid_format, i = self._check_list_field(['FILE', 'URL'], plugin_info['formats'])

            if not valid_format or (i < 1 and i > 2):
                reason = 'Format must contain at least one format of: FILE, URL'

        # Validate overrides
        if reason is None and 'overrides' in plugin_info and not self._check_list_field(["NAME", "VERSION", "OPEN"], plugin_info['overrides'])[0]:
            reason = "Override values should be one of: NAME, VERSION and OPEN"

        if reason is None and 'media_types' in plugin_info and not isinstance(plugin_info['media_types'], list):
            reason = 'Plugin media_types must be a list'

        if reason is None and not isinstance(plugin_info['module'], str):
            reason = 'Plugin module must be an string'

        if reason is None and not is_valid_version(plugin_info['version']):
            reason = 'Invalid format in plugin version'

        if reason is None and 'pull_accounting' in plugin_info and not isinstance(plugin_info['pull_accounting'], bool):
            reason = 'Plugin pull_accounting property must be a boolean'

        if reason is None and 'form' in plugin_info:
            if not isinstance(plugin_info['form'], dict):
                reason = 'Invalid format in form field, must be an object'
            else:
                reason = self._validate_plugin_form(plugin_info['form'])

        if reason is None and 'form_order' in plugin_info:
            if not isinstance(plugin_info['form_order'], list):
                return 'Invalid format in formOrder'

            if not 'form' in plugin_info:
                return 'Form Order cannot be specified without a form'

            # Check if all the form fields are included
            matched_keys = [key for key in plugin_info['form'].keys() if key in plugin_info['form_order']]

            if len(plugin_info['form'].keys()) != len(plugin_info['form_order']) or len(matched_keys) != len(plugin_info['form_order']):
                reason = 'If form order is provided all form keys need to be provided'

        return reason