Exemple #1
0
class ConferenceSchema(BaseSchema):
    id = fields.Integer(dump_only=True)
    tenant_uuid = fields.String(dump_only=True)
    name = fields.String(allow_none=True, validate=Length(max=128))
    preprocess_subroutine = fields.String(allow_none=True,
                                          validate=Length(max=39))
    max_users = fields.Integer(validate=Range(min=0))
    record = fields.Boolean()
    pin = fields.String(allow_none=True,
                        validate=(Length(max=80), Predicate('isdigit')))
    admin_pin = fields.String(allow_none=True,
                              validate=(Length(max=80), Predicate('isdigit')))
    quiet_join_leave = fields.Boolean()
    announce_join_leave = fields.Boolean()
    announce_user_count = fields.Boolean()
    announce_only_user = fields.Boolean()
    music_on_hold = fields.String(allow_none=True, validate=Length(max=128))
    links = ListLink(Link('conferences'))

    extensions = Nested(
        'ExtensionSchema',
        only=['id', 'exten', 'context', 'links'],
        many=True,
        dump_only=True,
    )
    incalls = Nested('IncallSchema',
                     only=['id', 'extensions', 'links'],
                     many=True,
                     dump_only=True)
Exemple #2
0
class ParkingLotSchema(BaseSchema):
    id = fields.Integer(dump_only=True)
    tenant_uuid = fields.String(dump_only=True)
    name = fields.String(allow_none=True, validate=Length(max=128))
    slots_start = fields.String(validate=(Length(max=40),
                                          Predicate('isdigit')),
                                required=True)
    slots_end = fields.String(validate=(Length(max=40), Predicate('isdigit')),
                              required=True)
    timeout = fields.Integer(validate=Range(min=0),
                             allow_none=True,
                             missing=45)
    music_on_hold = fields.String(validate=Length(max=128),
                                  allow_none=True,
                                  missing='default')
    links = ListLink(Link('parkinglots'))

    extensions = Nested(
        'ExtensionSchema',
        only=['id', 'exten', 'context', 'links'],
        many=True,
        dump_only=True,
    )

    @validates_schema
    def validate_slots_range(self, data, **kwargs):
        # validates_schema is executed before fields validator, so the required
        # fields is not yet checked
        if not data.get('slots_start') or not data.get('slots_end'):
            return

        if int(data['slots_start']) > int(data['slots_end']):
            raise ValidationError('It is not a valid range')
Exemple #3
0
class LineSchema(BaseSchema):
    id = fields.Integer(dump_only=True)
    tenant_uuid = fields.String(dump_only=True)
    name = fields.String(dump_only=True)
    protocol = fields.String(dump_only=True)
    device_id = fields.String(dump_only=True)
    device_slot = fields.Integer(dump_only=True)
    provisioning_extension = fields.String(dump_only=True)

    context = fields.String(required=True)
    provisioning_code = fields.String(validate=(Predicate('isdigit'),
                                                Length(equal=6)))
    position = fields.Integer(validate=Range(min=1))
    caller_id_name = fields.String(
        allow_none=True)  # Validate length callerid_name + num = max(160)
    caller_id_num = fields.String(validate=Predicate('isdigit'),
                                  allow_none=True)
    registrar = fields.String(validate=Length(max=128))
    links = ListLink(Link('lines'))

    application = Nested('ApplicationSchema',
                         only=['uuid', 'name', 'links'],
                         dump_only=True)
    endpoint_sip = Nested(
        'EndpointSIPSchema',
        # TODO(pc-m): Is it really useful to have the username/password on the relation?
        only=[
            'uuid',
            'label',
            'name',
            'auth_section_options.username',
            'links',
        ],
        dump_only=True,
    )
    endpoint_sccp = Nested('SccpSchema', only=['id', 'links'], dump_only=True)
    endpoint_custom = Nested('CustomSchema',
                             only=['id', 'interface', 'links'],
                             dump_only=True)
    extensions = Nested(
        'ExtensionSchema',
        only=['id', 'exten', 'context', 'links'],
        many=True,
        dump_only=True,
    )
    users = Nested(
        'UserSchema',
        only=['uuid', 'firstname', 'lastname', 'links'],
        many=True,
        dump_only=True,
    )
Exemple #4
0
class WizardContextIncallSchema(WizardContextInternalSchema):
    display_name = fields.String(validate=Length(min=3, max=128),
                                 missing='Incalls')
    did_length = fields.Integer(validate=Range(min=0, max=20))
    number_start = fields.String(validate=(Predicate('isdigit'),
                                           Length(max=16)))
    number_end = fields.String(validate=(Predicate('isdigit'), Length(max=16)))

    @validates_schema
    def validate_numbers(self, data):
        super(WizardContextIncallSchema, self).validate_numbers(data)
        if data.get('number_start') and data.get('number_end'):
            if not data.get('did_length'):
                raise ValidationError('Missing data for required field.',
                                      'did_length')
Exemple #5
0
class OutcallDestinationSchema(BaseDestinationSchema):
    outcall_id = fields.Integer(attribute='actionarg1', required=True)
    exten = fields.String(
        validate=(Predicate('isdigit'), Length(max=255)),
        attribute='actionarg2',
        required=True,
    )
Exemple #6
0
class DISADestinationSchema(ApplicationDestinationSchema):
    pin = fields.String(
        validate=(Predicate('isdigit'), Length(max=40)),
        allow_none=True,
        attribute='actionarg1',
    )
    context = fields.String(validate=Regexp(CONTEXT_REGEX),
                            attribute='actionarg2',
                            required=True)
