예제 #1
0
    def move(self):
        if not self.patch_request.is_component or self.patch_request.parent_type not in self.component_list_types:
            raise ValidationException('Invalid operation for property type')

        if self.patch_request.property_value['sourceIndex'] is None \
            or self.patch_request.property_value['targetIndex'] is None:
            raise ValidationException('Invalid move indices')

        components = self._get_property_value(self.patch_request.parent_name,
                                              [])
        source_index = self.patch_request.property_value.get('sourceIndex', -1)
        target_index = self.patch_request.property_value.get('targetIndex', -1)

        if source_index < 0 or target_index < 0 \
            or source_index > len(components) or target_index> len(components):
            raise ValidationException('Index out of range')

        component = components[source_index]

        if component is None or component[
                'id'] != self.patch_request.component_id:
            raise ValidationException('Invalid component id')

        components.insert(target_index, components.pop(source_index))
        self._set_property_value(self.patch_request.parent_name, components)

        patch_value = {
            'sourceIndex': source_index,
            'targetIndex': target_index
        }
        return self._create_patch_value('move', True,
                                        self.patch_request.parent_name,
                                        patch_value)
예제 #2
0
    def edit(self):
        patch_value = None

        if self.patch_request.is_component:
            component = None
            if self.patch_request.parent_type in self.component_selector_types:
                component = self._get_property_value(
                    self.patch_request.parent_name, {})
            elif self.patch_request.parent_type in self.component_list_types:
                components = self._get_property_value(
                    self.patch_request.parent_name, [])
                component = next(
                    (c for c in components
                     if c['id'] == self.patch_request.component_id), None)
            else:
                raise ValidationException('Invalid component type')

            if component is None:
                raise ValidationException('Invalid component')

            new_value = self._read_property_value(
                self._request_json.get('propertyDef', {}),
                self.patch_request.property, self.patch_request.property_value)
            component['componentData'][
                self.patch_request.property.name] = new_value
            if self.patch_request.parent_type in self.component_list_types:
                component['displayName'] = self._update_display_name(
                    component, new_value)

            custom_result = self._get_custom_component_properties()
            if custom_result is not None:
                new_value = custom_result

            patch_value = {
                'id': component.get('id'),
                'componentData': {
                    self.patch_request.property.name: new_value
                },
                'displayName': component['displayName']
            }
        else:
            new_value = self._read_property_value(
                self._request_json.get('propertyDef', {}),
                self.patch_request.property, self.patch_request.property_value)
            patch_value = self._set_property_value(
                self.patch_request.property.name, new_value)

        property_name = self.patch_request.parent_name if self.patch_request.is_component else self.patch_request.property.name
        return self._create_patch_value('edit',
                                        self.patch_request.is_component,
                                        property_name, patch_value)
예제 #3
0
    def read(self, data):
        val = super().read(data)

        if self.required and (val is None or val == ''):
            raise ValidationException(
                f'Field {self.property.name} is required',
                api_field=self.property.name)

        if self.maxlength > 0 and val is not None and len(
                val) > self.maxlength:
            raise ValidationException(
                f'Field {self.property.name} cannot be more than {self.maxlength} characters long.',
                api_field=self.property.name)
        return val
예제 #4
0
    def post(self):
        prefix = self.get_prefix()
        file = prefix + request.get_json()['file'] + '/'
        files = self.get_all()
        if next((x for x in files if x['name'] == request.get_json()['file']),
                None) is not None:
            raise ValidationException('File already exists')

        content, content_type = self.read_content()
        s3 = self.get_s3()

        metadata = {
            'author': g.token_data.get('user'),
            'containerversionid': str(g.token_data.get('containerVersionId'))
        }
        s3.Object(self.get_bucket(), file).put()
        s3.Object(self.get_bucket(),
                  file + 'draft').put(Body=content,
                                      Metadata=metadata,
                                      ContentType=content_type)
        s3.Object(self.get_bucket(),
                  file + 'production').put(Body=b'',
                                           Metadata=metadata,
                                           ContentType=content_type)
        return file
예제 #5
0
    def get_property_type(self, type_name):
        types = {
            'asset-select': AssetSelectPropertyType,
            'asset-field': AssetFieldPropertyType,
            'text': TextPropertyType,
            'color': ColorPropertyType,
            'image-upload': ImagePropertyType,
            'component': ComponentPropertyType,
            'components': ComponentsPropertyType,
            'checkbox': CheckboxPropertyType,
            'toggle': TogglePropertyType,
            'translated-text': TranslatedTextProperty,
            'dropdown': DropdownPropertyType,
            'dropdown-options': DropdownOptionsPropertyType,
            'multiselect': MultiselectPropertyType,
            'numeric': NumericPropertyType,
            'page-link': PageLinkPropertyType,
            'code-editor': CodeEditorPropertyType,
            'theme-color': ThemeColorPropertyType,
            'admin-launcher': AdminLauncherPropertyType,
            'html-editor': HtmlEditorPropertyType,
            'dynamic-component': DynamicComponentPropertyType,
            'dynamic-components': DynamicComponentsPropertyType,
            'data-column-components': DataColumnComponentsPropertyType,
            'font': FontPropertyType,
        }

        prop_type = types.get(type_name)
        if prop_type is None:
            raise ValidationException('Unknown type name:' + type_name)

        return prop_type(self)
    def read(self, data):
        val = super().read(data)

        if val == "":
            val = self.property.default

        try:
            val = int(val)

        except Exception as e:
            raise ValidationException('Invalid Number: ' + str(val))

        if (self.too_low(val)) or (self.too_high(val)):
            raise ValidationException('Invalid Number: ' + str(val) + \
                ' - must be in range ' + str(self.min) + ' to ' + str(self.max))

        return val
예제 #7
0
  def validate(self, rec):
    if not db:
      raise Exception('Unable to validate record without db context')

    db.session.flush()
    required = [col.name for col in self._model_class.__table__.columns if not col.nullable if col.name != 'id']
    for r in required:
      if getattr(rec, r) is None or not str(getattr(rec, r)).strip():
        raise ValidationException('Field is Required', self.underscore_to_camel(r))
예제 #8
0
    def get_presign_url(self, method, path=''):

        content_type = request.get_json()['contentType']
        prefix = self.get_prefix()
        file = ''

        if method == 'POST':
            file = prefix + request.get_json()['file'] + '/'
            files = self.get_all()
            if next(
                (x for x in files if x['name'] == request.get_json()['file']),
                    None) is not None:
                raise ValidationException('File already exists')
        else:
            file = prefix + path + '/'

        s3_client = self.get_s3_client()
        metadata = {
            'author': g.token_data.get('user'),
            'containerversionid': str(g.token_data.get('containerVersionId'))
        }
        metadata_presign = {
            'x-amz-meta-author':
            g.token_data.get('user'),
            'x-amz-meta-containerversionid':
            str(g.token_data.get('containerVersionId'))
        }
        #Generate presigned post url good for 3 minutes for upload
        response = s3_client.generate_presigned_post(
            Bucket=self.get_bucket(),
            Key=file + 'draft',
            Fields=metadata_presign,
            Conditions=[
                ['eq', '$Content-Type', content_type],
                {
                    'success_action_status': '201'
                },
                {
                    'x-amz-meta-author': g.token_data.get('user')
                },
                {
                    'x-amz-meta-containerversionid':
                    str(g.token_data.get('containerVersionId'))
                },
            ],
            ExpiresIn=60 * 15)

        #go ahead and create folder and empty production version
        if method == 'POST':
            s3 = self.get_s3()
            s3.Object(self.get_bucket(), file).put()
            s3.Object(self.get_bucket(),
                      file + 'production').put(Body=b'',
                                               Metadata=metadata,
                                               ContentType=content_type)

        return response
예제 #9
0
    def delete(self):
        if not self.patch_request.is_component or self.patch_request.parent_type not in self.component_list_types:
            raise ValidationException('Invalid operation for property type')

        if self.patch_request.component_id is None:
            raise ValidationException('Invalid component id')

        components = self._get_property_value(self.patch_request.parent_name,
                                              [])
        component = next((c for c in components
                          if c['id'] == self.patch_request.component_id), None)
        if component is None:
            raise ValidationException('Invalid component id')

        components.remove(component)
        self._set_property_value(self.patch_request.parent_name, components)

        return self._create_patch_value('delete', True,
                                        self.patch_request.parent_name,
                                        self.patch_request.component_id)
