From 3a9a50c4ea3428b788153f77f42f4ecf992a2a0a Mon Sep 17 00:00:00 2001
From: amy <milkdrop2000@protonmail.com>
Date: Tue, 20 Oct 2020 02:09:51 +0200
Subject: [PATCH] First version!

---
 __pycache__/msgData.cpython-37.pyc      | Bin 0 -> 2043 bytes
 __pycache__/msgTemplates.cpython-37.pyc | Bin 1441 -> 1693 bytes
 __pycache__/utils.cpython-37.pyc        | Bin 828 -> 946 bytes
 bot.py                                  |  83 +++++++++++++++---------
 msgData.py                              |  34 ++++++++++
 msgTemplates.py                         |  27 --------
 utils.py                                |   5 +-
 7 files changed, 90 insertions(+), 59 deletions(-)
 create mode 100644 __pycache__/msgData.cpython-37.pyc
 create mode 100644 msgData.py
 delete mode 100644 msgTemplates.py

diff --git a/__pycache__/msgData.cpython-37.pyc b/__pycache__/msgData.cpython-37.pyc
new file mode 100644
index 0000000000000000000000000000000000000000..1ec048f3f9f7ac9be4662113db1e17c8eb7c9892
GIT binary patch
literal 2043
zcmZ?b<>g{vU|>ks>WlYhXJB{?;=nK)0|SEt0|P^G90LPG3PTh_3S$&w3R4Pm3d<a(
zD5ezF6t+ypDCQLQD3%nCDAp9tD7F-?DE1WYD2^1KD9#k#D6SN~DDD*gD4rC7DBcvo
zD83Y-DE<`T6p<9s6tNWX6p3`UD1j8oU<OU8L^nnT2CMYc#3Cz&@YI~-{M=N9l6(a%
zE$3jL%p@%>1*jaCr$TvVPL4uaW>Im8LSAZW3P@R5YEfodr9x$XX^}!=a&mrYUWuYY
zaB5zPLT)NVG{K=bza&3TFELrKG&@0|G%vF(wWv6=q*5VOH#adeM<FpKr6{$ySRtuW
zp|m(NFWpKZp}L?bH7&EEwkS0{v$!O+2y9X+NHvOKFejB{q~<9UgDkDgFI7m)gPB~O
zS(2fUr~r0jW^!UlW`3SRa(+sx9>j&2B_JOpB_?Ns=-gC=#A1cw(&P*z2Y|Igya#4N
zO#vB_ppclCqL7|i0yRH1MX^d98diwFb1W^%$V~+Mp{%+V8kSsD*5Dw*;xv#;z=0W@
zUs{rpm|IYi5BCl<psKvWkODm=vp6}wC<PYy3Sd8%WTZk}h2(36qSWNn%(B!Jg|f^<
zXb@>KRjCmd*j36fb>M)&9wt>hFhv=uIR#aM!5R7G3MCnt#R|Ep#l?x~sa1->sd=yv
zgSrix3`+7r;a;0i)$3N2pKGN6PJRkV;b)UvoRgUZ^>0#si9<RlLFgst=h|_F<ij--
z6cnZAm1HKTD%e!l+HnP!CS|22m%yaKK?jXRF0M#WvV~X#_7zkDoJbThi>(x@Ypcv7
z^Gg*n63bE*l2TLipuw7&qKKSXK;aEBCOJPhw=^%aq*AX+wYpXzD?c+YH3jOIwEQB4
zl8n^MB4{2e$;?evtg@-Dg&PW$hJ*+tI3Rffssb8fpyUUUt;!0?NG(cL$Ve=PI1iNg
zi;D7#z}X=)FCCE^^b|bPK=}w1A9>jzvREOrSRqlNpeR2nCpA|`p&%zUu{c#BIX|x?
zF}Xw`5$bH;#Jt4x)FQ<y&4lXO1hAewh0MIN#GK3&1+?4^ak);FyeCv1BUqvC_5g)y
za$;Uyeu+Y2F*pN)l~zI=1~CU-G=M@bF)zO)Bee*uUm-U$ue2mpqgXSc${D9gP#w^u
zu7J-F!%$G_v{KO0f+b-5MUR$Nl^%u`s0TpV7tDmFCQxi?X;n!E=jW!DWPsuXRCpFE
zlw{^*rxs=A*;k4CCZ?o9a&At3S*k*2o<cCF%&g*eN=(krQ%C}lRVv{bl?o~O3gw{a
zE=yG?O3X{i&s9ju&o5DcX0KxVDlw3%y!;YH1<ztoa#BdlD=tqhs^SkW0hQjFc?ym>
z1sREoewu=}c#xfWiwl%zJyH`>Qj2b}f!Hp&w>UtwZ(?TNEfHk3zKNMRpp1M=0$nsD
zwW7o+Kc(^(Pib*#5hS;zrrhGq$xjb0PA&2R=Z9PTP%d1aGZmC*LB`$^05hTK2P`5A
z7J;aR<N)XVl+;^-U}0BKArO+8o0?x*0@Vw$2qwZ?3X0euXgzX^8_We8Re6gC6m-6j
zf~j~VLy-^z1BCdcuAh;go2s9fTd5yVln*LDiuJ*zk8V<aiGFTzx=Uh7qFzDeEe@O9
p{FKt1R6Ax+b*;p}z`(-9!o<YL!OX$T!pg$P!UV;PEFcKx0RZ<y#-acK

literal 0
HcmV?d00001

diff --git a/__pycache__/msgTemplates.cpython-37.pyc b/__pycache__/msgTemplates.cpython-37.pyc
index b380e66d1d4672873baaa24b62242b8c76280f9e..d57ae014b94914ff1eb9914938b2ef3f3a667bac 100644
GIT binary patch
delta 527
zcmZ3;J(riyiI<m)fq{XcQ?4(bgKZ+81f$zTbsIsh6#gjg6oDw76v1EyO`$}$i8+&`
zstbxz(=sb+i&E1wi%U|A6e{yei&AqFGjk^MGo~xUq{~u^GSe!-l3-?La$-qleqM5Z
zO6ue$#uH&`Fol@rI27lX<mc%nChL`ER}o`i6%Wj?&2>z>80(!Q^Gg+y6Z7)&OB51|
zvlUA66~Jz&R7lLrFUd$PQb^SWIanbrzX&E|rI1ivtB{+SS6Y&)QLLFzWrx#{k_`O%
z>mdf{hZZNMr&=k%+y?h(0zAZ!eVS0EgQfxMX0UQF8z~GE{4{xQ@gR%d;>t+PDey>5
zOqo23rA;VGAhoC{zbLdgwJ0PrH#NVsWU>Nls)7sy0|N^a3lkF~2QvpV3o8pF3lj??
J6f&_e0swvTw=4hv

delta 230
zcmbQsyO5jDiI<m)fq{WRlD99OiFG2M1f$(VbsJ9Z6#ifaO@TzUi6xT+6^l~SGmA@7
zixeXLLxXfZT_!6qrt>J4r50tTRVq09ySPqX#dyL*7DJswaehgDo?c?IUTJofAWVZ}
zXo!a{NLLlB;^q@fyBNJxLW>jAQ>_&68=wGF1+^GVWhN(<Waj7TCg-Q5`f2h^&S0H4
SS%NK<QDSl(n*=ix3nKstt3~zz

diff --git a/__pycache__/utils.cpython-37.pyc b/__pycache__/utils.cpython-37.pyc
index 276b69728cad34ea1f1b999200e3dcc600a3f1e7..7dff01dd38a94160bc07a2b6d6918225fe586300 100644
GIT binary patch
delta 175
zcmdnPwuznBiI<m)fq{WxrD|V%^h91sMvIB+2E3dpTrCVyY$=Sv44T{<V|tk~lNmv(
z7#J8pG&2JOgEIpILorBe3gZHX8is`+rA&TRY&H&x)wOn-jJMd*@{4j4OEejy*h-62
zi!xJ+I2jliAOuL?E#{KMbSaQ2Odz8fi-Z{%7&O@@zh+Wq6rRk*ti}gY#lgtK#KFbE
H!NCFmh(aFo

delta 60
zcmdnQzK4z1iI<m)fq{YH)4Sey&568{j0O|c4Okh288kUJrt~r~X|hd@Vpg8q#H_@_
Q!N9=4!N|kJ!NtJ=0IIeNt^fc4

diff --git a/bot.py b/bot.py
index 91ea6e2..594559d 100644
--- a/bot.py
+++ b/bot.py
@@ -1,18 +1,21 @@
 import discord, asyncio
 import os, sys, string, random, time
-import msgTemplates, utils
+import msgData, utils
 
 def getPath():
 	return os.path.dirname(os.path.realpath(__file__))
 
 # Maybe move these to a config?
-cslibServerID = 763446305006682142
-memberRoleID = 763872584408104960
+cslibServerId = 763446305006682142
+cslibLoggingChannelId = 767872605818191883
+verifiedMemberRoleId = 763872584408104960
 version = "0.1"
-prefix = "!"
+prefix = "-"
+registrationTimeout = 30 # minutes
 
 client = discord.Client()
 registrationDb = {}
+registrationEmailTimeout = {}
 registrationUserTimeout = {}
 
 @client.event
@@ -20,68 +23,82 @@ async def on_message (message):
 	if (message.author == client.user):
 		return
 
+	sendMsg = message.channel.send
+
 	if (message.content.lower ().startswith (prefix)):
 		command = message.content[len(prefix):].split(" ")
 		command[0] = command[0].lower()
 
-		# We are in a private chat
+		# We are not in a private DM chat
 		if (type(message.channel) is not discord.DMChannel):
 			if (command[0] == "help"):
-				outMsg = msgTemplates.helpHeader.format(version)
+				outMsg = msgData.helpHeader.format(version)
 
-				for cmd in msgTemplates.helpMain:
-					outMsg += "\t- **{}**: `{}`\n".format(cmd, msgTemplates.helpMain[cmd])
+				for cmd in msgData.helpMain:
+					outMsg += "\t**{}**: `{}`\n".format(cmd.format(prefix = prefix), msgData.helpMain[cmd])
 					
-				return await message.channel.send(outMsg)
+				return await sendMsg(outMsg)
 
 		else:
 			if (command[0] == "help"):
-				outMsg = msgTemplates.helpHeader.format(version)
+				outMsg = msgData.helpHeader.format(version)
 
-				for cmd in msgTemplates.helpDm:
-					outMsg += "\t- **{}**: `{}`\n".format(cmd, msgTemplates.helpDm[cmd])
+				for cmd in msgData.helpDm:
+					outMsg += "\t**{}**: `{}`\n".format(cmd.format(prefix = prefix), msgData.helpDm[cmd])
 					
-				return await message.channel.send(outMsg)
+				return await sendMsg(outMsg)
 
 			if (command[0] == "register"):
 				if (len(command) == 1):
-					return await message.channel.send(msgTemplates.usageRegister)
+					return await sendMsg(msgData.usageRegister.format(prefix = prefix))
 
 				email = command[1].strip()
 				if (not utils.validateMail (email)):
-					return await message.channel.send(msgTemplates.errorInvalidMail.format(email))
-					
+					return await sendMsg(msgData.errorInvalidMail.format(email))
+				
+				# Ugly! Maybe move these to utils.py...
+				if (email in registrationEmailTimeout and time.time() - registrationEmailTimeout[email] < registrationTimeout * 60):
+					timeLeft = registrationTimeout - int(time.time() - registrationEmailTimeout[email]) // 60
+					return await sendMsg(msgData.errorEmailTimeout.format(timeLeft))
+				
+				if (message.author.id in registrationUserTimeout and time.time() - registrationUserTimeout[message.author.id] < registrationTimeout * 60):
+					timeLeft = registrationTimeout - int(time.time() - registrationUserTimeout[message.author.id]) // 60
+					return await sendMsg(msgData.errorUserTimeout.format(timeLeft))
+
+				registrationEmailTimeout[email] = int(time.time())
+				registrationUserTimeout[message.author.id] = int(time.time())
+
 				verificationCode = ''.join(random.choices(string.ascii_lowercase + string.digits, k=16))
-				registrationDb[verificationCode] = message.author.id
+				registrationDb[verificationCode] = {"userId": message.author.id, "email": email}
 				
 				try:
-					utils.sendMail(email, msgTemplates.verificationMailTextBody.format(email, verificationCode))
+					utils.sendMail(email, msgData.verificationMailTextBody.format(email, verificationCode))
 				except:
-					return await message.channel.send(msgTemplates.errorMail)
+					return await sendMsg(msgData.errorMail.format(prefix = prefix))
 					
-				await message.channel.send(msgTemplates.verificationMailSent.format(email))
+				await sendMsg(msgData.verificationMailSent.format(email))
 
 			if (command[0] == "verify"):
 				if (len(command) == 1):
-					return await message.channel.send(msgTemplates.usageVerify)
+					return await sendMsg(msgData.usageVerify.format(prefix = prefix))
 
 				verificationCode = command[1]
 				if (verificationCode in registrationDb):
-					userId = registrationDb[verificationCode]
-					guild = client.get_guild(cslibServerID)
-					await guild.get_member(userId).edit(roles = [guild.get_role(memberRoleID)])
+					userId = registrationDb[verificationCode]["userId"]
+					email = registrationDb[verificationCode]["email"]
+					guild = client.get_guild(cslibServerId)
+					await guild.get_member(userId).edit(roles = [guild.get_role(verifiedMemberRoleId)])
 					registrationDb.pop(verificationCode, None)
 					
-					await message.channel.send(msgTemplates.userVerified)
+					await sendMsg(msgData.userVerified.format(prefix = prefix))
+					await log(msgData.logUserVerified.format(utils.tag(userId), email, verificationCode))
 
 				else:
-					await message.channel.send(msgTemplates.errorVerificationCode.format(command[1]))
+					await sendMsg(msgData.errorVerificationCode.format(command[1]))
 
 @client.event
 async def on_member_join(member):
-	print(member.display_name + "#" + member.discriminator + " Joined.")
-
-	dmChannel = member.create_dm()
+	dmChannel = await member.create_dm()
 	sentIntroBefore = False
 	async for message in dmChannel.history(limit=200):
 		if message.author == client.user:
@@ -89,13 +106,17 @@ async def on_member_join(member):
 			break
 
 	if (not sentIntroBefore):
-		await dmChannel.send(msgTemplates.verification)
+		await dmChannel.send(msgData.verification.format(prefix = prefix))
+		await log(msgData.logUserJoined.format(utils.tag(member.id)))
 
 @client.event
 async def on_ready():
-	print(client.user.name + " v" + version + " booted up.\n" + "\"Something needs tinkerin'?\"")
+	print(client.user.name + " v" + version + " booted up.\n" + random.choice(msgData.bootMessages))
 	await client.change_presence(activity = discord.Game(name = prefix + "help"))
 
+async def log(message):
+	await client.get_channel(cslibLoggingChannelId).send(message)
+
 tokenFile = getPath() + "/token"
 if (not os.path.isfile(tokenFile)):
 	print("Please create a 'token' file with the discord bot token in it.")
diff --git a/msgData.py b/msgData.py
new file mode 100644
index 0000000..e594598
--- /dev/null
+++ b/msgData.py
@@ -0,0 +1,34 @@
+verification = """:gear: Welcome to **CSLib** :gear: 
+I will first need to verify your account! Send me your `@soton.ac.uk` university e-mail address by using: `{prefix}register youremail@soton.ac.uk`
+I will then send you an e-mail with a verification code. Send it to back to me as such: `{prefix}verify yourverificationcode` and get verified!"""
+
+helpHeader = ":gear: **CSLib** The Authmaster v{} :gear:\n"
+helpDm = {
+	"{prefix}register youremail@soton.ac.uk": "Send a verification code to your Southampton e-mail address",
+	"{prefix}verify yourverificationcode": "Verify your discord account with the verification code received via e-mail"
+}
+helpMain = {
+	"{prefix}help": "Show this message"	
+}
+
+verificationMailSent = "Sent verification e-mail to: `{}`"
+verificationMailTextBody = """From: CSLib The Authmaster <cslibdiscordbot@gmail.com>
+To: CSLib Apprentice <{}>
+Subject: CSLib Verification
+
+Your CSLib verification code is: {}"""
+userVerified = "You have been verified! Welcome to the CSLib community."
+
+logUserJoined = "{} joined CSLib for their first time!"
+logUserVerified = "{} verified their e-mail: `{}` using verification code: `{}`"
+
+errorMail = "There has been an error sending an e-mail. If you think this is a problem, please contact a CSLib Manager!"
+errorInvalidMail = "`{}` is an invalid `@soton.ac.uk` e-mail,"
+errorVerificationCode = "Invalid verification code: `{}`"
+errorEmailTimeout = "You cannot ask to verify this e-mail address for another: `{} minute(s)`"
+errorUserTimeout = "You cannot ask to verify another e-mail for another: `{} minute(s)`"
+
+usageRegister = "Usage: **{prefix}register youremail@soton.ac.uk**"
+usageVerify = "Usage: **{prefix}verify yourverificationcode**"
+
+bootMessages = ["Something needs tinkerin?", "Made with love in Soton", "Bacon bacon", "Why do we have random boot messages?", "Why not! Is the answer", "Still in Alpha!"]
\ No newline at end of file
diff --git a/msgTemplates.py b/msgTemplates.py
deleted file mode 100644
index 2e08c04..0000000
--- a/msgTemplates.py
+++ /dev/null
@@ -1,27 +0,0 @@
-verification = """:gear: Welcome to **CSLib** :gear: 
-I will first need to verify your account! Send me your `@soton.ac.uk` university e-mail address by using: `!register YOUR-ID@soton.ac.uk`
-I will then send you an e-mail with a verification code. Send it to back to me as such: `!verify verification-code` and get verified!"""
-
-helpHeader = ":gear: **CSLib** Authmaster v{} :gear:\n"
-helpDm = {
-	"!register YOUR-ID@soton.ac.uk": "Send a verification code to your Southampton e-mail address",
-	"!verify AUTH-CODE": "Verify your discord account with the verification code received via e-mail"
-}
-helpMain = {
-	"!help": "Show this message"	
-}
-
-verificationMailSent = "Sent verification e-mail to: `{}`"
-verificationMailTextBody = """From: CSLib Authmaster <cslibdiscordbot@gmail.com>
-To: CSLib Apprentice <{}>
-Subject: CSLib Verification
-
-Your CSLib verification code is: {}"""
-userVerified = "You have been verified! Welcome to the CSLib community."
-
-errorMail = "There has been an error sending an e-mail. If you think this is a problem, please contact a CSLib Manager!"
-errorInvalidMail = "`{}` is an invalid `@soton.ac.uk` e-mail"
-errorVerificationCode = "Invalid verification code: `{}`"
-
-usageRegister = "Usage: !register `YOUR-ID@soton.ac.uk`"
-usageVerify = "Usage: !verify `verification-code`"
\ No newline at end of file
diff --git a/utils.py b/utils.py
index f342997..589b600 100644
--- a/utils.py
+++ b/utils.py
@@ -21,4 +21,7 @@ def setupMail():
 
 def sendMail(receiver, text):
 	receiver = [receiver] # Do we really need this?
-	smtpObj.sendmail('cslibdiscordbot@gmail.com', receiver, text)
\ No newline at end of file
+	smtpObj.sendmail('cslibdiscordbot@gmail.com', receiver, text)
+
+def tag(userid):
+	return "<@!{}>".format(userid)
\ No newline at end of file
-- 
GitLab