Пример #1
0
class HttpPush(db_sql.Model):
    __tablename__ = 'http_push'

    __table_args__ = {'schema': 'nwkserver'}

    app_eui = db_sql.Column(BINARY(8),
                            ForeignKey(Application.app_eui,
                                       ondelete='CASCADE',
                                       onupdate='CASCADE'),
                            primary_key=True)
    url = db_sql.Column(String(200), nullable=False)

    def obj_to_dict(self):
        return {'open': True, 'url': self.url}

    def add(self):
        db_sql.session.add(self)
        db_sql.session.commit()

    def delete(self):
        db_sql.session.delete(self)
        db_sql.session.commit()

    def update(self):
        db_sql.session.commit()
Пример #2
0
class Role(db.Model):
    __bind_key__ = 'lorawan'
    __table_args__ = {'schema': 'lorawan'}
    __tablename__ = 'role'

    id = db.Column(db.Integer(), primary_key=True)
    name = db.Column(db.String(50), unique=True)
Пример #3
0
class UserRoles(db.Model):
    __bind_key__ = 'lorawan'
    __tablename__ = 'user_roles'
    __table_args__ = {'schema': 'lorawan'}

    db.Column(db.Integer(), primary_key=True)
    user_id = db.Column(db.Integer(), db.ForeignKey('lorawan.user.id', ondelete='CASCADE'))
    role_id = db.Column(db.Integer(), db.ForeignKey('lorawan.role.id', ondelete='CASCADE'))
    PrimaryKeyConstraint(user_id, role_id)
Пример #4
0
class Token(db.Model):
    __bind_key__ = 'lorawan'
    __table_args__ = {'schema': 'lorawan'}
    id = db.Column(db.Integer, primary_key=True)
    client_id = db.Column(
        db.String(40),
        db.ForeignKey(Client.client_id),
        nullable=False,
    )
    client = db.relationship('Client')

    user_id = db.Column(db.Integer, db.ForeignKey(User.id))

    user = db.relationship('User')

    # currently only bearer is supported
    token_type = db.Column(db.String(40))

    access_token = db.Column(db.String(255), unique=True)
    refresh_token = db.Column(db.String(255), unique=True)
    expires = db.Column(db.DateTime)
    _scopes = db.Column(db.Text)

    def delete(self):
        db.session.delete(self)
        db.session.commit()
        return self

    @property
    def scopes(self):
        if self._scopes:
            return self._scopes.split()
        return []
Пример #5
0
class UserInvitation(db.Model):
    __bind_key__ = 'lorawan'
    __tablename__ = 'user_invite'
    __table_args__ = {'schema': 'lorawan'}

    id = db.Column(db.Integer, primary_key=True)
    email = db.Column(db.String(255))
    # save the user of the invitee
    invited_by_user_id = db.Column(db.Integer, db.ForeignKey('lorawan.user.id'))
    # token used for registration page to identify user registering
    token = db.Column(db.String(100), nullable=False, server_default='')
    used_by = db.Column(db.Integer, db.ForeignKey('lorawan.user.id'))
    create_at = db.Column(db.DateTime(), nullable=False)
    expired = db.Column(db.Boolean())
