aboutsummaryrefslogtreecommitdiff
path: root/auth.py
blob: a1ec562269b1ca52eafcde8393ad69afd8f35775 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
from datetime import datetime, timedelta
import io
import secrets
import socket

from sqlalchemy.orm.exc import NoResultFound

from database import AuthSession
from mapping import map_from, map_to
from messagehandler import handler
from myconfig import config, mappings
from netclass.jsonconverter import from_json

class InvalidTokenError(Exception):
	pass

class Auth:
	def __init__(self, dbsession, addr):
		self.dbsession = dbsession
		self.addr = addr
	
	def session(self, token):
		try:
			session = self.dbsession.query(AuthSession).filter_by(Token = token).one()
		except NoResultFound:
			raise InvalidTokenError()
		session.LastUsed = datetime.utcnow()
		session.LastIP = self.addr
		return session

	def create_session(self, user, app_name, app_description, version):
		session = AuthSession()
		session.Token = secrets.token_urlsafe()
		session.User = user
		session.AppName = app_name
		session.AppDesc = app_description
		session.Version = version
		
		session.Created = session.LastUsed = datetime.utcnow()
		session.LastIP = self.addr
		self.dbsession.add(session)
		return session


@handler("mud_token_login")
def mud_token_login(connection, contents):
	if connection.authsession is not None:
		connection.error("You're already logged in and tried to log in again.")
		return
	try:
		connection.authsession = connection.auth.session(contents)
		user = connection.authsession.User
		save = user.Save
		if save is None:
			connection.send_message("mud_login_denied")
		else:
			data = {"Upgrades": {u.Name: u.Installed for u in save.Upgrades},
					"CurrentLegions": [], #NYI
					"UniteAuthToken": connection.authsession.Token,
					"StoriesExperienced": [s.Name for s in save.StoriesExperienced],
					"Users": [map_to(u, mappings["ClientSave"]) for u in save.Users]}
			data.update(map_to(user, mappings["UserSave"]))
			data.update(map_to(save, mappings["Save"]))
			connection.send_message("mud_savefile", data)
	except InvalidTokenError:
		connection.send_message("mud_login_denied")

@handler("mud_save", dict)
def mud_save(connection, contents):
	user = connection.authsession.User
	save = user.Save
	if save is None:
		save = Save()
		user.Save = save
	map_from(user, mappings["UserSave"], contents)
	map_from(save, mappings["Save"], contents)
	connection.dbsession.query(Upgrade).filter_by(Save = save).delete()
	if contents["Upgrades"] is not None:
		for k, v in contents["Upgrades"].items():
			connection.dbsession.add(Upgrade(Name = k, Installed = v, Save = save))
	connection.dbsession.query(StoryExperienced).filter_by(Save = save).delete()
	if contents["StoriesExperienced"] is not None:
		for v in contents["StoriesExperienced"]:
			connection.dbsession.add(StoryExperienced(Name = v, Save = save))
	if contents["Users"] is not None:
		users_new = {u["Username"]: u for u in contents["Users"]}
		for usr in connection.dbsession.query(ClientSave).filter_by(Save = save):
			if usr.Username in users_new:
				map_from(usr, mappings["ClientSave"], users_new[usr.Username])
				del users_new[usr.Username]
			else:
				connection.dbsession.delete(usr)
		for data in users_new.values():
			usr = ClientSave(Save = save)
			map_from(usr, mappings["ClientSave"], data)
			connection.dbsession.add(usr)