def ready(self):
        import sys

        from django.conf import settings
        from django.core.exceptions import ImproperlyConfigured

        from wstore.models import Context
        from wstore.store_commons.utils.url import is_valid_url
        from wstore.ordering.inventory_client import InventoryClient
        from wstore.rss_adaptor.rss_manager import ProviderManager

        # Creates a new user profile when an user is created
        # post_save.connect(create_user_profile, sender=User)
        register_signals()

        testing = sys.argv[1:2] == ['test'] or sys.argv[1:2] == ['migrate']
        if not testing:
            # Validate that a correct site and local_site has been provided
            if not is_valid_url(settings.SITE) or not is_valid_url(settings.LOCAL_SITE):
                raise ImproperlyConfigured('SITE and LOCAL_SITE settings must be a valid URL')

            # Create context object if it does not exists
            if not len(Context.objects.all()):
                Context.objects.create(
                    failed_cdrs=[],
                    failed_upgrades=[]
                )

            inventory = InventoryClient()
            inventory.create_inventory_subscription()

            # Create RSS default aggregator and provider
            credentials = {
                'user': settings.STORE_NAME,
                'roles': [settings.ADMIN_ROLE],
                'email': settings.WSTOREMAIL
            }
            prov_manager = ProviderManager(credentials)

            try:
                prov_manager.register_aggregator({
                    'aggregatorId': settings.WSTOREMAIL,
                    'aggregatorName': settings.STORE_NAME,
                    'defaultAggregator': True
                })
            except Exception as e:  # If the error is a conflict means that the aggregator is already registered
                if e.response.status_code != 409:
                    raise e
Exemplo n.º 2
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 _get_asset_resources(self,
                             asset_t,
                             url,
                             provider_id=None,
                             prod_id=None):
        # Search the asset type
        asset_type = ResourcePlugin.objects.get(name=asset_t)

        # Validate location format
        if not is_valid_url(url):
            raise ProductError(
                'The location characteristic included in the product specification is not a valid URL'
            )

        # Use the location to retrieve the attached asset
        if not (provider_id is None):
            assets = Resource.objects.filter(download_link=url,
                                             provider=provider_id)
        elif not (prod_id is None):
            assets = Resource.objects.filter(download_link=url,
                                             product_id=prod_id)
        else:
            assets = Resource.objects.filter(download_link=url)

        return asset_type, assets
Exemplo n.º 4
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)
Exemplo n.º 5
0
    def _load_resource_info(self, provider, data, file_=None):

        if 'contentType' not in data:
            raise ValueError('Missing required field: contentType')

        resource_data = {
            'content_type': data['contentType'],
            'version': '',
            'resource_type': data.get('resourceType', ''),
            'state': '',
            'is_public': data.get('isPublic', False),
            'content_path': ''
        }

        current_organization = provider.userprofile.current_organization

        resource_data['metadata'] = data.get('metadata', {})

        # Check if the asset is a file upload or a service registration
        provided_as = 'FILE'
        if 'content' in data:
            if isinstance(data['content'], str) or isinstance(
                    data['content'], unicode):

                download_link = data['content']
                provided_as = 'URL'

            elif isinstance(data['content'], dict):
                resource_data['content_path'], download_link = \
                    self._save_resource_file(current_organization.name, data['content'])

            else:
                raise TypeError(
                    'content field has an unsupported type, expected string or object'
                )

        elif file_ is not None:
            resource_data[
                'content_path'], download_link = self._save_resource_file(
                    current_organization.name, file_)

        else:
            raise ValueError('The digital asset has not been provided')

        if not is_valid_url(download_link):
            raise ValueError('The provided content is not a valid URL')

        resource_data['link'] = download_link

        # Validate asset according to its type
        self._validate_asset_type(resource_data['resource_type'],
                                  resource_data['content_type'], provided_as,
                                  resource_data['metadata'])

        return resource_data, current_organization
def get_url(msg):
    correct = False
    while not correct:
        print msg
        domain = read_from_cmd()

        if not is_valid_url(domain):
            print "The domain " + domain + " is not a valid URL"
        else:
            correct = True

    return domain
Exemplo n.º 7
0
def get_url(msg):
    correct = False
    while not correct:
        print msg
        domain = read_from_cmd()

        if not is_valid_url(domain):
            print "The domain " + domain + " is not a valid URL"
        else:
            correct = True

    return domain
Exemplo n.º 8
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')
Exemplo n.º 9
0
def upgrade_resource(resource, data, file_=None):

    # Validate data
    if not "version" in data:
        raise ValueError("Missing a required field: Version")

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

    if not is_lower_version(resource.version, data["version"]):
        raise ValueError(
            "The new version cannot be lower that the current version: " + data["version"] + " - " + resource.version
        )

    # Check resource state
    if resource.state == "deleted":
        raise PermissionDenied("Deleted resources cannot be upgraded")

    # Save the old version
    resource.old_versions.append(
        ResourceVersion(
            version=resource.version, resource_path=resource.resource_path, download_link=resource.download_link
        )
    )

    # Update new version number
    resource.version = data["version"]

    # Update offerings
    if file_ or "content" in data:
        if file_:
            file_content = file_
        else:
            file_content = data["content"]

        # Create new file
        resource.resource_path = _save_resource_file(
            resource.provider.name, resource.name, resource.version, file_content
        )
        resource.download_link = ""
    elif "link" in data:
        if not is_valid_url(data["link"]):
            raise ValueError("Invalid URL format")

        resource.download_link = data["link"]
        resource.resource_path = ""
    else:
        raise ValueError("No resource has been provided")

    resource.save()
Exemplo n.º 10
0
    def _validate_product(self, provider, asset_t, media_type, url):
        # Search the asset type
        asset_type = ResourcePlugin.objects.get(name=asset_t)

        # Validate media type
        if len(asset_type.media_types) and media_type not in asset_type.media_types:
            raise ProductError('The media type characteristic included in the product specification is not valid for the given asset type')

        # Validate location format
        if not is_valid_url(url):
            raise ProductError('The location characteristic included in the product specification is not a valid URL')

        # Check if format is FILE
        is_file = False
        if 'FILE' in asset_type.formats:
            if 'URL' in asset_type.formats:
                site = Context.objects.all()[0].site
                if url.startswith(site.domain):
                    is_file = True
            else:
                is_file = True

        # If the asset is a file it must have been uploaded
        if is_file:
            try:
                asset = Resource.objects.get(download_link=url)
            except:
                raise ProductError('The URL specified in the location characteristic does not point to a valid digital asset')

            if asset.provider != provider:
                raise PermissionDenied('You are not authorized to use the digital asset specified in the location characteristic')

            if asset.content_type != media_type.lower():
                raise ProductError('The specified media type characteristic is different from the one of the provided digital asset')
        else:
            # If the asset is an URL and the resource model is created, that means that
            # the asset have been already included in another product
            if len(Resource.objects.filter(download_link=url)):
                raise ProductError('There is already an existing product specification defined for the given digital asset')

            # Create the new asset model
            asset = Resource.objects.create(
                resource_path='',
                download_link=url,
                provider=provider,
                content_type=media_type
            )

        return asset
Exemplo n.º 11
0
def upgrade_resource(resource, data, file_=None):

    # Validate data
    if not 'version' in data:
        raise ValueError('Missing a required field: Version')

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

    if not is_lower_version(resource.version, data['version']):
        raise ValueError('The new version cannot be lower that the current version: ' + data['version'] + ' - ' + resource.version)

    # Check resource state
    if resource.state == 'deleted':
        raise PermissionDenied('Deleted resources cannot be upgraded')

    # Save the old version
    resource.old_versions.append(ResourceVersion(
        version=resource.version,
        resource_path=resource.resource_path,
        download_link=resource.download_link
    ))

    # Update new version number
    resource.version = data['version']

    # Update offerings
    if file_ or 'content' in data:
        if file_:
            file_content = file_
        else:
            file_content = data['content']

        # Create new file
        resource.resource_path = _save_resource_file(resource.provider.name, resource.name, resource.version, file_content)
        resource.download_link = ''
    elif 'link' in data:
        if not is_valid_url(data['link']):
            raise ValueError('Invalid URL format')

        resource.download_link = data['link']
        resource.resource_path = ''
    else:
        raise ValueError('No resource has been provided')

    resource.save()
Exemplo n.º 12
0
def upgrade_resource(resource, user, data, file_=None):
    """
    Upgrades an existing resource to a new version
    """

    data = _validate_upgrade_resource_info(resource, data, file_=None)

    # Save the old version
    resource.old_versions.append(
        ResourceVersion(version=resource.version,
                        resource_path=resource.resource_path,
                        download_link=resource.download_link,
                        resource_usdl=resource.resource_usdl,
                        resource_uri=resource.resource_uri))

    # Update new version number
    resource.version = data['version']

    # Update offerings
    if file_ or 'content' in data:
        if file_:
            file_content = file_
        else:
            file_content = data['content']

        # Create new file
        resource.resource_path = _save_resource_file(resource.provider.name,
                                                     resource.name,
                                                     resource.version,
                                                     file_content)
        resource.download_link = ''
    elif 'link' in data:
        if not is_valid_url(data['link']):
            raise ValueError('Invalid URL format')

        resource.download_link = data['link']
        resource.resource_path = ''
    else:
        raise ValueError('No resource has been provided')

    # Save the resource
    decorated_save = _get_decorated_save('upgrade')
    decorated_save(resource, user)
Exemplo n.º 13
0
def register_resource(provider, data, file_=None):
    """
    Registers a new resource for the given provider
    """

    resource_data, current_organization = _validate_resource_info(provider,
                                                                  data,
                                                                  file_=file_)

    if not file_:
        if 'content' in data:
            resource_data['content_path'] = _save_resource_file(
                current_organization.name, resource_data['name'],
                resource_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')

            validation = validate_dataset(provider, data['link'])

            if not validation[0]:
                raise PermissionDenied(validation[1])

            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, resource_data['name'],
            resource_data['version'], file_)
        resource_data['link'] = ''

    resource_data['metadata'] = data.get('metadata', {})

    # Create the resource entry in the database
    _create_resource_model(current_organization, provider, resource_data)
Exemplo n.º 14
0
def upgrade_resource(resource, user, data, file_=None):
    """
    Upgrades an existing resource to a new version
    """

    data = _validate_upgrade_resource_info(resource, data, file_=None)

    # Save the old version
    resource.old_versions.append(ResourceVersion(
        version=resource.version,
        resource_path=resource.resource_path,
        download_link=resource.download_link,
        resource_usdl=resource.resource_usdl,
        resource_uri=resource.resource_uri
    ))

    # Update new version number
    resource.version = data['version']

    # Update offerings
    if file_ or 'content' in data:
        if file_:
            file_content = file_
        else:
            file_content = data['content']

        # Create new file
        resource.resource_path = _save_resource_file(resource.provider.name, resource.name, resource.version, file_content)
        resource.download_link = ''
    elif 'link' in data:
        if not is_valid_url(data['link']):
            raise ValueError('Invalid URL format')

        resource.download_link = data['link']
        resource.resource_path = ''
    else:
        raise ValueError('No resource has been provided')

    # Save the resource
    decorated_save = _get_decorated_save('upgrade')
    decorated_save(resource, user)
Exemplo n.º 15
0
def register_resource(provider, data, file_=None):
    """
    Registers a new resource for the given provider
    """

    resource_data, current_organization = _validate_resource_info(provider, data, file_=file_)

    if not file_:
        if 'content' in data:
            resource_data['content_path'] = _save_resource_file(current_organization.name, resource_data['name'], resource_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')

            validation = validate_dataset(provider, data['link'])

            if not validation[0]:
                raise PermissionDenied(validation[1])

            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, resource_data['name'], resource_data['version'], file_)
        resource_data['link'] = ''

    resource_data['metadata'] = data.get('metadata', {})

    # Create the resource entry in the database
    _create_resource_model(current_organization, provider, resource_data)
Exemplo n.º 16
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)
Exemplo n.º 17
0
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)
Exemplo n.º 18
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')
Exemplo n.º 19
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),
    )
Exemplo n.º 20
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')
Exemplo n.º 21
0
    def update(self, request, org):

        # Get the organization
        try:
            organization = Organization.objects.get(name=org)
        except:
            return build_response(request, 404, 'Organization not found')

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

        if not request.user.is_staff and request.user.pk not in organization.managers:
            return build_response(request, 403, 'Forbidden')

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

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

                organization.notification_url = data['notification_url']

            # Load the tax address
            new_taxaddr = {}
            if 'tax_address' in data and data['tax_address'] != {}:
                new_taxaddr = {
                    'street': data['tax_address']['street'],
                    'postal': data['tax_address']['postal'],
                    'city': data['tax_address']['city'],
                    'country': data['tax_address']['country']
                }

            organization.tax_address = new_taxaddr

            # Load the payment info
            new_payment = {}
            if 'payment_info' in data and data['payment_info'] != {}:

                number = data['payment_info']['number']

                if not is_valid_credit_card(number):
                    if 'number' in organization.payment_info and \
                            is_hidden_credit_card(number, organization.payment_info['number']):
                        number = organization.payment_info['number']
                    else:
                        raise Exception('Invalid credit card number')

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

            if 'limits' in data:
                limits = _check_limits(data['limits'])
                currency = limits['currency']
                # Get default RSS
                rss = RSS.objects.all()[0]
                rss_factory = RSSManagerFactory(rss)
                exp_manager = rss_factory.get_expenditure_manager(
                    rss.access_token)

                try:
                    exp_manager.set_actor_limit(limits, organization)
                except HTTPError as e:
                    if e.code == 401:
                        rss.refresh_token()
                        exp_manager.set_credentials(rss.access_token)
                        exp_manager.set_actor_limit(limits, organization)
                    else:
                        raise e

                # Save limits
                limits['currency'] = currency
                organization.expenditure_limits = limits

            organization.payment_info = new_payment
            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, 200, 'OK')
    def _validate_product(self, provider, asset_t, media_type, url):
        # Search the asset type
        asset_type = ResourcePlugin.objects.get(name=asset_t)

        # Validate media type
        if len(asset_type.media_types
               ) and media_type not in asset_type.media_types:
            raise ProductError(
                'The media type characteristic included in the product specification is not valid for the given asset type'
            )

        # Validate location format
        if not is_valid_url(url):
            raise ProductError(
                'The location characteristic included in the product specification is not a valid URL'
            )

        site = Context.objects.all()[0].site

        # If the asset is a file it must have been uploaded
        if 'FILE' in asset_type.formats and (
            ('URL' not in asset_type.formats) or
            ('URL' in asset_type.formats and url.startswith(site.domain))):

            try:
                asset = Resource.objects.get(download_link=url)
            except:
                raise ProductError(
                    'The URL specified in the location characteristic does not point to a valid digital asset'
                )

            if asset.provider != provider:
                raise PermissionDenied(
                    'You are not authorized to use the digital asset specified in the location characteristic'
                )

            if asset.content_type != media_type.lower():
                raise ProductError(
                    'The specified media type characteristic is different from the one of the provided digital asset'
                )

            asset.has_terms = self._has_terms
            asset.save()
        else:
            # If the asset is an URL and the resource model is created, that means that
            # the asset have been already included in another product
            resources = Resource.objects.filter(download_link=url)
            error = False
            for res in resources:
                # The asset has been attached so it already exists
                if res.product_id:
                    error = True
                else:
                    res.delete()

            if error:
                raise ProductError(
                    'There is already an existing product specification defined for the given digital asset'
                )

            # Create the new asset model
            asset = Resource.objects.create(has_terms=self._has_terms,
                                            resource_path='',
                                            download_link=url,
                                            provider=provider,
                                            content_type=media_type)
            self.rollback_logger['models'].append(asset)

        return asset
Exemplo n.º 23
0
 def test_valid_absolute_url_http(self):
     self.assertTrue(is_valid_url("http://data.source.commy/path"))
Exemplo n.º 24
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')
Exemplo n.º 25
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')
Exemplo n.º 26
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)
    )
Exemplo n.º 27
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')
Exemplo n.º 28
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)
Exemplo n.º 29
0
 def test_valid_absolute_url_https_query(self):
     self.assertTrue(is_valid_url("https://data.source.commy/path?a=b"))