Пример #6
0
class Gateway(db_sql.Model):
    redis_fields = (Field.user_id, Field.platform, Field.model,
                    Field.freq_plan, Field.public, Field.disable,
                    Field.location)
    __vars_can_write = (Field.platform, Field.model, Field.freq_plan,
                        Field.public, Field.disable, Field.name,
                        Field.location)
    _assert_switcher = {
        Field.user_id: Assertions.a_not_negative_int,
        Field.id: Assertions.a_eui_64,
        Field.mac_addr: Assertions.a_eui_48,
        Field.name: Assertions.a_str,
        Field.platform: Platform.assert_isinstanceof,
        Field.freq_plan: FrequencyPlan.assert_isinstanceof,
        Field.model: Model.assert_isinstanceof,
        Field.public: Assertions.a_bool,
        Field.disable: Assertions.a_bool,
        Field.restart: Assertions.a_bool,
        Field.location: Location.assert_isinstanceof,
        Field.time: Assertions.a_int,
    }

    __table_args__ = {'schema': 'nwkserver'}
    __tablename__ = 'gateway'

    id = Column(BINARY(8), primary_key=True)
    name = Column(String(50))
    user_id = db_sql.Column(db_sql.Integer(),
                            ForeignKey(User.id,
                                       ondelete='CASCADE',
                                       onupdate='CASCADE'),
                            nullable=False)

    @orm.reconstructor
    def init_on_load(self):
        self.mac_addr = eui_64_to_48(self.id)
        info = db0.hgetall(ConstDB.gateway + hexlify(self.id).decode())
        self.freq_plan = FrequencyPlan(info[b'freq_plan'].decode())
        self.public = bool(int(info[b'public']))
        self.disable = bool(int(info[b'disable']))
        self.platform = Platform[info[b'platform'].decode()]
        self.model = Model[info[b'model'].decode()]
        location = info.get(b'location')
        if location is not None:
            self.location = Location.objects.str_to_obj(location.decode())
        else:
            self.location = Location(0.0, 0.0, 0)
        time = db3.get(ConstDB3.T_GATEWAY + hexlify(self.id).decode())
        if time is not None:
            self.time = int(time)

    def __setattr__(self, key, value):
        try:
            attr = getattr(self, key)
            if attr is not None and key not in self.__vars_can_write:
                raise ReadOnlyDeny
        except AttributeError:
            pass
        if key in self._assert_switcher:
            self._assert_switcher[key](value)
        super.__setattr__(self, key, value)

    def __init__(self,
                 user_id,
                 mac_addr,
                 name,
                 platform,
                 model,
                 freq_plan=FrequencyPlan.EU863_870,
                 public=True,
                 disable=False,
                 location=None):
        """
        :param id: 8 bytes
        :param name: str
        :param platform: Platform
        :return:
        """
        self.user_id = user_id
        self.id = eui_48_to_64(mac_addr)
        self.name = name
        self.platform = platform
        self.freq_plan = freq_plan
        self.public = public
        self.disable = disable
        self.model = model
        if location is not None:
            self.location = location
        else:
            self.location = Location(0.0, 0.0, 0)

    def _zip_vars(self):
        return dict(
            zip(self.redis_fields,
                (self.user_id, self.platform.name, self.model.name,
                 self.freq_plan.value, self.public.real, self.disable.real,
                 str(self.location))))

    def _zip_vars_can_write(self):
        dd = {}
        for field in self.redis_fields:
            if field in self.__vars_can_write:
                value = getattr(self, field)
                if isinstance(value, enum.Enum):
                    value = value.value if field == Field.freq_plan else value.name
                elif isinstance(value, bool):
                    value = value.real
                dd[field] = value
        return dd

    def send_restart_request(self):
        db0.hset(ConstDB.gateway + hexlify(self.id).decode(), 'restart', 1)

    def save(self):
        db_sql.session.add(self)
        id_str = hexlify(self.id).decode()
        key = ConstDB.gateway + id_str
        if db0.exists(key):
            raise KeyDuplicateError(key)
        db0.hmset(key, self._zip_vars())
        #save to sql
        db_sql.session.commit()
        db_sql.session.registry.clear()

    def update(self):
        print(self._zip_vars_can_write())
        db0.hmset(ConstDB.gateway + hexlify(self.id).decode(),
                  self._zip_vars_can_write())
        db_sql.session.commit()

    def delete(self):
        db_sql.session.delete(self)
        db_sql.session.commit()
        # delete from sql
        id = hexlify(self.id).decode()
        gateway_trans = db0.keys(pattern=ConstDB.trans_params + '*' + id)
        pipe = db0.pipeline()
        for key in gateway_trans:
            key = key.decode()
            pipe.delete(key)
            dev_eui = key.split(":")[1]
            pipe.zrem(ConstDB.dev_gateways + dev_eui, self.id)
        pipe.delete(ConstDB.gateway + id)
        pipe.delete(ConstDB.gateway_pull + id)
        pipe.execute()

    def obj_to_dict(self):
        dd = {
            'id': hexlify(self.id).decode().upper(),
            'mac_addr': hexlify(self.mac_addr).decode().upper(),
            'name': self.name,
            'platform': self.platform.value,
            'model': self.model.value,
            'freq_plan': self.freq_plan.value,
            'public': self.public,
            'disable': self.disable,
            'location': self.location.obj_to_dict(),
        }
        if hasattr(self, 'time'):
            dd['last_data'] = self.time
        self.get_pull_info()
        if hasattr(self, 'ip_addr'):
            dd['ip'] = self.ip_addr
        if hasattr(self, 'prot_ver'):
            dd['ver'] = self.prot_ver
        return dd

    def get_pull_info(self):
        key = ConstDB.gateway_pull + hexlify(self.id).decode()
        info = db0.hgetall(key)
        if info:
            self.ip_addr = info[b'ip_addr'].decode()
            self.prot_ver = int(info[b'prot_ver'])
