示例#1
0
def untag_asset(tag_id, asset_id, asset_type, organization_id, commit=True):
    """
    Remove the tag with the tag_id and organization_id from the asset with the
    given asset_type ("device" or "gateway") and asset_id (device_id or
    gateway_id).
    """
    if not is_from_organization(tag_id, organization_id):
        raise Error.Forbidden(
            "Trying to delete a tag from other organization.")

    if asset_type == "device":
        if not DeviceRepository.is_from_organization(asset_id,
                                                     organization_id):
            raise Error.Forbidden(
                "Trying to untag a device from other organization")
        asset_tag = db.session.query(DeviceToTag).\
            filter(DeviceToTag.tag_id==tag_id, DeviceToTag.device_id==asset_id).first()
        if asset_tag: db.session.delete(asset_tag)
    elif asset_type == "gateway":
        if not GatewayRepository.is_from_organization(asset_id,
                                                      organization_id):
            raise Error.Forbidden(
                "Trying to untag a gateway from other organization")
        asset_tag = db.session.query(GatewayToTag).\
            filter(GatewayToTag.tag_id==tag_id, GatewayToTag.gateway_id==asset_id).first()
        if asset_tag: db.session.delete(asset_tag)
    else:
        raise Error.BadRequest(f"Invalid asset_type: {asset_type}")
    if commit: db.session.commit()
示例#2
0
def tag_asset(tag_id, asset_id, asset_type, organization_id, commit=True):
    """
    Tag the asset with the given asset_type ("device" or "gateway") and asset_id
    (device_id or gateway_id) with the tag with tag_id and organization_id.
    """
    if not is_from_organization(tag_id, organization_id):
        raise Error.Forbidden("Trying to use a tag from other organization.")
    if is_tagged(tag_id, asset_id, asset_type): return

    if asset_type == "device":
        if not DeviceRepository.is_from_organization(asset_id,
                                                     organization_id):
            raise Error.Forbidden(
                "Trying to tag a device from other organization")
        asset_tag = DeviceToTag(tag_id=tag_id, device_id=asset_id)
        db.session.add(asset_tag)
    elif asset_type == "gateway":
        if not GatewayRepository.is_from_organization(asset_id,
                                                      organization_id):
            raise Error.Forbidden(
                "Trying to tag a gateway from other organization")
        asset_tag = GatewayToTag(tag_id=tag_id, gateway_id=asset_id)
        db.session.add(asset_tag)
    else:
        raise Error.BadRequest(f"Invalid asset_type: {asset_type}")
    if commit: db.session.commit()
 def wrapper(*args,**kwargs):
     verify_jwt_in_request()
     claims = get_jwt_claims()
     try:
         user_roles = [UserRole.find_by_id(user_role_id).role_name for user_role_id in claims.get('user_roles_id')]
     except AttributeError:
         raise Error.Forbidden("Couldn't load user roles")
     if RoleTypes.System.value in user_roles: 
         raise Error.Forbidden("User must have regular or admin role to access this endpoint")
     else:
         return fn(*args,**kwargs)
示例#4
0
    def delete(self):
        user = User.find_by_username(get_jwt_identity())
        if not user or is_system(user.id):
            raise Error.Forbidden("User not allowed")
        organization_id = user.organization_id

        body = json.loads(request.data)
        parsed_result = AppKeysSchema().load(body).data
        app_keys = parsed_result.get('keys')
        if app_keys is None:
            raise Error.BadRequest(
                f"AppKeysAPI POST request body must contain a non-empty list of keys with at most {MAX_PER_ORGANIZATION} keys"
            )

        app_keys = [key.upper() for key in app_keys]
        total = len(app_keys)
        app_keys = list(set(app_keys))
        not_duplicated = len(app_keys)
        validate_keys(app_keys)

        deleted = AppKeysRepository.delete(keys_list=app_keys,
                                           organization_id=organization_id)
        return {
            "message":
            f"{deleted} app keys deleted, {total-not_duplicated} were duplicated and {not_duplicated-deleted} were not present in user's organization"
        }, 200
