Tinydb added #11

Merged
bmartin5692 merged 5 commits from tinydb into master 2019-03-12 02:05:18 +01:00
2 changed files with 169 additions and 176 deletions
Showing only changes of commit 09e41cbc6e - Show all commits

View file

@ -7,6 +7,7 @@ from .xmppserver import XMPPServer
import asyncio import asyncio
import contextvars import contextvars
import time import time
from datetime import datetime, timedelta
import platform import platform
import os import os
import logging import logging
@ -22,6 +23,7 @@ server_cert = "./certs/cert.pem"
server_key = "./certs/key.pem" server_key = "./certs/key.pem"
use_auth = False use_auth = False
token_validity_seconds = 3600 #1 hour
# Logs # Logs
bumperlog = logging.getLogger("bumper") bumperlog = logging.getLogger("bumper")
@ -63,16 +65,12 @@ class BumperUser(object):
def __init__(self, userid=""): def __init__(self, userid=""):
self.userid = userid self.userid = userid
self.devices = [] self.devices = []
self.tokens = []
self.authcodes = []
self.bots = [] self.bots = []
def asdict(self): def asdict(self):
return { return {
"userid": self.userid, "userid": self.userid,
"devices": self.devices, "devices": self.devices,
"tokens": self.tokens,
"authcodes": self.authcodes,
"bots": self.bots, "bots": self.bots,
} }
@ -90,6 +88,11 @@ def user_get(userid):
User = Query() User = Query()
return users.get(User.userid == userid) 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): def user_full_upsert(user):
users = db_get().table('users') users = db_get().table('users')
User = Query() User = Query()
@ -135,47 +138,52 @@ def user_remove_bot(userid, did):
users.upsert({'bots': userbots}, User.userid == userid) 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): def user_add_token(userid, token):
users = db_get().table('users') tokens = db_get().table('tokens')
User = Query() tmptoken = tokens.get((Query().userid == userid) & (Query().token == token))
user = users.get(User.userid == userid) if not tmptoken:
usertokens = list(user['tokens']) tokens.insert({'userid':userid, 'token':token, 'expiration':"{}".format(datetime.now() + timedelta(seconds=token_validity_seconds))})
if not token in usertokens:
usertokens.append(token)
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): def user_revoke_token(userid, token):
users = db_get().table('users') tokens = db_get().table('tokens')
User = Query() tmptoken = tokens.get((Query().userid == userid) & (Query().token == token))
user = users.get(User.userid == userid) if tmptoken:
usertokens = list(user['tokens']) tokens.remove(doc_ids=[tmptoken.doc_id])
if token in usertokens:
usertokens.remove(token)
users.upsert({'tokens': usertokens}, User.userid == userid) def user_add_authcode(userid, token, authcode):
tokens = db_get().table('tokens')
def user_add_authcode(userid, authcode): tmptoken = tokens.get((Query().userid == userid) & (Query().token == token))
users = db_get().table('users') if tmptoken:
User = Query() tokens.upsert({'authcode': authcode}, ((Query().userid == userid) & (Query().token == token)))
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_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): class VacBotDevice(object):
def __init__( def __init__(
@ -228,9 +236,25 @@ class VacBotClient(object):
def check_authcode(uid, authcode): def check_authcode(uid, authcode):
users = bumper_users_var.get() bumperlog.debug("Checking for authcode: {}".format(authcode))
for user in users: tokens = db_get().table('tokens')
if uid == "fuid_{}".format(user.userid) and authcode in user.authcodes: 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 True
return False return False

View file

@ -185,50 +185,12 @@ class ConfServer:
if ( if (
not user_devid == "" not user_devid == ""
): # Performing basic "auth" using devid, super insecure ): # Performing basic "auth" using devid, super insecure
users = bumper.db_get().table('users').all() user = bumper.user_by_deviceid(user_devid)
for user in users:
if user_devid in user['devices']:
if "checkLogin" in request.path: if "checkLogin" in request.path:
if request.query[ self.check_token(countrycode, user, request.query["accessToken"])
"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)
else: 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 #Deactivate old tokens and authcodes
for token in user['tokens']: bumper.user_revoke_expired_tokens(user['userid'])
bumper.user_revoke_token(user['userid'], token)
for authcode in user['authcodes']:
bumper.user_revoke_authcode(user['userid'], authcode)
body = { body = {
"code": bumper.RETURN_API_SUCCESS, "code": bumper.RETURN_API_SUCCESS,
@ -261,14 +223,44 @@ class ConfServer:
except Exception as e: except Exception as e:
confserverlog.exception("{}".format(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): def generate_token(self, user):
tmpaccesstoken = uuid.uuid4().hex tmpaccesstoken = uuid.uuid4().hex
bumper.user_add_token(user['userid'],tmpaccesstoken) bumper.user_add_token(user['userid'],tmpaccesstoken)
return tmpaccesstoken return tmpaccesstoken
def generate_authcode(self, countrycode, user): def generate_authcode(self, user, countrycode, token):
tmpauthcode = "{}_{}".format(countrycode, uuid.uuid4().hex) tmpauthcode = "{}_{}".format(countrycode, uuid.uuid4().hex)
bumper.user_add_authcode(user['userid'], tmpauthcode) bumper.user_add_authcode(user['userid'], token, tmpauthcode)
return tmpauthcode return tmpauthcode
@ -276,11 +268,11 @@ class ConfServer:
try: try:
user_devid = devid user_devid = devid
countrycode = country countrycode = country
users = bumper.db_get().table('users').all() user = bumper.user_by_deviceid(user_devid)
bots = bumper.db_get().table('bots').all() bots = bumper.db_get().table('bots').all()
if len(users) > 0: #Default to user 0 if user: #Default to user 0
tmpuser = users[0] tmpuser = user
bumper.user_add_device(tmpuser['userid'], user_devid) bumper.user_add_device(tmpuser['userid'], user_devid)
else: else:
bumper.user_add("tmpuser") #Add a new user bumper.user_add("tmpuser") #Add a new user
@ -291,26 +283,13 @@ class ConfServer:
bumper.user_add_bot(tmpuser['userid'], bot['did']) bumper.user_add_bot(tmpuser['userid'], bot['did'])
if "checkLogin" in request.path: #If request was to check a token do so if "checkLogin" in request.path: #If request was to check a token do so
if request.query["accessToken"] in tmpuser['tokens']: checkToken = self.check_token(countrycode, user, request.query["accessToken"])
return { isGood = json.loads(checkToken.text)
"code": bumper.RETURN_API_SUCCESS, if isGood['code'] == "0000":
"data": { return isGood
"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()),
}
#Deactivate old tokens and authcodes #Deactivate old tokens and authcodes
for token in tmpuser['tokens']: bumper.user_revoke_expired_tokens(tmpuser['userid'])
bumper.user_revoke_token(tmpuser['userid'], token)
for authcode in tmpuser['authcodes']:
bumper.user_revoke_authcode(tmpuser['userid'], authcode)
body = { body = {
"code": bumper.RETURN_API_SUCCESS, "code": bumper.RETURN_API_SUCCESS,
@ -334,22 +313,13 @@ class ConfServer:
try: try:
user_devid = request.match_info.get("devid", "") user_devid = request.match_info.get("devid", "")
if not user_devid == "": if not user_devid == "":
user = bumper.user_by_deviceid(user_devid)
users = bumper.db_get().table('users').all() if user:
for user in users:
if user_devid in user['devices']:
if ( if (
request.query["uid"] == "fuid_{}".format(user['userid']) bumper.check_token(user['userid'], request.query["accessToken"])
and request.query["accessToken"] in user['tokens']
): ):
#Deactivate old tokens and authcodes #Deactivate old tokens and authcodes
for token in user['tokens']: bumper.user_revoke_token(user['userid'], request.query["accessToken"])
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)
body = { body = {
"code": bumper.RETURN_API_SUCCESS, "code": bumper.RETURN_API_SUCCESS,
@ -368,18 +338,20 @@ class ConfServer:
user_devid = request.match_info.get("devid", "") user_devid = request.match_info.get("devid", "")
if not user_devid == "": if not user_devid == "":
users = bumper.db_get().table('users').all() user = bumper.user_by_deviceid(user_devid)
if len(users) > 0: if user:
for user in users: token = bumper.user_get_token(user['userid'], request.query["accessToken"])
if ( if token:
user_devid in user['devices'] authcode = ""
and request.query["accessToken"] in user['tokens'] if not 'authcode' in token:
): authcode = self.generate_authcode(user, request.match_info.get("country", "us"), request.query["accessToken"])
else:
authcode = token['authcode']
body = { body = {
"code": bumper.RETURN_API_SUCCESS, "code": bumper.RETURN_API_SUCCESS,
"data": { "data": {
"authCode": self.generate_authcode(request.match_info.get("country", "us"), user), "authCode": authcode,
"ecovacsUid": request.query["uid"], "ecovacsUid": request.query["uid"],
}, },
"msg": "操作成功", "msg": "操作成功",
@ -560,13 +532,10 @@ class ConfServer:
} }
elif service == "EcoUpdate": elif service == "EcoUpdate":
body = {"result": "ok", "ip": "47.88.66.164", "port": 8005} body = {"result": "ok", "ip": "47.88.66.164", "port": 8005}
elif todo == "loginByItToken":
users = bumper.db_get().table('users').all() elif todo == "loginByItToken":
for user in users:
if ( if (
postbody["userId"] == "fuid_{}".format(user['userid']) bumper.check_authcode(postbody["userId"], postbody["token"])
and postbody["token"] in user['authcodes']
): ):
body = { body = {
"resource": postbody["resource"], "resource": postbody["resource"],