Exemple #7
0
class RangeSchema(BaseSchema):
    start = fields.String(
        validate=(Predicate('isdigit'), Length(max=16)), required=True
    )
    end = fields.String(validate=(Predicate('isdigit'), Length(max=16)))

    def validate_range(self, start, end):
        if start > end:
            raise ValidationError(
                'Start of range must be lower than or equal to the end'
            )

    @validates_schema
    def validate_schema(self, data, **kwargs):
        if data.get('start') and data.get('end'):
            start = data.get('start')
            end = data.get('end')
            if len(start) != len(end):
                raise ValidationError('Start and end must be of the same length')
            self.validate_range(int(start), int(end))
Exemple #8
0
class LineSipSchema(BaseSchema):
    id = fields.Integer(dump_only=True)
    username = fields.String(validate=Regexp(USERNAME_REGEX))
    secret = fields.String(validate=Regexp(SECRET_REGEX))
    callerid = fields.String(validate=Regexp(CALLERID_REGEX), allow_none=True)
    device_slot = fields.Integer(validate=Range(min=0))
    context = fields.String(required=True)
    provisioning_extension = fields.String(
        validate=(Length(equal=6), Predicate('isdigit'))
    )
    links = ListLink(Link('lines'), Link('lines_sip'))
Exemple #9
0
class WizardContextInternalSchema(BaseSchema):
    display_name = fields.String(validate=Length(min=3, max=128),
                                 missing='Default')
    number_start = fields.String(validate=(Predicate('isdigit'),
                                           Length(max=16)),
                                 required=True)
    number_end = fields.String(validate=(Predicate('isdigit'), Length(max=16)),
                               required=True)

    @validates_schema
    def validate_numbers(self, data):
        if not data.get('number_start') and not data.get('number_end'):
            return
        if not data.get('number_start') or not data.get('number_end'):
            raise ValidationError(
                'Both numbers, number_start and number_end, must be set')

        if len(data['number_start']) != len(data['number_end']):
            raise ValidationError('Numbers do not have de same length')

        if int(data['number_start']) > int(data['number_end']):
            raise ValidationError('It is not a valid interval')
Exemple #10
0
class PagingSchema(BaseSchema):
    id = fields.Integer(dump_only=True)
    tenant_uuid = fields.String(dump_only=True)
    number = fields.String(validate=(Length(max=32), Predicate('isdigit')),
                           required=True)
    name = fields.String(validate=Length(max=128), allow_none=True)
    announce_caller = fields.Boolean()
    announce_sound = fields.String(validate=Length(max=64), allow_none=True)
    caller_notification = fields.Boolean()
    duplex = fields.Boolean(attribute='duplex_bool')
    ignore_forward = fields.Boolean()
    record = fields.Boolean(attribute='record_bool')
    enabled = fields.Boolean()
    links = ListLink(Link('pagings'))

    users_caller = Nested(
        'UserSchema',
        only=['uuid', 'firstname', 'lastname', 'links'],
        many=True,
        dump_only=True,
    )
    users_member = Nested(
        'UserSchema',
        only=['uuid', 'firstname', 'lastname', 'links'],
        many=True,
        dump_only=True,
    )

    @post_dump
    def wrap_users(self, data, **kwargs):
        users_member = data.pop('users_member', [])
        users_caller = data.pop('users_caller', [])

        if not self.only or 'members' in self.only:
            data['members'] = {'users': users_member}
        if not self.only or 'callers' in self.only:
            data['callers'] = {'users': users_caller}

        return data
class ParamSchema(Schema):
    class Meta:
        unknown = EXCLUDE

    admin_pw = Str(required=True)

    city = Str(required=True)

    country_code = Str(
        validate=[
            Length(2, 2),
            Predicate(
                "isupper",
                error="Non-uppercased characters aren't allowed",
            ),
        ],
        required=True,
    )

    email = Email(required=True)

    hostname = Str(required=True)

    org_name = Str(required=True)

    state = Str(required=True)

    optional_scopes = List(
        Str(),
        validate=ContainsOnly(OPTIONAL_SCOPES),
        missing=[],
    )

    ldap_pw = Str(missing="", default="")

    sql_pw = Str(missing="", default="")

    couchbase_pw = Str(missing="", default="")

    couchbase_superuser_pw = Str(missing="", default="")

    auth_sig_keys = Str(missing="")

    auth_enc_keys = Str(missing="")

    @validates("hostname")
    def validate_fqdn(self, value):
        fqdn = FQDN(value)
        if not fqdn.is_valid:
            raise ValidationError("Invalid FQDN format.")

    @validates("admin_pw")
    def validate_password(self, value, **kwargs):
        if not PASSWD_RGX.search(value):
            raise ValidationError(
                "Must be at least 6 characters and include "
                "one uppercase letter, one lowercase letter, one digit, "
                "and one special character."
            )

    @validates_schema
    def validate_ldap_pw(self, data, **kwargs):
        if "ldap" in data["optional_scopes"]:
            try:
                self.validate_password(data["ldap_pw"])
            except ValidationError as exc:
                raise ValidationError({"ldap_pw": exc.messages})

    @validates_schema
    def validate_ext_persistence_pw(self, data, **kwargs):
        err = {}
        scope_attr_map = [
            ("sql", "sql_pw"),
            ("couchbase", "couchbase_pw"),
        ]

        for scope, attr in scope_attr_map:
            # note we don't enforce custom password validation as cloud-based
            # databases may use password that not conform to our policy
            # hence we simply check for empty password only
            if scope in data["optional_scopes"] and data[attr] == "":
                err[attr] = ["Empty password isn't allowed"]

        if err:
            raise ValidationError(err)