def create(keys_list, organization_id):
    """
    Create a new app_key for every key in keys_list that is
    not already part of this organizantion's set of keys.
    """
    global MAX_PER_ORGANIZATION

    already_in_db = set(row.key
                        for row in get_with(organization_id=organization_id,
                                            keys_list=keys_list))
    added_keys = []

    for key in keys_list:
        if key not in already_in_db:
            db.session.add(AppKey(key=key, organization_id=organization_id))
            already_in_db.add(key)
            added_keys.append(key)

    db.session.commit()

    created = len(added_keys)
    total = count_with(organization_id=organization_id)
    if total > MAX_PER_ORGANIZATION:
        try:
            delete(keys_list=added_keys, organization_id=organization_id)
        except Exception as e:
            log.warning(
                f"Error {e} on delete added keys after max app keys limit exceeded for organization with id {organization_id}"
            )
            return created

        raise Error.Forbidden(
            "Creating these app keys would exceed the limit per organization")

    return created
示例#6
0
    def patch(self, tag_id):
        user = User.find_by_username(get_jwt_identity())
        if not user or is_system(user.id):
            raise Error.Forbidden("User not allowed")
        organization_id = user.organization_id
        
        name = request.args.get('name', type=str, default=None)
        color = request.args.get('color', type=str, default=None)


        previous_tag = TagRepository.get_with(tag_id, organization_id)

        tag_list = TagRepository.list_all(
            organization_id=organization_id
            )
        
        if name in (tag.name for tag in tag_list) and name != previous_tag.name:
            return [{'code': 'EXISTING_NAME', 'message': 'Existing tag with that name'}], 400

        TagRepository.update(
            tag_id=tag_id,
            name=name,
            color=color,
            organization_id=organization_id)
        return {"message": "Tag updated"}, 200
示例#7
0
def list_asset_tags(asset_id, asset_type, organization_id):
    if asset_type == "device":
        if not DeviceRepository.is_from_organization(asset_id,
                                                     organization_id):
            raise Error.Forbidden(
                "Trying to list tags from a device from other organization")
        return db.session.query(Tag).\
            join(DeviceToTag).\
            filter(DeviceToTag.device_id == asset_id).all()
    elif asset_type == "gateway":
        if not GatewayRepository.is_from_organization(asset_id,
                                                      organization_id):
            raise Error.Forbidden(
                "Trying to list tags from a gateway from other organization")
        return db.session.query(Tag).\
            join(GatewayToTag).\
            filter(GatewayToTag.gateway_id == asset_id).all()
    else:
        raise Error.BadRequest(f"Invalid asset_type: {asset_type}")
示例#8
0
    def get(self, tag_id):
        user = User.find_by_username(get_jwt_identity())
        if not user or is_system(user.id):
            raise Error.Forbidden("User not allowed")
        organization_id = user.organization_id

        tag = TagRepository.get_with(
            tag_id=tag_id,
            organization_id=organization_id
            )
        return {"id": tag.id, "name": tag.name, "color": tag.color}, 200
示例#9
0
    def delete(self, tag_id):
        user = User.find_by_username(get_jwt_identity())
        if not user or is_system(user.id):
            raise Error.Forbidden("User not allowed")
        organization_id = user.organization_id

        TagRepository.delete(
            tag_id=tag_id,
            organization_id=organization_id
            )
        return {"message": "Tag deleted"}, 200
示例#10
0
    def get(self):
        user = User.find_by_username(get_jwt_identity())
        if not user or is_system(user.id):
            raise Error.Forbidden("User not allowed")
        organization_id = user.organization_id

        tag_list = TagRepository.list_all(
            organization_id=organization_id
            )
        return [{
            "id" : tag.id,
            "name" : tag.name,
            "color": tag.color
        } for tag in tag_list], 200
示例#11
0
    def get(self):
        user = User.find_by_username(get_jwt_identity())
        if not user or is_system(user.id):
            raise Error.Forbidden("User not allowed")
        organization_id = user.organization_id

        app_keys = AppKeysRepository.get_with(organization_id=organization_id)

        return {
            "limit":
            MAX_PER_ORGANIZATION,
            "count":
            len(app_keys),
            "keys": [{
                "id": app_key.id,
                "key": app_key.key,
                "organization_id": app_key.organization_id
            } for app_key in app_keys]
        }, 200
示例#12
0
    def post(self):
        user = User.find_by_username(get_jwt_identity())
        if not user or is_system(user.id):
            raise Error.Forbidden("User not allowed")
        organization_id = user.organization_id
        
        name = request.args.get('name', type=str)
        color = request.args.get('color', type=str)

        tag_list = TagRepository.list_all(
            organization_id=organization_id
            )
        
        if name in (tag.name for tag in tag_list):
            return [{'code': 'EXISTING_NAME', 'message': 'Existing tag with that name'}], 400

        tag = TagRepository.create(
            name=name,
            color=color,
            organization_id=organization_id
            )
        return {"id": tag.id, "name": tag.name, "color": tag.color}, 200
    def post(self):
        user = User.find_by_username(get_jwt_identity())
        if not user or is_system(user.id):
            raise Error.Forbidden("User not allowed")
        organization_id = user.organization_id

        args = self.parser.parse_args()
        asset_list = args["asset_list"]
        importance = args["importance"]

        if importance not in ['LOW', 'MEDIUM', 'HIGH']:
            raise Exception(f'"{importance}" is not a valid importance value')

        for asset_id in asset_list:
            asset_id = json.loads(asset_id.replace("\'", "\""))
            asset = AssetRepository.get_with(asset_id=int(
                asset_id["asset_id"]),
                                             asset_type=asset_id["asset_type"],
                                             organization_id=organization_id)
            asset.importance = importance
        db.session.commit()
        return {"message": "Assets importance set"}, 200
def get_with(asset_id, asset_type, organization_id=None):
    """ Gets an asset from database
    Request parameters:
        - asset_id: database id of the asset
        - asset_type: type of the requested asset, can be "device" or "gateway".
        - organization_id (optional): when given, asserts that received organization
            matchs the asset's organization
    Returns:
        - Model object of requested asset
    """
    if asset_type == "device":
        asset = Device.query.get(asset_id)
        if not asset:
            raise Error.NotFound(
                f"Asset with id {asset_id} and type {asset_type} not found")
        device_session = db.session.query(DeviceSession).\
            filter(DeviceSession.device_id==asset_id).\
            order_by(DeviceSession.last_activity.desc()).\
            first()
        asset.dev_addr = device_session.dev_addr if device_session else None
        asset.hex_id = asset.dev_eui
    elif asset_type == "gateway":
        asset = db.session.query(Gateway).\
            filter(Gateway.id == asset_id).\
            first()
        if not asset:
            raise Error.NotFound(
                f"Asset with id {asset_id} and type {asset_type} not found")
        asset.hex_id = asset.gw_hex_id
    else:
        raise Error.BadRequest(
            f"Invalid asset_type: {asset_type}. Valid values are \'device\' or \'gateway\'"
        )
    if organization_id and asset.organization_id != organization_id:
        raise Error.Forbidden(
            "User's organization's different from asset organization")
    asset.type = asset_type
    return asset
