def kf_authenticate_simple_refrush(): if request.is_json: data = request.json Can = False AccessToken = data.get('accessToken') ClientToken = data.get("clientToken", str( uuid.uuid4()).replace("-", "")) IReturn = {} if 'clientToken' in data: OldToken = Token.gettoken_strict( AccessToken, data.get("clientToken")) else: OldToken = Token.gettoken_strict(AccessToken) if not OldToken: raise Exceptions.InvalidToken() if int(time.time()) >= OldToken.get("createTime") + (config.TokenTime.RefrushTime * config.TokenTime.TimeRange): raise Exceptions.InvalidToken() NewAccessToken = str(uuid.uuid4()).replace('-', '') cache_token.set(".".join(["token", NewAccessToken]), { "clientToken": OldToken.get('clientToken'), "bind": "", "user": OldToken.get("user"), "createTime": int(time.time()) }, ttl=config.TokenTime.RefrushTime * config.TokenTime.TimeRange) cache_token.delete(".".join(["token", AccessToken])) IReturn['accessToken'] = NewAccessToken IReturn['clientToken'] = OldToken.get('clientToken') return Response(json.dumps(IReturn), mimetype='application/json; charset=utf-8')
def kf_group_interfaces_create(): if request.is_json: data = request.json name = data.get("name") joinway = data.get("joinway", "public_join") if joinway not in ["public_join", "public_join_review", "private"]: raise Exceptions.InvalidToken() if not re.match(r"[a-zA-Z0-9\u4E00-\u9FA5_-]{4,16}$", name): raise Exceptions.InvalidToken() if model.group.select().where(model.group.name == name): raise Exceptions.InvalidToken() accessToken = data.get("accessToken") clientToken = data.get("clientToken") if not accessToken: raise Exceptions.InvalidToken() if Token.is_validate_strict(accessToken, clientToken): raise Exceptions.InvalidToken() token = Token.gettoken_strict(accessToken, clientToken) user_uuid = model.getuser_uuid(token.get("user")).uuid new_group = model.group(name=name, creater=user_uuid, manager=user_uuid, create_date=datetime.datetime.now(), joinway=joinway) new_group.save() new_manager = model.member( user=user_uuid, group=new_group.id, permission="super_manager") return Response(json.dumps({ "groupId": new_group.uuid, "timestamp": new_group.create_date.timestamp() }), mimetype='application/json; charset=utf-8')
def auto_verify(request): data = request.json accessToken = data.get("accessToken") clientToken = data.get("clientToken") if not accessToken: raise Exceptions.InvalidToken() if Token.is_validate_strict(accessToken, clientToken): raise Exceptions.InvalidToken() return Token.gettoken_strict(accessToken, clientToken)
def group_joinserver(group_id): group.get_group(group_id) token = {} if request.is_json: data = request.json AccessToken = data['accessToken'] ClientToken = data.get("clientToken") TokenValidate = Token.is_validate_strict(AccessToken, ClientToken) if not TokenValidate: # Token有效 # uuid = token.bind token = Token.gettoken_strict(AccessToken, ClientToken) if not token: raise Exceptions.InvalidToken() group.token_is_group(token, group_id) if token.get('bind'): result = model.getprofile_uuid(token.get('bind')) if not result: return Response(status=404) else: raise Exceptions.InvalidToken() player = model.getprofile(result.get().name).get() playeruuid = player.profile_id.replace("-", "") if data['selectedProfile'] == playeruuid: cache_joinserver.set(data['serverId'], { "accessToken": AccessToken, "selectedProfile": data['selectedProfile'], "remoteIP": request.remote_addr }, ttl=config.ServerIDOutTime) model.log_yggdrasil( operational="sessionserver.session.minecraft.join", user=token.get("user"), IP=request.remote_addr, time=datetime.datetime.now()).save() return Response(status=204) else: model.log_yggdrasil( operational="sessionserver.session.minecraft.join", user=token.get("user"), IP=request.remote_addr, time=datetime.datetime.now(), successful=False).save() raise Exceptions.InvalidToken() else: model.log_yggdrasil( operational="sessionserver.session.minecraft.join", IP=request.remote_addr, time=datetime.datetime.now(), successful=False).save() raise Exceptions.InvalidToken()
def kf_validate(): if request.is_json: data = request.json AccessToken = data['accessToken'] ClientToken = data.get("clientToken") result = Token.gettoken_strict(AccessToken, ClientToken) if not result: raise Exceptions.InvalidToken() else: if Token.is_validate_strict(AccessToken, ClientToken): raise Exceptions.InvalidToken() else: return Response(status=204)
def group_invalidate(group_id): group.get_group(group_id) if request.is_json: data = request.json AccessToken = data['accessToken'] ClientToken = data.get("clientToken") result = Token.gettoken(AccessToken, ClientToken) if result: group.token_is_group(result, group_id) model.log_yggdrasil(operational="authserver.invalidate", user=result.get("user"), otherargs=json.dumps( {"clientToken": data.get("clientToken")}), IP=request.remote_addr, time=datetime.datetime.now()).save() cache_token.delete(AccessToken) else: model.log_yggdrasil(operational="authserver.invalidate", otherargs=json.dumps( {"clientToken": data.get("clientToken")}), IP=request.remote_addr, time=datetime.datetime.now(), successful=False).save() if ClientToken: raise Exceptions.InvalidToken() #User = model.user.get(email=result.email) '''if User.permission == 0: return Response(simplejson.dumps({ 'error' : "ForbiddenOperationException", 'errorMessage' : "You have been banned by the administrator, please contact the administrator for help" }), status=403, mimetype='application/json; charset=utf-8')''' return Response(status=204)
def fairy_upload(): data = request.data header = data[:(32 + 64)].decode() Cached = cache_uploadtoken.get(".".join(["fairy", "security", "checkinfo", header[:32]])) if not Cached: raise Exceptions.InvalidToken() imagehex = header[32:] if model.gettexture_hash(imagehex): return Response(json.dumps({ "error": "ForbiddenOperationException", "errorMessage": "Quantum repeatability does not hold here." }), status=403, mimetype='application/json; charset=utf-8') hexed = hashlib.sha256(data[(32 + 64):]).hexdigest() if Cached.get("sha256") != hexed: return Response(json.dumps({ "error": "ForbiddenOperationException", "errorMessage": "Hash value does not match." }), status=403, mimetype='application/json; charset=utf-8') size = Cached.get("size") height = size.get("height") width = size.get("width") if len(data) - (32 + 64 + 8) != ((height * width) * 4): return Response(json.dumps({"error": "ForbiddenOperationException","errorMessage": "Parsing does not provide sufficient amount of bytes"}), status=403, mimetype='application/json; charset=utf-8') if (len(data) - (32 + 64)) % 4 != 0: return Response(json.dumps({"error": "ForbiddenOperationException","errorMessage": "No correct encoded image."}), status=403, mimetype='application/json; charset=utf-8') if not ((height % 32 == 0) or (height % 17 == 0)) and ((width % 64 == 0) or (width % 22 == 0)): return Response(json.dumps({"error": "ForbiddenOperationException","errorMessage": "No correct encoded image."}), status=403, mimetype='application/json; charset=utf-8') if height % 17 == 0: height = int(width / 17) * 32 if width % 22 == 0: width = int(width / 22) * 32 image = Image.new('RGBA', (width, height), (255, 255, 255, 255)) draw = ImageDraw.Draw(image) dots = utils.chunk(list(data[(32 + 64):]), 4)[2:] chunks = utils.chunk(dots, height) for x in range(len(chunks)): for y in range(len(chunks[x])): draw.point((x, y), fill=(chunks[x][y][1], chunks[x][y][2], chunks[x][y][3], chunks[x][y][0])) image.save("".join(["./data/texture/", imagehex, ".png"]), "PNG") skintype = Cached.get("type") if skintype == "SKIN" and height % 64 == 0: skinmodel = ["STEVE", "ALEX"][sv3d.isSilmSkin(image)] texture = model.textures( userid=Token.gettoken_strict(Cached.get("accessToken")).get("user"), photoname=Cached.get("name"), height=height, width=width, model=skinmodel, type=skintype, hash=hexed ) texture.save() return Response(model.kf_format_textures(texture), mimetype='application/json; charset=utf-8')
def kf_profile_cape_change(profileid): if request.is_json: data = request.json result = model.getprofile_id(profileid) if not result: return Response(json.dumps({ "error": "ForbiddenOperationException", "errorMessage": "no such profile." }), status=403, mimetype='application/json; charset=utf-8') result = result.get() accessToken = data.get("accessToken") if not accessToken: return Response(json.dumps({ "error": "ForbiddenOperationException", "errorMessage": "no such profile." }), status=403, mimetype='application/json; charset=utf-8') if Token.is_validate_strict(accessToken): raise Exceptions.InvalidToken() user = Token.getuser_byaccessToken(accessToken) if model.isBanned(user): raise Exceptions.InvalidToken() texture = model.gettexture(data.get("texture")) if not texture: raise Exceptions.InvalidToken() if texture.isPrivate: if texture.userid != user.uuid: raise Exceptions.InvalidToken() if texture.type != "cape": raise Exceptions.InvalidToken() if result.cape == texture.textureid: return Response(status=204) result.cape = texture.textureid result.change_time = datetime.datetime.now() result.save() return Response(status=204)
def fairy_checkinfo(): if request.is_json: data = request.json sha256 = data.get("sha256", 0) size = data.get("size", 0) name = data.get("name", 0) accessToken = data.get("accessToken", 0) type = data.get("type", 0) if False in [size, sha256, accessToken, name, type]: return Response(json.dumps({ "error": "ForbiddenOperationException", "errorMessage": "Invalid Data" })) else: if not Token.gettoken_strict(accessToken): raise Exceptions.InvalidToken() if Token.is_validate_strict(accessToken): raise Exceptions.InvalidToken() if model.gettexture_photoname(name): return Response(json.dumps({ "error": "ForbiddenOperationException", "errorMessage": "Invalid Data." })) UploadToken = str(uuid.uuid4()).replace("-", "") if False in [ SizeConfig.height[0] < size.get("height") < SizeConfig.height[1], SizeConfig.width[0] < size.get("width") < SizeConfig.width[1] ]: return Response(json.dumps({ "error": "PictureDecodeError", "errorMessage": "Invalid Size." }), status=403, mimetype='application/json; charset=utf-8') if type not in ["skin", "cape"]: raise Exceptions.InvalidToken() cache_uploadtoken.set(".".join(["fairy", "security", "checkinfo", UploadToken]), { "sha256": sha256, "size": size, "accessToken": accessToken, "name": name, "type": type }, ttl=30) # size: # height # width return Response(json.dumps({"uploadToken": UploadToken}))
def kf_login_verify(): if request.is_json: data = request.json Data = cache_secureauth.get(data.get("authId")) if not Data: return Response(status=403) else: user_result = model.getuser(Data['username']) if user_result: AuthRequest = password.crypt( user_result.password, Data['HashKey']) print(AuthRequest) if AuthRequest == data['Password']: if Data.get("inorderto") == "signin": notDoubleProfile = False Profileresult = model.getprofile_createby( user_result.uuid) if len(Profileresult) == 1: notDoubleProfile = True SelectedProfile = model.format_profile( Profileresult.get()) AccessToken = str(uuid.uuid4()).replace("-", "") ClientToken = str(uuid.uuid4()).replace("-", "") cache_token.set(AccessToken, { "clientToken": ClientToken, "bind": Profileresult.get().uuid if notDoubleProfile else None, "user": user_result.uuid, "group": "global", "createTime": int(time.time()) }, ttl=config.TokenTime.RefrushTime * config.TokenTime.TimeRange) IReturn = { "accessToken": AccessToken, "clientToken": ClientToken, } cache_secureauth.delete(data['authId']) if data.get("requestUser"): IReturn['metadata'] = { "user": { "userId": user_result.uuid } } return Response(json.dumps(IReturn), mimetype='application/json; charset=utf-8') if Data.get("inorderto") == "signout": result = Token.getalltoken(user_result) if result: for i in result: cache_secureauth.delete(i) return Response(status=204) else: cache_secureauth.delete(data['authId']) raise Exceptions.InvalidCredentials() else: cache_secureauth.delete(data['authId']) return Response(status=403)
def group_PlayerHasJoined(group_id): group.get_group(group_id) args = request.args ServerID = args['serverId'] PlayerName = args['username'] RemoteIP = args['ip'] if 'ip' in args else None Successful = False Data = cache_joinserver.get(ServerID) if not Data: model.log_yggdrasil( operational="sessionserver.session.minecraft.hasJoined", IP=request.remote_addr, time=datetime.datetime.now(), successful=False).save() return Response(status=204) TokenInfo = Token.gettoken(Data['accessToken']) group.token_is_group(TokenInfo, group_id) ProfileInfo = model.getprofile_uuid_name(TokenInfo.get("bind"), name=PlayerName) if not TokenInfo or not ProfileInfo: model.log_yggdrasil( operational="sessionserver.session.minecraft.hasJoined", IP=request.remote_addr, time=datetime.datetime.now(), successful=False).save() return Response(status=204) ProfileInfo = ProfileInfo.get() Successful = PlayerName == ProfileInfo.name and [ True, RemoteIP == Data['remoteIP'] ][bool(RemoteIP)] if Successful: model.log_yggdrasil( operational="sessionserver.session.minecraft.hasJoined", user=TokenInfo.get("user"), IP=request.remote_addr, time=datetime.datetime.now()).save() result = json.dumps( model.format_profile(ProfileInfo, Properties=True, unsigned=False, BetterData=True)) return Response(result, mimetype="application/json; charset=utf-8") else: model.log_yggdrasil( operational="sessionserver.session.minecraft.hasJoined", user=TokenInfo.get("user"), IP=request.remote_addr, time=datetime.datetime.now(), successful=False).save() return Response(status=204) return Response(status=204)
def group_validate(group_id): group.get_group(group_id) if request.is_json: data = request.json AccessToken = data['accessToken'] ClientToken = data.get("clientToken") result = Token.gettoken_strict(AccessToken, ClientToken) if not result: model.log_yggdrasil(operational="authserver.validate", otherargs=json.dumps( {"clientToken": data.get("clientToken")}), IP=request.remote_addr, time=datetime.datetime.now(), successful=False).save() raise Exceptions.InvalidToken() else: group.token_is_group(result, group_id) if Token.is_validate_strict(AccessToken, ClientToken): model.log_yggdrasil(user=result.get("user"), operational="authserver.validate", otherargs=json.dumps({ "clientToken": data.get("clientToken") }), IP=request.remote_addr, time=datetime.datetime.now(), successful=False).save() raise Exceptions.InvalidToken() else: model.log_yggdrasil( user=result.get("user"), operational="authserver.validate", otherargs=json.dumps( {"clientToken": data.get("clientToken")}), IP=request.remote_addr, time=datetime.datetime.now(), ).save() return Response(status=204)
def group_signout(group_id): group.get_group(group_id) if request.is_json: data = request.json email = data['username'] passwd = data['password'] result = model.getuser(email) if not result: model.log_yggdrasil(operational="authserver.signout", IP=request.remote_addr, time=datetime.datetime.now(), successful=False).save() raise Exceptions.InvalidCredentials() else: group.get_member(result, group_id) '''if result.permission == 0: return Response(json.dumps({ 'error' : "ForbiddenOperationException", 'errorMessage' : "Invalid credentials. Invalid username or password." }), status=403, mimetype='application/json; charset=utf-8')''' if not cache_limit.get(".".join(['lock', result.email])): cache_limit.set(".".join(['lock', result.email]), "LOCKED", ttl=config.AuthLimit) else: raise Exceptions.InvalidCredentials() if password.crypt(passwd, salt=result.passwordsalt) == result.password: Token_result = Token.getalltoken(result) if Token_result: for i in Token_result: if i.get("group") == group_id: cache_token.delete(i) model.log_yggdrasil(operational="authserver.signout", user=result.uuid, IP=request.remote_addr, time=datetime.datetime.now()).save() return Response(status=204) else: model.log_yggdrasil(operational="authserver.signout", user=result.uuid, IP=request.remote_addr, time=datetime.datetime.now(), successful=False).save() raise Exceptions.InvalidCredentials()
def kf_invalidate(): if request.is_json: data = request.json AccessToken = data['accessToken'] ClientToken = data.get("clientToken") result = Token.gettoken(AccessToken, ClientToken) if result: cache_token.delete(".".join(['token', AccessToken])) else: if ClientToken: raise Exceptions.InvalidToken() #User = model.user.get(email=result.email) '''if User.permission == 0: return Response(simplejson.dumps({ 'error' : "ForbiddenOperationException", 'errorMessage' : "You have been banned by the administrator, please contact the administrator for help" }), status=403, mimetype='application/json; charset=utf-8')''' return Response(status=204)
def group_refresh(group_id): group.get_group(group_id) if request.is_json: data = request.json Can = False AccessToken = data.get('accessToken') ClientToken = data.get("clientToken", str(uuid.uuid4()).replace("-", "")) IReturn = {} if 'clientToken' in data: OldToken = Token.gettoken_strict(AccessToken, data.get("clientToken")) else: OldToken = Token.gettoken_strict(AccessToken) if not OldToken: raise Exceptions.InvalidToken() group.token_is_group(OldToken, group_id) if int(time.time()) >= OldToken.get("createTime") + ( config.TokenTime.RefrushTime * config.TokenTime.TimeRange): model.log_yggdrasil(operational="authserver.refrush", user=OldToken.get("user"), otherargs=json.dumps( {"clientToken": data.get("clientToken")}), IP=request.remote_addr, time=datetime.datetime.now(), successful=False).save() raise Exceptions.InvalidToken() User = model.getuser_uuid(OldToken.get("user")) group.get_member(group_id, User.uuid) TokenSelected = OldToken.get("bind") if TokenSelected: TokenProfile = model.getprofile_uuid(TokenSelected).get() else: TokenProfile = {} if 'selectedProfile' in data: PostProfile = data['selectedProfile'] needuser = model.getprofile_id_name(PostProfile['id'], PostProfile['name']) if not needuser: # 验证客户端提供的角色信息 raise Exceptions.IllegalArgumentException() # 角色不存在. else: needuser = needuser.get() # 验证完毕,有该角色. if OldToken.get('bind'): # 如果令牌本来就绑定了角色 model.log_yggdrasil(operational="authserver.refrush", user=User.uuid, otherargs=json.dumps({ "clientToken": data.get("clientToken") }), IP=request.remote_addr, time=datetime.datetime.now(), successful=False).save() error = { 'error': 'IllegalArgumentException', 'errorMessage': "Access token already has a profile assigned." } return Response(json.dumps(error), status=400, mimetype='application/json; charset=utf-8') if needuser.createby != OldToken.get("user"): # 如果角色不属于用户 model.log_yggdrasil(operational="authserver.refrush", user=User.uuid, otherargs=json.dumps({ "clientToken": data.get("clientToken") }), IP=request.remote_addr, time=datetime.datetime.now(), successful=False).save() error = { 'error': "ForbiddenOperationException", 'errorMessage': "Attempting to bind a token to a role that does not belong to its corresponding user." } return Response(json.dumps(error), status=403, mimetype='application/json; charset=utf-8') TokenSelected = model.findprofilebyid(PostProfile['id']).uuid IReturn['selectedProfile'] = model.format_profile( model.findprofilebyid(PostProfile['id']), unsigned=True) Can = True NewAccessToken = str(uuid.uuid4()).replace('-', '') cache_token.set(NewAccessToken, { "clientToken": OldToken.get('clientToken'), "bind": TokenSelected, "user": OldToken.get("user"), "group": group_id, "createTime": int(time.time()) }, ttl=config.TokenTime.RefrushTime * config.TokenTime.TimeRange) cache_token.delete(AccessToken) IReturn['accessToken'] = NewAccessToken IReturn['clientToken'] = OldToken.get('clientToken') if TokenProfile and not Can: IReturn['selectedProfile'] = model.format_profile(TokenProfile, unsigned=True) if 'requestUser' in data: if data['requestUser']: IReturn['user'] = model.format_user(User) User.last_login = datetime.datetime.now() model.log_yggdrasil(operational="authserver.refrush", user=User.uuid, otherargs=json.dumps( {"clientToken": data.get("clientToken")}), IP=request.remote_addr, time=datetime.datetime.now()).save() return Response(json.dumps(IReturn), mimetype='application/json; charset=utf-8')