예제 #10
0
    def read(self, data):
        val = super().read(data)
        if val is None:
            val = '#fff'

        val = val.lower()

        if not bool(_rgbstring.match(val)):
            raise ValidationException(400, 'Invalid Color: ' + val)

        return val
예제 #11
0
    def get_expression(self, column_name, column, op, value):
        if isinstance(value, str) and value in self.subs:
            value = self.subs[value]

        original_value = value
        if isinstance(value, str) and value.lower() == '_null_':
            value = None

        if column is not None:
            if isinstance(column, JSONB):
                pass
            if str(column.type) == 'DATETIME' or str(column.type) == 'DATE':
                value = parse(value)
            elif str(column.type) == 'BIGINT' or str(column.type) == 'INT':
                value = int(str(value))
            elif str(column.type) == 'FLOAT':
                value = float(str(value))
            elif str(column.type) == 'BOOLEAN':
                value = str(value).lower() == 'true'
                if op != 'eq':
                    raise ValidationException(
                        'Booleans can only be filtered using an equals operator',
                        api_field=column_name)

            if op == 'eq':
                if str(column.type) == 'BIGINT[]':
                    return column.any(value)
                else:
                    return column == value
            elif op == 'neq':
                return column != value
            elif op == 'gt':
                return column > value
            elif op == 'gte':
                return column >= value
            elif op == 'lt':
                return column < value
            elif op == 'lte':
                return column <= value
            elif op == 'sw':
                return cast(column, String).ilike(original_value + '%')
            elif op == 'ct':
                return cast(column, String).ilike('%' + original_value + '%')
            elif op == 'aeq':
                return and_(column.op('@>')(value), column.op('<@')(value))
            elif op == 'adeq':
                return and_(column.op('@>')(value), column.op('<@')(value))
            elif op == 'act':
                return column.contains(value)
            elif op == 'jsonbstrct':  # Checks if jsonb array contains a given string
                return column.op('?')(value)
            elif op == 'jsonbstrctd':  # Checks if jsonb array contains a given integer
                return column.op('@>')(value)
예제 #12
0
    def add(self):
        if not self.patch_request.is_component:
            raise ValidationException('Only components can be added')

        if not self.patch_request.is_component or self.patch_request.parent_type not in self.component_list_types:
            raise ValidationException('Invalid operation for property type')

        components = self._get_property_value(self.patch_request.parent_name,
                                              [])
        new_component = self._parse_component_data()

        if self.is_component_valid(
                self.patch_request.component['componentType']):
            component_def = self.get_component_def(
                self.patch_request.component['componentType'])
            new_component['componentTemplate'] = component_def.get(
                'template', '')
        components.append(new_component)

        return self._create_patch_value('add', self.patch_request.is_component,
                                        self.patch_request.parent_name,
                                        new_component)
  def read(self, data):
    val = data.get(self.property.name)

    check_hash = { str(x): x for x in self.property.options }
    check_hash['None'] = None

    if val is None:
      val = self.property.default

    if str(val) not in check_hash:
      raise ValidationException('Invalid Value: ' + str(val) + ' - must be in set ' + ','.join(list(self.property.options.keys())))

    return val
예제 #14
0
    def read_content(self):
        data = request.get_json()

        contents = data.get('contents')
        if contents is None:
            raise ValidationException('file must be uploaded as base-64 data',
                                      api_field='contents')

        content_type = 'binary/octet-stream'
        content = b''

        if ',' in contents:
            content_type = contents.split(',')[0].split(':')[1].split(';')[0]
            contents = contents.split(',')[1]

        content = base64.b64decode(contents)

        return content, content_type