示例#15
0
def get_with(asset_id, asset_type, organization_id=None):
    """ Gets an asset from database
    Request parameters:
        - asset_id: database id of the asset
        - asset_type: type of the requested asset, can be "device" or "gateway".
        - organization_id (optional): when given, asserts that received organization
            matchs the asset's organization
    Returns:
        - Model object of requested asset
    """
    if asset_type == "device":
        asset_query = db.session.query(
            Device.id,
            Device.organization_id,
            Device.dev_eui.label('hex_id'),
            expression.literal_column('\'Device\'').label('type'),
            Device.name,
            Device.app_name,
            DataCollector.name.label('data_collector'),
            PolicyItem.parameters.label('policy_parameters'),
            Device.connected.label('connected'),
            Device.last_activity,
            Device.activity_freq,
            Device.activity_freq_variance,
            Device.npackets_up,
            Device.npackets_down,
            Device.npackets_lost.label('packet_loss'),
            Device.max_rssi,
            Device.max_lsnr,
            Device.ngateways_connected_to,
            Device.payload_size,
            Device.last_packets_list
            ).filter(Device.id == asset_id).\
                join(DataCollector, Device.data_collector_id == DataCollector.id).\
                join(Policy, Policy.id == DataCollector.policy_id).\
                join(PolicyItem, and_(Policy.id == PolicyItem.policy_id, PolicyItem.alert_type_code == 'LAF-401')).\
                join(RowProcessed, RowProcessed.analyzer == 'packet_analyzer').\
                join(Packet, Packet.id == RowProcessed.last_row).\
                join(DeviceCounters, and_(
                    DeviceCounters.device_id == Device.id,
                    DeviceCounters.counter_type.in_(dev_wanted_counters),
                    DeviceCounters.last_update + func.make_interval(0,0,0,1) > Packet.date
                    ), isouter=True).\
                group_by(Device.id, DataCollector.name, PolicyItem.parameters)

        asset_query = add_counters_columns(asset_query, dev_wanted_counters,
                                           DeviceCounters)
        asset = asset_query.first()

    elif asset_type == "gateway":
        asset_query = db.session.query(
            Gateway.id,
            Gateway.organization_id,
            Gateway.gw_hex_id.label('hex_id'),
            expression.literal_column('\'Gateway\'').label('type'),
            Gateway.name,
            expression.null().label('app_name'),
            DataCollector.name.label('data_collector'),
            expression.null().label('policy_parameters'),
            Gateway.connected.label('connected'),
            Gateway.last_activity,
            Gateway.activity_freq,
            cast(expression.null(), Float).label('activity_freq_variance'),
            Gateway.npackets_up,
            Gateway.npackets_down,
            cast(expression.null(), Float).label('packet_loss'),
            cast(expression.null(), Float).label('max_rssi'),
            cast(expression.null(), Float).label('max_lsnr'),
            cast(expression.null(), Float).label('ngateways_connected_to'),
            cast(expression.null(), Float).label('payload_size'),
            expression.null().label('last_packets_list')
            ).filter(Gateway.id == asset_id).\
                join(DataCollector, Gateway.data_collector_id == DataCollector.id).\
                join(RowProcessed, RowProcessed.analyzer == 'packet_analyzer').\
                join(Packet, Packet.id == RowProcessed.last_row).\
                join(GatewayCounters, and_(
                    GatewayCounters.gateway_id == Gateway.id,
                    GatewayCounters.counter_type.in_(gtw_wanted_counters),
                    GatewayCounters.last_update + func.make_interval(0,0,0,1) > Packet.date
                    ), isouter=True).\
                group_by(Gateway.id, DataCollector.name)

        asset_query = add_counters_columns(asset_query, gtw_wanted_counters,
                                           GatewayCounters)
        asset = asset_query.first()
    else:
        raise Error.BadRequest(
            f"Invalid asset_type: {asset_type}. Valid values are \'device\' or \'gateway\'"
        )
    if not asset:
        raise Error.NotFound(
            f"Asset with id {asset_id} and type {asset_type} not found")
    if organization_id and asset.organization_id != organization_id:
        raise Error.Forbidden(
            "User's organization's different from asset organization")
    return asset