diff --git a/CHANGELOG.md b/CHANGELOG.md index c537d52..49cd283 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +# 0.24.0 + +* Adds config endpoint + # 0.23.0 * Results will return the total count in the DB to help with pagination diff --git a/fediseer/apis/models/v1.py b/fediseer/apis/models/v1.py index 8436c3f..a29f434 100644 --- a/fediseer/apis/models/v1.py +++ b/fediseer/apis/models/v1.py @@ -25,6 +25,12 @@ class Models: 'domains': fields.List(fields.String(description="The suspicious domains as a list.")), 'csv': fields.String(description="The suspicious domains as a csv."), }) + self.response_model_model_Config_get = api.model('FediseerConfig', { + 'max_guarantees': fields.Integer(description="The total amount of guarantees one instance can give", required=True), + 'max_guarantors': fields.Integer(description="The total amount of guarantors one instance can have", required=True), + 'max_config_actions_per_min': fields.Integer(description="The amount of config actions one instance can take per minute.", required=True), + 'max_tags': fields.Integer(description="The maximum tags each instance can self-assign.", required=True), + }) self.response_model_instances = api.model('InstanceDetails', { 'id': fields.Integer(description="The instance id", example=1), 'domain': fields.String(description="The instance domain", example="lemmy.dbzer0.com"), diff --git a/fediseer/apis/v1/__init__.py b/fediseer/apis/v1/__init__.py index 6710616..eaa7692 100644 --- a/fediseer/apis/v1/__init__.py +++ b/fediseer/apis/v1/__init__.py @@ -16,6 +16,7 @@ import fediseer.apis.v1.faq as faq from fediseer.apis.v1.base import api api.add_resource(base.Suspicions, "/instances") +api.add_resource(base.Config, "/config") api.add_resource(find.FindInstance, "/find_instance") api.add_resource(activitypub.User, "/user/") api.add_resource(activitypub.Inbox, "/inbox/") diff --git a/fediseer/apis/v1/base.py b/fediseer/apis/v1/base.py index 4a3092b..7d3c8f7 100644 --- a/fediseer/apis/v1/base.py +++ b/fediseer/apis/v1/base.py @@ -9,9 +9,9 @@ from fediseer.database import functions as database from fediseer import exceptions as e from fediseer.utils import hash_api_key from fediseer.messaging import activitypub_pm -from pythorhead import Lemmy from fediseer.fediverse import InstanceInfo from fediseer.limiter import limiter +from fediseer import consts api = Namespace('v1', 'API Version 1' ) @@ -42,7 +42,6 @@ class Suspicions(Resource): get_parser.add_argument("domains", required=False, type=bool, help="Set to true to return just the domains as a list. Mutually exclusive with csv", location="args") @api.expect(get_parser) - @logger.catch(reraise=True) @cache.cached(timeout=10, query_string=True) @api.marshal_with(models.response_model_model_Suspicions_get, code=200, description='Suspicious Instances', skip_none=True) def get(self): @@ -59,6 +58,24 @@ class Suspicions(Resource): return {"domains": [instance["domain"] for instance in sus_instances]},200 return {"instances": sus_instances},200 +class Config(Resource): + get_parser = reqparse.RequestParser() + get_parser.add_argument("Client-Agent", default="unknown:0:unknown", type=str, required=False, help="The client name and version.", location="headers") + + @api.expect(get_parser) + @cache.cached(timeout=600) + @api.marshal_with(models.response_model_model_Config_get, code=200, description='Fediseer config') + def get(self): + '''The current Fediseer configuration options + ''' + self.args = self.get_parser.parse_args() + return { + 'max_guarantees': consts.MAX_GUARANTEES, + 'max_guarantors': consts.MAX_GUARANTORS, + 'max_tags': consts.MAX_TAGS, + 'max_config_actions_per_min': consts.MAX_CONFIG_ACTIONS_PER_MIN, + }, 200 + # Debug # from fediseer.flask import OVERSEER # with OVERSEER.app_context(): diff --git a/fediseer/apis/v1/censures.py b/fediseer/apis/v1/censures.py index 71c9b38..255dedd 100644 --- a/fediseer/apis/v1/censures.py +++ b/fediseer/apis/v1/censures.py @@ -2,7 +2,7 @@ from fediseer.apis.v1.base import * from fediseer.classes.instance import Censure from fediseer.utils import sanitize_string from fediseer.classes.reports import Report -from fediseer import enums +from fediseer import enums, consts from fediseer.register import ensure_instance_registered class CensuresGiven(Resource): @@ -226,7 +226,7 @@ class Censures(Resource): if instance.domain == domain: raise e.BadRequest("You're a mad lad, but you can't censure yourself.") if database.has_too_many_actions_per_min(instance.domain): - raise e.TooManyRequests("Your instance is doing more than 20 actions per minute. Please slow down.") + raise e.TooManyRequests(f"Your instance is doing more than {consts.MAX_CONFIG_ACTIONS_PER_MIN} actions per minute. Please slow down.") unbroken_chain, chainbreaker = database.has_unbroken_chain(instance.id) if not unbroken_chain: raise e.Forbidden(f"Guarantee chain for this instance has been broken. Chain ends at {chainbreaker.domain}!") @@ -291,7 +291,7 @@ class Censures(Resource): if not instance: raise e.NotFound(f"No Instance found matching provided API key and domain. Have you remembered to register it?") if database.has_too_many_actions_per_min(instance.domain): - raise e.TooManyRequests("Your instance is doing more than 20 actions per minute. Please slow down.") + raise e.TooManyRequests(f"Your instance is doing more than {consts.MAX_CONFIG_ACTIONS_PER_MIN} actions per minute. Please slow down.") target_instance = database.find_instance_by_domain(domain=domain) if not target_instance: raise e.BadRequest("Instance from which to modify censure not found") @@ -400,7 +400,7 @@ class BatchCensures(Resource): if database.instance_has_flag(instance.id,enums.InstanceFlags.RESTRICTED): raise e.Forbidden("You cannot take this action as your instance is restricted") if database.has_too_many_actions_per_min(instance.domain): - raise e.TooManyRequests("Your instance is doing more than 20 actions per minute. Please slow down.") + raise e.TooManyRequests(f"Your instance is doing more than {consts.MAX_CONFIG_ACTIONS_PER_MIN} actions per minute. Please slow down.") unbroken_chain, chainbreaker = database.has_unbroken_chain(instance.id) if not unbroken_chain: raise e.Forbidden(f"Guarantee chain for this instance has been broken. Chain ends at {chainbreaker.domain}!") diff --git a/fediseer/apis/v1/endorsements.py b/fediseer/apis/v1/endorsements.py index dec6365..e62a9c5 100644 --- a/fediseer/apis/v1/endorsements.py +++ b/fediseer/apis/v1/endorsements.py @@ -1,7 +1,7 @@ from fediseer.apis.v1.base import * from fediseer.classes.instance import Endorsement,Censure from fediseer.classes.reports import Report -from fediseer import enums +from fediseer import enums, consts from fediseer.utils import sanitize_string from fediseer.register import ensure_instance_registered @@ -198,7 +198,7 @@ class Endorsements(Resource): if instance.domain == domain: raise e.BadRequest("Nice try, but you can't endorse yourself.") if database.has_too_many_actions_per_min(instance.domain): - raise e.TooManyRequests("Your instance is doing more than 20 actions per minute. Please slow down.") + raise e.TooManyRequests(f"Your instance is doing more than {consts.MAX_CONFIG_ACTIONS_PER_MIN} actions per minute. Please slow down.") unbroken_chain, chainbreaker = database.has_unbroken_chain(instance.id) if not unbroken_chain: raise e.Forbidden(f"Guarantee chain for this instance has been broken. Chain ends at {chainbreaker.domain}!") @@ -275,7 +275,7 @@ class Endorsements(Resource): if not instance: raise e.NotFound(f"No Instance found matching provided API key and domain. Have you remembered to register it?") if database.has_too_many_actions_per_min(instance.domain): - raise e.TooManyRequests("Your instance is doing more than 20 actions per minute. Please slow down.") + raise e.TooManyRequests(f"Your instance is doing more than {consts.MAX_CONFIG_ACTIONS_PER_MIN} actions per minute. Please slow down.") target_instance = database.find_instance_by_domain(domain=domain) if not target_instance: raise e.BadRequest("Instance for which to modify endorsement not found") @@ -326,7 +326,7 @@ class Endorsements(Resource): if not instance: raise e.NotFound(f"No Instance found matching provided API key and domain. Have you remembered to register it?") if database.has_too_many_actions_per_min(instance.domain): - raise e.TooManyRequests("Your instance is doing more than 20 actions per minute. Please slow down.") + raise e.TooManyRequests(f"Your instance is doing more than {consts.MAX_CONFIG_ACTIONS_PER_MIN} actions per minute. Please slow down.") target_instance = database.find_instance_by_domain(domain=domain) if not target_instance: raise e.BadRequest("Instance from which to withdraw endorsement not found") @@ -390,7 +390,7 @@ class BatchEndorsements(Resource): if database.instance_has_flag(instance.id,enums.InstanceFlags.RESTRICTED): raise e.Forbidden("You cannot take this action as your instance is restricted") if database.has_too_many_actions_per_min(instance.domain): - raise e.TooManyRequests("Your instance is doing more than 20 actions per minute. Please slow down.") + raise e.TooManyRequests(f"Your instance is doing more than {consts.MAX_CONFIG_ACTIONS_PER_MIN} actions per minute. Please slow down.") unbroken_chain, chainbreaker = database.has_unbroken_chain(instance.id) if not unbroken_chain: raise e.Forbidden(f"Guarantee chain for this instance has been broken. Chain ends at {chainbreaker.domain}!") diff --git a/fediseer/apis/v1/guarantees.py b/fediseer/apis/v1/guarantees.py index 64b3197..34fefc7 100644 --- a/fediseer/apis/v1/guarantees.py +++ b/fediseer/apis/v1/guarantees.py @@ -1,7 +1,7 @@ from fediseer.apis.v1.base import * from fediseer.classes.instance import Guarantee, RejectionRecord, Solicitation, InstanceFlag from fediseer.classes.reports import Report -from fediseer import enums +from fediseer import enums, consts from fediseer.register import ensure_instance_registered class Guarantors(Resource): @@ -74,7 +74,7 @@ class Guarantees(Resource): def put(self, domain): '''Guarantee an instance A instance can only be guaranteed by one other instance - An instance can guarantee up to 20 other instances + An instance can guarantee up to consts.MAX_GUARANTEES other instances A guaranteed instance can guarantee and endorse other instances. ''' self.args = self.put_parser.parse_args() @@ -85,12 +85,12 @@ class Guarantees(Resource): raise e.NotFound(f"No Instance found matching provided API key and domain. Have you remembered to register it?") if len(instance.guarantors) == 0: raise e.Forbidden("Only guaranteed instances can guarantee others.") - if len(instance.guarantees) >= 20 and instance.id != 0: - raise e.Forbidden("You cannot guarantee for more than 20 instances") + if len(instance.guarantees) >= consts.MAX_GUARANTEES and instance.id != 0: + raise e.Forbidden(f"You cannot guarantee for more than {consts.MAX_GUARANTEES} instances") if database.instance_has_flag(instance.id,enums.InstanceFlags.RESTRICTED): raise e.Forbidden("You cannot take this action as your instance is restricted") if database.has_too_many_actions_per_min(instance.domain): - raise e.TooManyRequests("Your instance is doing more than 20 actions per minute. Please slow down.") + raise e.TooManyRequests(f"Your instance is doing more than {consts.MAX_CONFIG_ACTIONS_PER_MIN} actions per minute. Please slow down.") unbroken_chain, chainbreaker = database.has_unbroken_chain(instance.id) if not unbroken_chain: raise e.Forbidden(f"Guarantee chain for this instance has been broken. Chain ends at {chainbreaker.domain}!") @@ -168,7 +168,7 @@ class Guarantees(Resource): if not instance: raise e.NotFound(f"No Instance found matching provided API key and domain. Have you remembered to register it?") if database.has_too_many_actions_per_min(instance.domain): - raise e.TooManyRequests("Your instance is doing more than 20 actions per minute. Please slow down.") + raise e.TooManyRequests(f"Your instance is doing more than {consts.MAX_CONFIG_ACTIONS_PER_MIN} actions per minute. Please slow down.") target_instance = database.find_instance_by_domain(domain=domain) if not target_instance: raise e.BadRequest("Instance from which to withdraw endorsement not found") diff --git a/fediseer/apis/v1/hesitations.py b/fediseer/apis/v1/hesitations.py index 7f975e4..9fa9b1e 100644 --- a/fediseer/apis/v1/hesitations.py +++ b/fediseer/apis/v1/hesitations.py @@ -2,7 +2,7 @@ from fediseer.apis.v1.base import * from fediseer.classes.instance import Hesitation from fediseer.utils import sanitize_string from fediseer.classes.reports import Report -from fediseer import enums +from fediseer import enums, consts from fediseer.register import ensure_instance_registered class HesitationsGiven(Resource): @@ -208,7 +208,7 @@ class Hesitations(Resource): if instance.domain == domain: raise e.BadRequest("You're a mad lad, but you can't hesitation yourself.") if database.has_too_many_actions_per_min(instance.domain): - raise e.TooManyRequests("Your instance is doing more than 20 actions per minute. Please slow down.") + raise e.TooManyRequests(f"Your instance is doing more than {consts.MAX_CONFIG_ACTIONS_PER_MIN} actions per minute. Please slow down.") unbroken_chain, chainbreaker = database.has_unbroken_chain(instance.id) if not unbroken_chain: raise e.Forbidden(f"Guarantee chain for this instance has been broken. Chain ends at {chainbreaker.domain}!") @@ -274,7 +274,7 @@ class Hesitations(Resource): if not instance: raise e.NotFound(f"No Instance found matching provided API key and domain. Have you remembered to register it?") if database.has_too_many_actions_per_min(instance.domain): - raise e.TooManyRequests("Your instance is doing more than 20 actions per minute. Please slow down.") + raise e.TooManyRequests(f"Your instance is doing more than {consts.MAX_CONFIG_ACTIONS_PER_MIN} actions per minute. Please slow down.") target_instance = database.find_instance_by_domain(domain=domain) if not target_instance: raise e.BadRequest("Instance from which to modify hesitation not found") @@ -330,7 +330,7 @@ class Hesitations(Resource): if not instance: raise e.NotFound(f"No Instance found matching provided API key and domain. Have you remembered to register it?") if database.has_too_many_actions_per_min(instance.domain): - raise e.TooManyRequests("Your instance is doing more than 20 actions per minute. Please slow down.") + raise e.TooManyRequests(f"Your instance is doing more than {consts.MAX_CONFIG_ACTIONS_PER_MIN} actions per minute. Please slow down.") target_instance = database.find_instance_by_domain(domain=domain) if not target_instance: raise e.BadRequest("Instance from which to withdraw hesitation not found") @@ -383,7 +383,7 @@ class BatchHesitations(Resource): if database.instance_has_flag(instance.id,enums.InstanceFlags.RESTRICTED): raise e.Forbidden("You cannot take this action as your instance is restricted") if database.has_too_many_actions_per_min(instance.domain): - raise e.TooManyRequests("Your instance is doing more than 20 actions per minute. Please slow down.") + raise e.TooManyRequests(f"Your instance is doing more than {consts.MAX_CONFIG_ACTIONS_PER_MIN} actions per minute. Please slow down.") unbroken_chain, chainbreaker = database.has_unbroken_chain(instance.id) if not unbroken_chain: raise e.Forbidden(f"Guarantee chain for this instance has been broken. Chain ends at {chainbreaker.domain}!") diff --git a/fediseer/apis/v1/rebuttals.py b/fediseer/apis/v1/rebuttals.py index 4dd8679..8f9f100 100644 --- a/fediseer/apis/v1/rebuttals.py +++ b/fediseer/apis/v1/rebuttals.py @@ -2,7 +2,7 @@ from fediseer.apis.v1.base import * from fediseer.classes.instance import Rebuttal from fediseer.utils import sanitize_string from fediseer.classes.reports import Report -from fediseer import enums +from fediseer import enums, consts class Rebuttals(Resource): decorators = [limiter.limit("45/minute"), limiter.limit("30/minute", key_func = get_request_path)] @@ -33,7 +33,7 @@ class Rebuttals(Resource): if database.instance_has_flag(instance.id,enums.InstanceFlags.RESTRICTED): raise e.Forbidden("You cannot take this action as your instance is restricted") if database.has_too_many_actions_per_min(instance.domain): - raise e.TooManyRequests("Your instance is doing more than 20 actions per minute. Please slow down.") + raise e.TooManyRequests(f"Your instance is doing more than {consts.MAX_CONFIG_ACTIONS_PER_MIN} actions per minute. Please slow down.") unbroken_chain, chainbreaker = database.has_unbroken_chain(instance.id) if not unbroken_chain: raise e.Forbidden(f"Guarantee chain for this instance has been broken. Chain ends at {chainbreaker.domain}!") @@ -92,7 +92,7 @@ class Rebuttals(Resource): if not instance: raise e.NotFound(f"No Instance found matching provided API key and domain. Have you remembered to register it?") if database.has_too_many_actions_per_min(instance.domain): - raise e.TooManyRequests("Your instance is doing more than 20 actions per minute. Please slow down.") + raise e.TooManyRequests(f"Your instance is doing more than {consts.MAX_CONFIG_ACTIONS_PER_MIN} actions per minute. Please slow down.") target_instance = database.find_instance_by_domain(domain=domain) if not target_instance: raise e.BadRequest("Instance from which to modify censure not found") diff --git a/fediseer/apis/v1/solicitations.py b/fediseer/apis/v1/solicitations.py index bb20771..1556b02 100644 --- a/fediseer/apis/v1/solicitations.py +++ b/fediseer/apis/v1/solicitations.py @@ -1,6 +1,6 @@ from fediseer.apis.v1.base import * from fediseer.messaging import activitypub_pm -from fediseer import enums +from fediseer import enums, consts from fediseer.classes.instance import Solicitation from fediseer.classes.reports import Report @@ -56,7 +56,7 @@ class Solicitations(Resource): if instance.is_guaranteed(): raise e.BadRequest(f"Your instance is already guaranteed by {instance.get_guarantor().domain}") if database.has_too_many_actions_per_min(instance.domain): - raise e.TooManyRequests("Your instance is doing more than 20 actions per minute. Please slow down.") + raise e.TooManyRequests(f"Your instance is doing more than {consts.MAX_CONFIG_ACTIONS_PER_MIN} actions per minute. Please slow down.") guarantor_instance = None if self.args.guarantor: guarantor_instance = database.find_instance_by_domain(self.args.guarantor) diff --git a/fediseer/consts.py b/fediseer/consts.py index 77948da..d5bbd7e 100644 --- a/fediseer/consts.py +++ b/fediseer/consts.py @@ -11,4 +11,7 @@ SUPPORTED_SOFTWARE = { "mitra", } POLLS_PER_DAY=2 -MAX_TAGS=100 \ No newline at end of file +MAX_TAGS=100 +MAX_GUARANTEES=20 +MAX_GUARANTORS=1 #TODO: Not implemented yet +MAX_CONFIG_ACTIONS_PER_MIN=20 \ No newline at end of file diff --git a/fediseer/database/functions.py b/fediseer/database/functions.py index 5efc368..905a417 100644 --- a/fediseer/database/functions.py +++ b/fediseer/database/functions.py @@ -7,7 +7,7 @@ from sqlalchemy.orm import joinedload from fediseer.classes.instance import Instance, Endorsement, Guarantee, RejectionRecord, Censure, Hesitation, Solicitation, InstanceFlag, InstanceTag, Rebuttal from fediseer.classes.user import Claim, User from fediseer.classes.reports import Report -from fediseer import enums +from fediseer import enums, consts def get_all_instance_query( min_endorsements = 0, @@ -590,7 +590,7 @@ def has_too_many_actions_per_min(source_domain): ).filter( Report.created > datetime.utcnow() - timedelta(minutes=1), ) - return query.count() > 20 + return query.count() > consts.MAX_CONFIG_ACTIONS_PER_MIN def get_instance_flag(instance_id, flag_enum): query = InstanceFlag.query.filter(