Пример #7
0
class LocationService(db_sql.Model):
    __tablename__ = 'location_service'

    __table_args__ = {'schema': 'nwkserver'}

    app_eui = db_sql.Column(BINARY(8),
                            ForeignKey(Application.app_eui,
                                       ondelete='CASCADE',
                                       onupdate='CASCADE'),
                            primary_key=True)

    def delete(self):
        db_sql.session.delete(self)
        db_sql.session.commit()

    def add(self):
        db_sql.session.add(self)
        db_sql.session.commit()


# class ServiceName(enum.Enum):
#     http_push = 'http push'
#     location = 'location'
#
#
# class Service(db_sql.Model):
#     __tablename__ = 'service'
#
#     @declared_attr
#     def __table_args__(cls):
#         return {'schema': find_schema(cls)}
#
#     id = db_sql.Column(db_sql.Integer(), primary_key=True)
#     name = db_sql.Column(Enum(ServiceName), unique=True)
#
#     def obj_to_dict(self):
#         return {'name': self.name}
#
#
# class AppServices(db_sql.Model):
#     __tablename__ = 'app_services'
#
#     @declared_attr
#     def __table_args__(cls):
#         return {'schema': find_schema(cls)}
#
#     app_eui = db_sql.Column(BINARY(8), db_sql.ForeignKey('nwkserver.app.app_eui', ondelete='CASCADE'))
#     service_id = db_sql.Column(db_sql.Integer(), db_sql.ForeignKey('nwkserver.service.id', ondelete='CASCADE'))
#     PrimaryKeyConstraint(app_eui, service_id)
#     info = db_sql.Column(db_sql.String(200), nullable=True)
#     service = db_sql.relationship('Service')
#
#     def obj_to_dict(self):
#         return {'name': self.service.name,
#                 'info': self.info}
#
#     def delete(self):
#         db_sql.session.delete(self)
#         db_sql.session.commit()
#
#     def get(self, app_eui, service_name):
#         q = db_sql.session.query(AppServices).filter(AppServices.app_eui == app_eui).join(AppServices.service).filter(Service.name==service_name).first()
#         return q
Пример #8
0
class User(db.Model):
    __bind_key__ = 'lorawan'
    __table_args__ = {'schema': 'lorawan'}
    __tablename__ = 'user'

    id = db.Column(db.Integer, primary_key=True)

    # User email information
    email = db.Column(db.String(255), nullable=False, unique=True)

    # User authentication information
    password = db.Column(db.String(255), nullable=False, server_default='')
    reset_password_token = db.Column(db.String(100), nullable=True)
    confirmed_at = db.Column(db.DateTime())
    confirm_email_token = db.Column(db.String(100), nullable=True)

    # User information
    active = db.Column('is_active', db.Boolean(), nullable=False, server_default='0')
    first_name = db.Column(db.String(100), nullable=True)
    last_name = db.Column(db.String(100), nullable=True)

    # Relationships
    roles = relationship('Role', secondary='lorawan.user_roles')

    apps = relationship('Application')
    gateways = relationship('Gateway')

    def generate_auth_token(self, expiration=600):
        s = Serializer(current_app.config['SECRET_KEY'], expires_in=expiration)
        return s.dumps({'id': self.id})

    @staticmethod
    def verify_auth_token(token):
        s = Serializer(current_app.config['SECRET_KEY'])
        try:
            data = s.loads(token)
        except SignatureExpired:
            return None   # valid token, but expired
        except BadSignature:
            return None    # invalid token
        user = User.query.get(data['id'])
        return user

    def verify_password(self, password):
        """
        Make it backward compatible to legacy password hash.
        In addition, if such password were found, update the user's password field.
        """
        hashed_password = self.password
        verified = passwords.verify_password(current_app.user_manager, password, hashed_password)
        return verified

    def role_name_list(self):
        name_list = []
        for role in self.roles:
            name_list.append(role.name)
        return name_list


    def obj_to_dict(self):
        return {
            'id': self.id,
            'email': self.email,
            'roles': self.role_name_list(),
            'confirmed_at': str(self.confirmed_at),
            'active': str(self.active),
            'app_num': self.apps.__len__(),
            'gateway_num': self.gateways.__len__()
        }