예제 #15
0
    def _parse_component_data(self):
        if not self.patch_request.is_component:
            raise ValidationException('Invalid operation for property type')

        future_prop_data = {}
        new_component = self.patch_request.property_value
        component_prop_json = self._request_json.get('componentDef',
                                                     {}).get('properties', [])
        for prop in self.patch_request.component.get('properties', []):
            prop_json = next(
                (p for p in component_prop_json if p['name'] == prop.name),
                None)
            future_prop_data[prop.name] = \
              self._read_property_value(prop_json, prop, new_component.get('componentData', {}).get(prop.name, prop.default))

        new_component['componentData'] = future_prop_data

        return self._pack_component(new_component)
예제 #16
0
    def replace(self):
        if not self.patch_request.is_component or self.patch_request.parent_type not in self.component_selector_types:
            raise ValidationException('Invalid operation for property type')

        patch_value = None
        if self.patch_request.component_type is None:
            patch_value = self._set_property_value(
                self.patch_request.parent_name,
                self._get_none_component_type())
        else:
            new_component = self._parse_component_data()
            component_type = self.patch_request.component.get('componentType')
            if component_type is None:
                component_type = self.patch_request.component.get('type')
            if self.is_component_valid(component_type):
                component_def = self.get_component_def(component_type)
                new_component['componentTemplate'] = component_def.get(
                    'template', '')
            patch_value = self._set_property_value(
                self.patch_request.parent_name, new_component)

        return self._create_patch_value('replace', True,
                                        self.patch_request.parent_name,
                                        patch_value)
    def read(self, data):
        val = data.get(self.property.name, [])
        components = []

        for c in val:
            comp_values = {}

            component_type = c.get('componentType', '__NOTYPE__')
            component_data = c.get('componentData', {})
            component_id = c.get('id', None)
            component_json = next(
                (x for x in self.property.options.get('components', [])
                 if x['type'] == component_type), None)
            if component_json is None:
                raise ValidationException('Invalid Dynamic Component Value: ' +
                                          component_type)

            components.append(
                DynamicComponentPropertyType.get_component_data(
                    component_id, component_type, component_data,
                    component_json))

        self.value = components
        return components
예제 #18
0
    def read(self, data):
        val = super().read(data)

        components = []
        for c in val:
            comp_values = {}

            component_type = c.get('componentType',
                                   c.get('type', '__NOTYPE__'))
            component_data = c.get('componentData', {})
            component_json = next(
                (x for x in self.property.options.get('components', [])
                 if x['type'] == component_type), None)
            if component_json:
                from ..components import Components
                component = Components.DynamicComponent.from_json(
                    component_json)
                component_data = component.read(component_data)

                display_name = component.label
                additional_display = component_data.get('title')
                if additional_display and isinstance(
                        additional_display,
                        dict) and 'en-us' in additional_display:
                    display_name = display_name + ' - ' + str(
                        additional_display['en-us'])
                elif additional_display:
                    display_name = display_name + ' - ' + str(
                        additional_display)

                result = {
                    'id':
                    c.get('id'),
                    'componentType':
                    c.get('componentType', c.get('type')),
                    'componentData':
                    c.get('componentData', {}),
                    'displayName':
                    display_name,
                    'versionId':
                    c.get('versionId', component.component_set_version_id),
                    'componentSetId':
                    c.get('componentSetId', component.component_set_id),
                    'icon':
                    c.get('icon')
                }

                display_name_template = None
                if component.display_name is not None and '{{' in component.display_name:
                    display_name_template = component.display_name

                if component.component_type in g.all_components:
                    component_meta = g.all_components.get(
                        component.component_type, {})
                    # Flag the component as being used so widget proxy can update component set namespace version table
                    component_meta.update({'isUsed': True})

                    result['componentTemplate'] = component_meta.get(
                        'template', '')
                    display_name_template = component_meta.get(
                        'displayNameTemplate')

                if display_name_template is None and 'displayNameTemplate' in component_json:
                    display_name_template = component_json.get(
                        'displayNameTemplate')

                if display_name_template:
                    rtemplate = Environment(
                        loader=BaseLoader).from_string(display_name_template)
                    result['displayName'] = rtemplate.render(**result)

                components.append(result)
            else:
                raise ValidationException('Invalid Value: ' + component_type)

        self.value = components
        return components
예제 #19
0
 def default(self):
     raise ValidationException('Invalid patch operation')
예제 #20
0
 def get_component_def(self, component_type):
     raise ValidationException('Not implemented')