Skip to content

Commit

Permalink
Added %SecurityAudit command. Companion now auto creates a
Browse files Browse the repository at this point in the history
`companion-administration` channel. Audit reports show there.

Changes to be committed:
	modified:   Companion
  • Loading branch information
rapmd73 committed Oct 25, 2024
1 parent 73305ff commit d01982c
Showing 1 changed file with 121 additions and 29 deletions.
150 changes: 121 additions & 29 deletions Companion
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,7 @@ from io import BytesIO

# Active version

Version="0.0.0.0.880"
Version="0.0.0.0.890"

# The running name of the program. Must be global and NEVER changing.

Expand Down Expand Up @@ -1502,10 +1502,116 @@ async def ModeratorNotify(bot,guild,text):
await channel.send(text)
break

# Verify the CompanionAdministration channel exists and is set to the owner role.

async def VerifyCompanionAdministration(guild):
# Check for the 'CompanionAdministration' channel
channel=discord.utils.get(guild.text_channels, name='companion-administration')

# If the channel does not exist, create it
if not channel:
# Get the 'owner' role
owner_role = discord.utils.get(guild.roles, name='owner')

if owner_role:
# Create the channel and set permissions
channel = await guild.create_text_channel(
'companion-administration',
overwrites={
guild.default_role: discord.PermissionOverwrite(read_messages=False), # Deny everyone else
owner_role: discord.PermissionOverwrite(read_messages=True,send_messages=True)
},
position=len(guild.channels),
topic='This channel is for Companion administration.'
)
else:
# Owner role does not exist
return None
return channel

# Perform security audit on a given guild

async def SecurityAudit(guild=None,message=None):
pass
async def SecurityAudit(guild=None,message=None,auto=False):
# failsafe catch
if guild==None and message==None:
return

# Do nothing if there is no owner role
orole=discord.utils.get(guild.roles,name='owner')
if not orole:
return

# Make sure we have a guild structure
if not guild and message:
guild=message.guild

# Create the CompanionAdministration area (if not exist) and get the channel
admin=await VerifyCompanionAdministration(guild)

# Start with the automatic setting. Results will be forced if audit fails
ShowResults=auto
FailedAudit=False
AuditOwnerRole=False
IsHighestPos=False
IsOwnerInRole=False
GuildVerification=False
ExplicitContent=False
MFAlevel=False

if orole:
AuditOwnerRole=True
hrp=max(role.position for role in guild.roles) # Get the highest role position
if orole.position==hrp:
IsHighestPos=True
else:
FailedAudit=True

urole=discord.utils.get(guild.owner.roles,name='owner')
if urole:
IsOwnerInRole=True
else:
FailedAudit=True
else:
FailedAudit=True

if str(guild.verification_level.name)=='highest':
GuildVerification=True
else:
FailedAudit=True

if str(guild.explicit_content_filter)=='all_members':
ExplicitContent=True
else:
FailedAudit=True

if str(guild.mfa_level)=='MFALevel.require_2fa':
MFAlevel=True
else:
FailedAudit=True

# Report the results
if ShowResults or FailedAudit:
await admin.send(f"Guild: {guild.name} ({guild.id})")
await admin.send(f"Owner: {guild.owner} ({guild.owner.id})")
if not AuditOwnerRole:
await admin.send(f"The `owner` role does not exist.")
if not IsHighestPos:
await admin.send(f"The `owner` role does NOT have the highet position in the role list.")
if not IsOwnerInRole:
await admin.send(f"{guild.owner} is NOT in the `owner` role.")
if not GuildVerification:
await admin.send(f"this guild is NOT protected with the highest verification level.")
if not ExplicitContent:
await admin.send(f"Member content is NOT protected.")
if not MFAlevel:
await admin.send(f"This guild is NOT protected by two factor authentication")
if ShowResults:
await admin.send(f"Current Members: {guild.member_count}")
if FailedAudit:
await admin.send(f"**This server has FAILED the security audit.** Please correct the above issues as quickly as possible. Thank you.")
else:
if ShowResults:
await admin.send(f"**This server has PASSED the security audit.**")

###
### Background Tasks
Expand Down Expand Up @@ -1900,14 +2006,20 @@ async def on_message(message):
await message.channel.send(f'You have messaged the Companion AI chatbot/moderation. This bot functions ONLY within the limits of a Discord server and does NOT support interactions via DMs. Thank you.')
return

# Owner role information. This will be used to verify bot commands.
orole=discord.utils.get(guild.roles,name='owner')
mrole=orole and orole in message.author.roles

# Figure out which persona is calling the shots.
guild=message.guild
channel=str(message.channel)
uid=str(message.author.id)

# Owner role information. This will be used to verify bot commands.
orole=discord.utils.get(guild.roles,name='owner')
# Bots/webhooks will breaks this... safe way to make sure webhook can
# never be registered as owner
if not message.author.bot:
mrole=orole and orole in message.author.roles
else:
mrole=None

# Handle auto publish
if message.channel.type==discord.ChannelType.news:
await message.publish()
Expand Down Expand Up @@ -1935,7 +2047,6 @@ async def on_message(message):
# MUST BE FIRST!
# Imposter among us no more!
# Check to see if the user trying to impersonate the owner
guild=message.guild
owner=guild.owner
owner_name=owner.name.lower()
owner_nick=owner.display_name.lower()
Expand Down Expand Up @@ -2034,7 +2145,8 @@ async def on_message(message):
# Only guild owner/Owner role allowed to use advanced commands
if mrole:
if str(message.content).strip().startswith('%SecurityAudit'):
await SecurityAudit(guild,message)
await message.delete()
await SecurityAudit(guild,message,True)
return

if str(message.content).strip().startswith('%CheckBot'):
Expand Down Expand Up @@ -2173,31 +2285,11 @@ async def on_ready():

try:
# Print some fluff
print("In guilds:")
for guild in client.guilds:
# Make sure the neccessary directories exist
mkdir(f'{MemoryStorage}/{guild.id}')
mkdir(f'{LoggingStorage}/{guild.id}')

print(f" {guild.name} ({guild.id}), {guild.owner} ({guild.owner.id})")
ofound=False
orole=discord.utils.get(guild.roles,name='owner')
if orole:
print(f" Owner role exists")
hrp=max(role.position for role in guild.roles) # Get the highest role position
if orole.position!=hrp:
print(f" Owner role does NOT have the highest position")

urole=discord.utils.get(guild.owner.roles,name='owner')
if urole:
print(f" {guild.owner} is in the owner role")
else:
print(f" {guild.owner} is NOT in the owner role")
else:
print(f" NO owner role found!")

print(f" {guild.verification_level.name}, {guild.explicit_content_filter}, {guild.mfa_level}, {guild.member_count} members")

# Check if the bot's role has administrator permissions
if not guild.me.guild_permissions.administrator:
print(f" Error: Companion does not have administrator privileges in {guild.name}.")
Expand Down

0 comments on commit d01982c

Please sign in to comment.