feat: geo risk scores
This commit is contained in:
parent
315dae7f06
commit
0e0d499428
17 changed files with 558 additions and 54 deletions
|
@ -1,5 +1,5 @@
|
|||
import json
|
||||
from datetime import datetime
|
||||
from datetime import datetime, timedelta
|
||||
from typing import Optional, List, Union, Any, Dict
|
||||
|
||||
from tldextract import extract
|
||||
|
@ -8,9 +8,17 @@ from werkzeug.datastructures import FileStorage
|
|||
from app.brm.brn import BRN
|
||||
from app.brm.utils import thumbnail_uploaded_image, create_data_uri, normalize_color
|
||||
from app.extensions import db
|
||||
from app.models import AbstractConfiguration, AbstractResource
|
||||
from app.models import AbstractConfiguration, AbstractResource, Deprecation
|
||||
from app.models.onions import Onion
|
||||
|
||||
country_origin = db.Table(
|
||||
'country_origin',
|
||||
db.metadata,
|
||||
db.Column('country_id', db.ForeignKey('country.id'), primary_key=True),
|
||||
db.Column('origin_id', db.ForeignKey('origin.id'), primary_key=True),
|
||||
extend_existing=True,
|
||||
)
|
||||
|
||||
|
||||
class Origin(AbstractConfiguration):
|
||||
group_id = db.Column(db.Integer, db.ForeignKey("group.id"), nullable=False)
|
||||
|
@ -18,9 +26,11 @@ class Origin(AbstractConfiguration):
|
|||
auto_rotation = db.Column(db.Boolean, nullable=False)
|
||||
smart = db.Column(db.Boolean(), nullable=False)
|
||||
assets = db.Column(db.Boolean(), nullable=False)
|
||||
risk_level_override = db.Column(db.Integer(), nullable=True)
|
||||
|
||||
group = db.relationship("Group", back_populates="origins")
|
||||
proxies = db.relationship("Proxy", back_populates="origin")
|
||||
countries = db.relationship("Country", secondary=country_origin, back_populates='origins')
|
||||
|
||||
@property
|
||||
def brn(self) -> BRN:
|
||||
|
@ -35,7 +45,7 @@ class Origin(AbstractConfiguration):
|
|||
@classmethod
|
||||
def csv_header(cls) -> List[str]:
|
||||
return super().csv_header() + [
|
||||
"group_id", "domain_name", "auto_rotation", "smart"
|
||||
"group_id", "domain_name", "auto_rotation", "smart", "assets", "country"
|
||||
]
|
||||
|
||||
def destroy(self) -> None:
|
||||
|
@ -51,6 +61,75 @@ class Origin(AbstractConfiguration):
|
|||
domain_name: str = self.domain_name
|
||||
return f"https://{domain_name.replace(tld, onion.onion_name)}.onion"
|
||||
|
||||
@property
|
||||
def risk_level(self) -> Dict[str, int]:
|
||||
if self.risk_level_override:
|
||||
return {country.country_code: self.risk_level_override for country in self.countries}
|
||||
frequency_factor = 0
|
||||
recency_factor = 0
|
||||
recent_deprecations = (
|
||||
db.session.query(Deprecation) # type: ignore[no-untyped-call]
|
||||
.join(Proxy,
|
||||
Deprecation.resource_id == Proxy.id)
|
||||
.join(Origin, Origin.id == Proxy.origin_id)
|
||||
.filter(
|
||||
Origin.id == self.id,
|
||||
Deprecation.resource_type == 'Proxy',
|
||||
Deprecation.deprecated_at >= datetime.utcnow() - timedelta(hours=168)
|
||||
)
|
||||
.distinct(Proxy.id)
|
||||
.all()
|
||||
)
|
||||
for deprecation in recent_deprecations:
|
||||
recency_factor += 1 / max((datetime.utcnow() - deprecation.deprecated_at).total_seconds() // 3600, 1)
|
||||
frequency_factor += 1
|
||||
risk_levels: Dict[str, int] = {}
|
||||
for country in self.countries:
|
||||
risk_levels[country.country_code.upper()] = int(max(1, min(10, frequency_factor * recency_factor))) + country.risk_level
|
||||
return risk_levels
|
||||
|
||||
|
||||
class Country(AbstractConfiguration):
|
||||
@property
|
||||
def brn(self) -> BRN:
|
||||
return BRN(
|
||||
group_id=0,
|
||||
product="country",
|
||||
provider="iso3166-1",
|
||||
resource_type="alpha2",
|
||||
resource_id=self.country_code
|
||||
)
|
||||
|
||||
country_code = db.Column(db.String(2), nullable=False)
|
||||
risk_level_override = db.Column(db.Integer(), nullable=True)
|
||||
|
||||
origins = db.relationship("Origin", secondary=country_origin, back_populates='countries')
|
||||
|
||||
@property
|
||||
def risk_level(self) -> int:
|
||||
if self.risk_level_override:
|
||||
return int(self.risk_level_override // 2)
|
||||
frequency_factor = 0
|
||||
recency_factor = 0
|
||||
recent_deprecations = (
|
||||
db.session.query(Deprecation) # type: ignore[no-untyped-call]
|
||||
.join(Proxy,
|
||||
Deprecation.resource_id == Proxy.id)
|
||||
.join(Origin, Origin.id == Proxy.origin_id)
|
||||
.join(Origin.countries)
|
||||
.filter(
|
||||
Country.id == self.id,
|
||||
Deprecation.resource_type == 'Proxy',
|
||||
Deprecation.deprecated_at >= datetime.utcnow() - timedelta(hours=168)
|
||||
)
|
||||
.distinct(Proxy.id)
|
||||
.all()
|
||||
)
|
||||
for deprecation in recent_deprecations:
|
||||
recency_factor += 1 / max((datetime.utcnow() - deprecation.deprecated_at).total_seconds() // 3600, 1)
|
||||
frequency_factor += 1
|
||||
return int(max(1, min(10, frequency_factor * recency_factor)))
|
||||
|
||||
|
||||
class StaticOrigin(AbstractConfiguration):
|
||||
group_id = db.Column(db.Integer, db.ForeignKey("group.id"), nullable=False)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue