Move tokens to new table
Move tokens to new table - Authcode linked to token
This commit is contained in:
parent
6994f5ae5e
commit
09e41cbc6e
2 changed files with 169 additions and 176 deletions
|
|
@ -7,6 +7,7 @@ from .xmppserver import XMPPServer
|
|||
import asyncio
|
||||
import contextvars
|
||||
import time
|
||||
from datetime import datetime, timedelta
|
||||
import platform
|
||||
import os
|
||||
import logging
|
||||
|
|
@ -22,6 +23,7 @@ server_cert = "./certs/cert.pem"
|
|||
server_key = "./certs/key.pem"
|
||||
|
||||
use_auth = False
|
||||
token_validity_seconds = 3600 #1 hour
|
||||
|
||||
# Logs
|
||||
bumperlog = logging.getLogger("bumper")
|
||||
|
|
@ -63,16 +65,12 @@ class BumperUser(object):
|
|||
def __init__(self, userid=""):
|
||||
self.userid = userid
|
||||
self.devices = []
|
||||
self.tokens = []
|
||||
self.authcodes = []
|
||||
self.bots = []
|
||||
|
||||
def asdict(self):
|
||||
return {
|
||||
"userid": self.userid,
|
||||
"devices": self.devices,
|
||||
"tokens": self.tokens,
|
||||
"authcodes": self.authcodes,
|
||||
"bots": self.bots,
|
||||
}
|
||||
|
||||
|
|
@ -90,6 +88,11 @@ def user_get(userid):
|
|||
User = Query()
|
||||
return users.get(User.userid == userid)
|
||||
|
||||
def user_by_deviceid(deviceid):
|
||||
users = db_get().table('users')
|
||||
User = Query()
|
||||
return users.get(User.devices.any([deviceid]))
|
||||
|
||||
def user_full_upsert(user):
|
||||
users = db_get().table('users')
|
||||
User = Query()
|
||||
|
|
@ -135,47 +138,52 @@ def user_remove_bot(userid, did):
|
|||
|
||||
users.upsert({'bots': userbots}, User.userid == userid)
|
||||
|
||||
def user_get_tokens(userid):
|
||||
tokens = db_get().table('tokens')
|
||||
return tokens.search((Query().userid == userid))
|
||||
|
||||
def user_get_token(userid, token):
|
||||
tokens = db_get().table('tokens')
|
||||
return tokens.get((Query().userid == userid) & (Query().token == token))
|
||||
|
||||
def user_add_token(userid, token):
|
||||
users = db_get().table('users')
|
||||
User = Query()
|
||||
user = users.get(User.userid == userid)
|
||||
usertokens = list(user['tokens'])
|
||||
if not token in usertokens:
|
||||
usertokens.append(token)
|
||||
tokens = db_get().table('tokens')
|
||||
tmptoken = tokens.get((Query().userid == userid) & (Query().token == token))
|
||||
if not tmptoken:
|
||||
tokens.insert({'userid':userid, 'token':token, 'expiration':"{}".format(datetime.now() + timedelta(seconds=token_validity_seconds))})
|
||||
|
||||
users.upsert({'tokens': usertokens}, User.userid == userid)
|
||||
def user_revoke_all_tokens(userid):
|
||||
tokens = db_get().table('tokens')
|
||||
tsearch = tokens.search(Query().userid == userid)
|
||||
for i in tsearch:
|
||||
tokens.remove(doc_ids=[i.doc_id])
|
||||
|
||||
def user_revoke_expired_tokens(userid):
|
||||
tokens = db_get().table('tokens')
|
||||
tsearch = tokens.search(Query().userid == userid)
|
||||
for i in tsearch:
|
||||
bumperlog.debug("Checking expiration of token {}: Is Current Time: {} >= Expiration: {}".format(i['token'],datetime.fromisoformat(i['expiration']), datetime.now()))
|
||||
if datetime.now() >= datetime.fromisoformat(i['expiration']):
|
||||
bumperlog.debug("Removing token {} due to expiration".format(i['token']))
|
||||
tokens.remove(doc_ids=[i.doc_id])
|
||||
|
||||
def user_revoke_token(userid, token):
|
||||
users = db_get().table('users')
|
||||
User = Query()
|
||||
user = users.get(User.userid == userid)
|
||||
usertokens = list(user['tokens'])
|
||||
if token in usertokens:
|
||||
usertokens.remove(token)
|
||||
tokens = db_get().table('tokens')
|
||||
tmptoken = tokens.get((Query().userid == userid) & (Query().token == token))
|
||||
if tmptoken:
|
||||
tokens.remove(doc_ids=[tmptoken.doc_id])
|
||||
|
||||
users.upsert({'tokens': usertokens}, User.userid == userid)
|
||||
|
||||
def user_add_authcode(userid, authcode):
|
||||
users = db_get().table('users')
|
||||
User = Query()
|
||||
user = users.get(User.userid == userid)
|
||||
userauthcodes = list(user['authcodes'])
|
||||
if not authcode in userauthcodes:
|
||||
userauthcodes.append(authcode)
|
||||
|
||||
users.upsert({'authcodes': userauthcodes}, User.userid == userid)
|
||||
|
||||
def user_revoke_authcode(userid, authcode):
|
||||
users = db_get().table('users')
|
||||
User = Query()
|
||||
user = users.get(User.userid == userid)
|
||||
userauthcodes = list(user['authcodes'])
|
||||
if authcode in userauthcodes:
|
||||
userauthcodes.remove(authcode)
|
||||
|
||||
users.upsert({'authcodes': userauthcodes}, User.userid == userid)
|
||||
def user_add_authcode(userid, token, authcode):
|
||||
tokens = db_get().table('tokens')
|
||||
tmptoken = tokens.get((Query().userid == userid) & (Query().token == token))
|
||||
if tmptoken:
|
||||
tokens.upsert({'authcode': authcode}, ((Query().userid == userid) & (Query().token == token)))
|
||||
|
||||
def user_revoke_authcode(userid, token, authcode):
|
||||
tokens = db_get().table('tokens')
|
||||
tmptoken = tokens.get((Query().userid == userid) & (Query().token == token))
|
||||
if tmptoken:
|
||||
tokens.upsert({'authcode': ''}, ((Query().userid == userid) & (Query().token == token)))
|
||||
|
||||
class VacBotDevice(object):
|
||||
def __init__(
|
||||
|
|
@ -228,9 +236,25 @@ class VacBotClient(object):
|
|||
|
||||
|
||||
def check_authcode(uid, authcode):
|
||||
users = bumper_users_var.get()
|
||||
for user in users:
|
||||
if uid == "fuid_{}".format(user.userid) and authcode in user.authcodes:
|
||||
bumperlog.debug("Checking for authcode: {}".format(authcode))
|
||||
tokens = db_get().table('tokens')
|
||||
tmpauth = tokens.get(
|
||||
(Query().authcode == authcode) & #Match authcode
|
||||
((Query().userid == uid.replace("fuid_","")) | (Query().userid == "fuid_{}".format(uid))) #Userid with or without fuid_
|
||||
)
|
||||
if tmpauth:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def check_token(uid, token):
|
||||
bumperlog.debug("Checking for token: {}".format(token))
|
||||
tokens = db_get().table('tokens')
|
||||
tmpauth = tokens.get(
|
||||
(Query().token == token) & #Match token
|
||||
((Query().userid == uid.replace("fuid_","")) | (Query().userid == "fuid_{}".format(uid))) #Userid with or without fuid_
|
||||
)
|
||||
if tmpauth:
|
||||
return True
|
||||
|
||||
return False
|
||||
|
|
|
|||
|
|
@ -185,50 +185,12 @@ class ConfServer:
|
|||
if (
|
||||
not user_devid == ""
|
||||
): # Performing basic "auth" using devid, super insecure
|
||||
users = bumper.db_get().table('users').all()
|
||||
for user in users:
|
||||
if user_devid in user['devices']:
|
||||
user = bumper.user_by_deviceid(user_devid)
|
||||
if "checkLogin" in request.path:
|
||||
if request.query[
|
||||
"accessToken"
|
||||
] in user['tokens'] and request.query[
|
||||
"uid"
|
||||
] == "fuid_{}".format(
|
||||
user['userid']
|
||||
):
|
||||
|
||||
body = {
|
||||
"code": bumper.RETURN_API_SUCCESS,
|
||||
"data": {
|
||||
"accessToken": request.query["accessToken"],
|
||||
"country": countrycode,
|
||||
"email": "null@null.com",
|
||||
"uid": "fuid_{}".format(user['userid']),
|
||||
"username": "fusername_{}".format(
|
||||
user['userid']
|
||||
),
|
||||
},
|
||||
"msg": "操作成功",
|
||||
"time": bumper.get_milli_time(time.time()),
|
||||
}
|
||||
return web.json_response(body)
|
||||
|
||||
self.check_token(countrycode, user, request.query["accessToken"])
|
||||
else:
|
||||
body = {
|
||||
"code": bumper.ERR_TOKEN_INVALID,
|
||||
"data": None,
|
||||
"msg": "当前密码错误",
|
||||
"time": bumper.get_milli_time(time.time()),
|
||||
}
|
||||
return web.json_response(body)
|
||||
else:
|
||||
|
||||
#Deactivate old tokens and authcodes
|
||||
for token in user['tokens']:
|
||||
bumper.user_revoke_token(user['userid'], token)
|
||||
|
||||
for authcode in user['authcodes']:
|
||||
bumper.user_revoke_authcode(user['userid'], authcode)
|
||||
bumper.user_revoke_expired_tokens(user['userid'])
|
||||
|
||||
body = {
|
||||
"code": bumper.RETURN_API_SUCCESS,
|
||||
|
|
@ -261,14 +223,44 @@ class ConfServer:
|
|||
except Exception as e:
|
||||
confserverlog.exception("{}".format(e))
|
||||
|
||||
|
||||
def check_token(self, countrycode, user, token):
|
||||
if (
|
||||
bumper.check_token(user['userid'], token)
|
||||
):
|
||||
body = {
|
||||
"code": bumper.RETURN_API_SUCCESS,
|
||||
"data": {
|
||||
"accessToken": token,
|
||||
"country": countrycode,
|
||||
"email": "null@null.com",
|
||||
"uid": "fuid_{}".format(user['userid']),
|
||||
"username": "fusername_{}".format(
|
||||
user['userid']
|
||||
),
|
||||
},
|
||||
"msg": "操作成功",
|
||||
"time": bumper.get_milli_time(time.time()),
|
||||
}
|
||||
return web.json_response(body)
|
||||
|
||||
else:
|
||||
body = {
|
||||
"code": bumper.ERR_TOKEN_INVALID,
|
||||
"data": None,
|
||||
"msg": "当前密码错误",
|
||||
"time": bumper.get_milli_time(time.time()),
|
||||
}
|
||||
return web.json_response(body)
|
||||
|
||||
def generate_token(self, user):
|
||||
tmpaccesstoken = uuid.uuid4().hex
|
||||
bumper.user_add_token(user['userid'],tmpaccesstoken)
|
||||
return tmpaccesstoken
|
||||
|
||||
def generate_authcode(self, countrycode, user):
|
||||
def generate_authcode(self, user, countrycode, token):
|
||||
tmpauthcode = "{}_{}".format(countrycode, uuid.uuid4().hex)
|
||||
bumper.user_add_authcode(user['userid'], tmpauthcode)
|
||||
bumper.user_add_authcode(user['userid'], token, tmpauthcode)
|
||||
return tmpauthcode
|
||||
|
||||
|
||||
|
|
@ -276,11 +268,11 @@ class ConfServer:
|
|||
try:
|
||||
user_devid = devid
|
||||
countrycode = country
|
||||
users = bumper.db_get().table('users').all()
|
||||
user = bumper.user_by_deviceid(user_devid)
|
||||
bots = bumper.db_get().table('bots').all()
|
||||
|
||||
if len(users) > 0: #Default to user 0
|
||||
tmpuser = users[0]
|
||||
if user: #Default to user 0
|
||||
tmpuser = user
|
||||
bumper.user_add_device(tmpuser['userid'], user_devid)
|
||||
else:
|
||||
bumper.user_add("tmpuser") #Add a new user
|
||||
|
|
@ -291,26 +283,13 @@ class ConfServer:
|
|||
bumper.user_add_bot(tmpuser['userid'], bot['did'])
|
||||
|
||||
if "checkLogin" in request.path: #If request was to check a token do so
|
||||
if request.query["accessToken"] in tmpuser['tokens']:
|
||||
return {
|
||||
"code": bumper.RETURN_API_SUCCESS,
|
||||
"data": {
|
||||
"accessToken": request.query["accessToken"], # Random chars 32 length
|
||||
"country": countrycode,
|
||||
"email": "null@null.com",
|
||||
"uid": "fuid_{}".format(tmpuser['userid']),
|
||||
"username": "fusername_{}".format(tmpuser['userid']),
|
||||
},
|
||||
"msg": "操作成功",
|
||||
"time": bumper.get_milli_time(time.time()),
|
||||
}
|
||||
checkToken = self.check_token(countrycode, user, request.query["accessToken"])
|
||||
isGood = json.loads(checkToken.text)
|
||||
if isGood['code'] == "0000":
|
||||
return isGood
|
||||
|
||||
#Deactivate old tokens and authcodes
|
||||
for token in tmpuser['tokens']:
|
||||
bumper.user_revoke_token(tmpuser['userid'], token)
|
||||
|
||||
for authcode in tmpuser['authcodes']:
|
||||
bumper.user_revoke_authcode(tmpuser['userid'], authcode)
|
||||
bumper.user_revoke_expired_tokens(tmpuser['userid'])
|
||||
|
||||
body = {
|
||||
"code": bumper.RETURN_API_SUCCESS,
|
||||
|
|
@ -334,22 +313,13 @@ class ConfServer:
|
|||
try:
|
||||
user_devid = request.match_info.get("devid", "")
|
||||
if not user_devid == "":
|
||||
|
||||
users = bumper.db_get().table('users').all()
|
||||
for user in users:
|
||||
if user_devid in user['devices']:
|
||||
user = bumper.user_by_deviceid(user_devid)
|
||||
if user:
|
||||
if (
|
||||
request.query["uid"] == "fuid_{}".format(user['userid'])
|
||||
and request.query["accessToken"] in user['tokens']
|
||||
bumper.check_token(user['userid'], request.query["accessToken"])
|
||||
):
|
||||
#Deactivate old tokens and authcodes
|
||||
for token in user['tokens']:
|
||||
bumper.user_revoke_token(user['userid'], token)
|
||||
#bumper.user_revoke_token(user['userid'],request.query["accessToken"])
|
||||
|
||||
for authcode in user['authcodes']:
|
||||
bumper.user_revoke_authcode(user['userid'], authcode)
|
||||
|
||||
bumper.user_revoke_token(user['userid'], request.query["accessToken"])
|
||||
|
||||
body = {
|
||||
"code": bumper.RETURN_API_SUCCESS,
|
||||
|
|
@ -368,18 +338,20 @@ class ConfServer:
|
|||
|
||||
user_devid = request.match_info.get("devid", "")
|
||||
if not user_devid == "":
|
||||
users = bumper.db_get().table('users').all()
|
||||
if len(users) > 0:
|
||||
for user in users:
|
||||
if (
|
||||
user_devid in user['devices']
|
||||
and request.query["accessToken"] in user['tokens']
|
||||
):
|
||||
user = bumper.user_by_deviceid(user_devid)
|
||||
if user:
|
||||
token = bumper.user_get_token(user['userid'], request.query["accessToken"])
|
||||
if token:
|
||||
authcode = ""
|
||||
if not 'authcode' in token:
|
||||
authcode = self.generate_authcode(user, request.match_info.get("country", "us"), request.query["accessToken"])
|
||||
else:
|
||||
authcode = token['authcode']
|
||||
|
||||
body = {
|
||||
"code": bumper.RETURN_API_SUCCESS,
|
||||
"data": {
|
||||
"authCode": self.generate_authcode(request.match_info.get("country", "us"), user),
|
||||
"authCode": authcode,
|
||||
"ecovacsUid": request.query["uid"],
|
||||
},
|
||||
"msg": "操作成功",
|
||||
|
|
@ -560,13 +532,10 @@ class ConfServer:
|
|||
}
|
||||
elif service == "EcoUpdate":
|
||||
body = {"result": "ok", "ip": "47.88.66.164", "port": 8005}
|
||||
elif todo == "loginByItToken":
|
||||
|
||||
users = bumper.db_get().table('users').all()
|
||||
for user in users:
|
||||
elif todo == "loginByItToken":
|
||||
if (
|
||||
postbody["userId"] == "fuid_{}".format(user['userid'])
|
||||
and postbody["token"] in user['authcodes']
|
||||
bumper.check_authcode(postbody["userId"], postbody["token"])
|
||||
):
|
||||
body = {
|
||||
"resource": postbody["resource"],
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue