sysadmins and moderators

pull/20/head
db0 2023-09-10 18:43:08 +02:00
parent 3138111520
commit 7d665ecd75
8 changed files with 44 additions and 8 deletions

5
CHANGELOG.md 100644
View File

@ -0,0 +1,5 @@
# Changelog
# 0.8.1
Added sysadmins and moderators count. This allows instance admins to self-report how many people they have in sysadmins positions and how many in moderator positions. This might be useful to find which instances might be lacking in support for their user-base.

View File

@ -1,3 +1,4 @@
requests requests
pythorhead pythorhead
pythonseer>=0.1.3 pythonseer>=0.1.3
python-dotenv

View File

@ -1,12 +1,15 @@
import requests import requests
import os
from dotenv import load_dotenv
from pythorhead import Lemmy from pythorhead import Lemmy
from pythonseer import Fediseer from pythonseer import Fediseer
from pythonseer.types import FormatType from pythonseer.types import FormatType
load_dotenv()
# Your own instance's domain # Your own instance's domain
LEMMY_DOMAIN = "lemmy.dbzer0.com" LEMMY_DOMAIN = "lemmy.dbzer0.com"
USERNAME = "username" USERNAME = "username"
# You can write your password here, or add it to the LEMMY_PASSWORD env var, or add LEMMY_PASSWORD to a .env file
PASSWORD = "password" PASSWORD = "password"
# If there's this many registered users per local post+comments, this site will be considered suspicious # If there's this many registered users per local post+comments, this site will be considered suspicious
ACTIVITY_SUSPICION = 20 ACTIVITY_SUSPICION = 20
@ -17,6 +20,9 @@ blacklist = {
"truthsocial.com", "truthsocial.com",
"threads.net", "threads.net",
} }
# Add instances in here which want to ensure are not added in your blocklist
whitelist = {
}
# If you (don't) want to combine your own censures, with the ones from other trusted instances, adjust the list below. # If you (don't) want to combine your own censures, with the ones from other trusted instances, adjust the list below.
# The censures will be the combined list from your own domain and any domains specified below. # The censures will be the combined list from your own domain and any domains specified below.
trusted_instances = [ trusted_instances = [
@ -31,9 +37,9 @@ reason_filters = []
# If you want to only censure instances which have been marked by more than 1 trusted instance, then increase the number below # If you want to only censure instances which have been marked by more than 1 trusted instance, then increase the number below
min_censures = 1 min_censures = 1
password = os.getenv("LEMMY_PASSWORD", PASSWORD)
lemmy = Lemmy(f"https://{LEMMY_DOMAIN}") lemmy = Lemmy(f"https://{LEMMY_DOMAIN}")
if lemmy.log_in(USERNAME, PASSWORD) is False: if lemmy.log_in(USERNAME, password) is False:
raise Exception("Could not log in to lemmy") raise Exception("Could not log in to lemmy")
fediseer = Fediseer() fediseer = Fediseer()
@ -52,7 +58,7 @@ censures = fediseer.censure.get_given(
min_censures = min_censures, min_censures = min_censures,
format = FormatType.LIST, format = FormatType.LIST,
) )
defed = blacklist | set(censures["domains"]) | set(sus["domains"]) defed = (blacklist | set(censures["domains"]) | set(sus["domains"])) - whitelist
# I need to retrieve the site info because it seems if "RequireApplication" is set # I need to retrieve the site info because it seems if "RequireApplication" is set
# We need to always re-set the application_question. # We need to always re-set the application_question.
# So we retrieve it from the existing site, to set the same value # So we retrieve it from the existing site, to set the same value

View File

@ -35,6 +35,8 @@ class Models:
'endorsements': fields.Integer(description="The amount of endorsements this instance has received"), 'endorsements': fields.Integer(description="The amount of endorsements this instance has received"),
'guarantor': fields.String(description="The domain of the instance which guaranteed this instance.", example="fediseer.com"), 'guarantor': fields.String(description="The domain of the instance which guaranteed this instance.", example="fediseer.com"),
'censure_reasons': fields.List(fields.String(description="The reasons instances have given for censuring this instance")), 'censure_reasons': fields.List(fields.String(description="The reasons instances have given for censuring this instance")),
'sysadmins': fields.Integer(required=False, default=None, description="The count of system administrators in this instance as reported by its admins."),
'moderators': fields.Integer(required=False, default=None, description="The count of community moderators in this instance as reported by its admins."),
}) })
self.response_model_model_Whitelist_get = api.model('WhitelistedInstances', { self.response_model_model_Whitelist_get = api.model('WhitelistedInstances', {
'instances': fields.List(fields.Nested(self.response_model_instances)), 'instances': fields.List(fields.Nested(self.response_model_instances)),
@ -60,4 +62,6 @@ class Models:
self.input_api_key_reset = api.model('ApiKeyResetInput', { self.input_api_key_reset = api.model('ApiKeyResetInput', {
'admin_username': fields.String(required=False, description="If a username is given, their API key will be reset. Otherwise the user's whose API key was provided will be reset. This allows can be initiated by other instance admins or the fediseer.", example="admin"), 'admin_username': fields.String(required=False, description="If a username is given, their API key will be reset. Otherwise the user's whose API key was provided will be reset. This allows can be initiated by other instance admins or the fediseer.", example="admin"),
'return_new_key': fields.Boolean(required=False, default=False, description="If True, the key will be returned as part of the response instead of PM'd. Fediseer will still PM a notification to the target admin account."), 'return_new_key': fields.Boolean(required=False, default=False, description="If True, the key will be returned as part of the response instead of PM'd. Fediseer will still PM a notification to the target admin account."),
'sysadmins': fields.Integer(required=False, default=None, min=0, max=100, description="Report how many system administrators this instance currently has."),
'moderators': fields.Integer(required=False, default=None, min=0, max=1000, description="Report how many instance moderators this instance currently has."),
}) })

View File

@ -105,7 +105,9 @@ class WhitelistDomain(Resource):
patch_parser.add_argument("apikey", type=str, required=True, help="The sending instance's API key.", location='headers') patch_parser.add_argument("apikey", type=str, required=True, help="The sending instance's API key.", location='headers')
patch_parser.add_argument("Client-Agent", default="unknown:0:unknown", type=str, required=False, help="The client name and version.", location="headers") patch_parser.add_argument("Client-Agent", default="unknown:0:unknown", type=str, required=False, help="The client name and version.", location="headers")
patch_parser.add_argument("admin_username", required=False, type=str, help="If a username is given, their API key will be reset. Otherwise the user's whose API key was provided will be reset. This allows can be initiated by other instance admins or the fediseer.", location="json") patch_parser.add_argument("admin_username", required=False, type=str, help="If a username is given, their API key will be reset. Otherwise the user's whose API key was provided will be reset. This allows can be initiated by other instance admins or the fediseer.", location="json")
patch_parser.add_argument("return_new_key", default=False, required=True, type=bool, help="If True, the key will be returned as part of the response instead of PM'd. IT will still PM a notification to you.", location="json") patch_parser.add_argument("return_new_key", default=False, required=False, type=bool, help="If True, the key will be returned as part of the response instead of PM'd. IT will still PM a notification to you.", location="json")
patch_parser.add_argument("sysadmins", default=None, required=False, type=int, help="How many sysadmins this instance has.", location="json")
patch_parser.add_argument("moderators", default=None, required=False, type=int, help="How many moderators this instance has.", location="json")
@api.expect(patch_parser,models.input_api_key_reset, validate=True) @api.expect(patch_parser,models.input_api_key_reset, validate=True)
@ -123,6 +125,14 @@ class WhitelistDomain(Resource):
raise e.Forbidden("You have not yet claimed an instance. Use the POST method to do so.") raise e.Forbidden("You have not yet claimed an instance. Use the POST method to do so.")
instance = database.find_instance_by_user(user) instance = database.find_instance_by_user(user)
requestor_instance = instance requestor_instance = instance
changed = False
new_key = None
if self.args.sysadmins is not None and instance.sysadmins != self.args.sysadmins:
instance.sysadmins = self.args.sysadmins
changed = True
if self.args.moderators is not None and instance.moderators != self.args.moderators:
instance.moderators = self.args.moderators
changed = True
if self.args.admin_username: if self.args.admin_username:
requestor = None requestor = None
if self.args.admin_username != user.username or user.username == "fediseer": if self.args.admin_username != user.username or user.username == "fediseer":
@ -142,11 +152,15 @@ class WhitelistDomain(Resource):
else: else:
new_key = activitypub_pm.pm_new_api_key(domain, self.args.admin_username, instance.software, requestor=requestor) new_key = activitypub_pm.pm_new_api_key(domain, self.args.admin_username, instance.software, requestor=requestor)
user.api_key = hash_api_key(new_key) user.api_key = hash_api_key(new_key)
db.session.commit() changed = True
if self.args.return_new_key: db.session.commit()
if changed is True:
if self.args.return_new_key and new_key is True:
return {"message": "Changed", "new_key": new_key},200 return {"message": "Changed", "new_key": new_key},200
else: else:
return {"message": "Changed"},200 return {"message": "Changed"},200
else:
return {"message": "OK"},200
delete_parser = reqparse.RequestParser() delete_parser = reqparse.RequestParser()
delete_parser.add_argument("apikey", type=str, required=True, help="The sending instance's API key.", location='headers') delete_parser.add_argument("apikey", type=str, required=True, help="The sending instance's API key.", location='headers')

View File

@ -72,6 +72,8 @@ class Instance(db.Model):
open_registrations = db.Column(db.Boolean, unique=False, nullable=False, index=True) open_registrations = db.Column(db.Boolean, unique=False, nullable=False, index=True)
email_verify = db.Column(db.Boolean, unique=False, nullable=False, index=True) email_verify = db.Column(db.Boolean, unique=False, nullable=False, index=True)
software = db.Column(db.String(50), unique=False, nullable=False, index=True) software = db.Column(db.String(50), unique=False, nullable=False, index=True)
sysadmins = db.Column(db.Integer, unique=False, nullable=True)
moderators = db.Column(db.Integer, unique=False, nullable=True)
approvals = db.relationship("Endorsement", back_populates="approving_instance", cascade="all, delete-orphan", foreign_keys=[Endorsement.approving_id]) approvals = db.relationship("Endorsement", back_populates="approving_instance", cascade="all, delete-orphan", foreign_keys=[Endorsement.approving_id])
endorsements = db.relationship("Endorsement", back_populates="endorsed_instance", cascade="all, delete-orphan", foreign_keys=[Endorsement.endorsed_id]) endorsements = db.relationship("Endorsement", back_populates="endorsed_instance", cascade="all, delete-orphan", foreign_keys=[Endorsement.endorsed_id])
@ -98,6 +100,8 @@ class Instance(db.Model):
"endorsements": len(self.endorsements), "endorsements": len(self.endorsements),
"approvals": len(self.approvals), "approvals": len(self.approvals),
"guarantor": self.get_guarantor_domain(), "guarantor": self.get_guarantor_domain(),
"sysadmins": self.sysadmins,
"moderators": self.moderators,
} }
return ret_dict return ret_dict

View File

@ -1,4 +1,4 @@
FEDISEER_VERSION = "0.7.0" FEDISEER_VERSION = "0.9.1"
SUPPORTED_SOFTWARE = [ SUPPORTED_SOFTWARE = [
"lemmy", "lemmy",
"mastodon", "mastodon",

View File

@ -0,0 +1,2 @@
ALTER TABLE instances ADD COLUMN sysadmins INTEGER;
ALTER TABLE instances ADD COLUMN moderators INTEGER;