Exemplo n.º 30
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')
import sys

from django.conf import settings
from django.core.exceptions import ImproperlyConfigured

from wstore.models import Context
from wstore.store_commons.utils.url import is_valid_url
from wstore.ordering.inventory_client import InventoryClient
from wstore.rss_adaptor.rss_manager import ProviderManager

testing = sys.argv[1:2] == ['test']

if not testing:
    # Validate that a correct site and local_site has been provided
    if not is_valid_url(settings.SITE) or not is_valid_url(
            settings.LOCAL_SITE):
        raise ImproperlyConfigured(
            'SITE and LOCAL_SITE settings must be a valid URL')

    # Create context object if it does not exists
    if not len(Context.objects.all()):
        Context.objects.create()

    inventory = InventoryClient()
    inventory.create_inventory_subscription()

    # Create RSS default aggregator and provider
    credentials = {
        'user': settings.STORE_NAME,
        'roles': ['provider'],
Exemplo n.º 32
0
    def update(self, request, org):

        # Get the organization
        try:
            organization = Organization.objects.get(name=org)
        except:
            return build_response(request, 404, 'Organization not found')

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

        if not request.user.is_staff and request.user.pk not in organization.managers:
            return build_response(request, 403, 'Forbidden')

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

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

                organization.notification_url = data['notification_url']

            # Load the tax address
            new_taxaddr = {}
            if 'tax_address' in data and data['tax_address'] != {}:
                new_taxaddr = {
                    'street': data['tax_address']['street'],
                    'postal': data['tax_address']['postal'],
                    'city': data['tax_address']['city'],
                    'country': data['tax_address']['country']
                }

            organization.tax_address = new_taxaddr

            # Load the payment info
            new_payment = {}
            if 'payment_info' in data and data['payment_info'] != {}:

                number = data['payment_info']['number']

                if not is_valid_credit_card(number):
                    if 'number' in organization.payment_info and \
                            is_hidden_credit_card(number, organization.payment_info['number']):
                        number = organization.payment_info['number']
                    else:
                        raise Exception('Invalid credit card number')

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

            if 'limits' in data:
                limits = _check_limits(data['limits'])
                currency = limits['currency']
                # Get default RSS
                rss = RSS.objects.all()[0]
                rss_factory = RSSManagerFactory(rss)
                exp_manager = rss_factory.get_expenditure_manager(rss.access_token)

                try:
                    exp_manager.set_actor_limit(limits, organization)
                except HTTPError as e:
                    if e.code == 401:
                        rss.refresh_token()
                        exp_manager.set_credentials(rss.access_token)
                        exp_manager.set_actor_limit(limits, organization)
                    else:
                        raise e

                # Save limits
                limits['currency'] = currency
                organization.expenditure_limits = limits

            organization.payment_info = new_payment
            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, 200, 'OK')
Exemplo n.º 33
0
 def test_invalid_url_number(self):
     self.assertFalse(is_valid_url(1))
Exemplo n.º 34
0
 def test_invalid_url_protocol(self):
     self.assertFalse(is_valid_url("sftp://localhost/"))
Exemplo n.º 35
0
 def test_invalid_url_relative_schema(self):
     self.assertFalse(is_valid_url("//my/path"))
Exemplo n.º 36
0
 def test_invalid_url_list(self):
     self.assertFalse(is_valid_url(("sftp://localhost@c", )))
Exemplo n.º 37
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'
    )
Exemplo n.º 38
0
 def test_invalid_characters(self):
     self.assertFalse(is_valid_url("http://data.source.commy/path a"))
Exemplo n.º 39
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)
Exemplo n.º 40
0
 def test_valid_absolute_url_https_port(self):
     self.assertTrue(is_valid_url("https://data.source.commy:300/path"))
Exemplo n.º 41
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')
Exemplo n.º 42
0
 def test_valid_absolute_url_https_ckan(self):
     self.assertTrue(
         is_valid_url(
             "https://data.opplafy.eu/dataset/4d3d9728-39bb-4749-8c8f-d9cea51abe4b"
         ))
Exemplo n.º 43
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')