def _test_address(data): import netaddr from octoprint.util.net import get_lan_ranges, sanitize_address remote_addr = data.get("address") if not remote_addr: remote_addr = get_remote_address(request) remote_addr = sanitize_address(remote_addr) ip = netaddr.IPAddress(remote_addr) lan_subnets = get_lan_ranges() detected_subnet = None for subnet in lan_subnets: if ip in subnet: detected_subnet = subnet break result = { "is_lan_address": detected_subnet is not None, "address": remote_addr, } if detected_subnet is not None: result["subnet"] = str(detected_subnet) return jsonify(**result)
def getSessionKey(): logger.warn( "Client {} accessed the apps API which has been deprecated since 1.3.11 and will be removed in " "1.4.0. Clients should use the Application Keys Plugin workflow instead" .format(get_remote_address(request))) unverified_key, valid_until = octoprint.server.appSessionManager.create() return jsonify(unverifiedKey=unverified_key, validUntil=valid_until)
def login(): data = request.get_json() if not data: data = request.values if octoprint.server.userManager.enabled and "user" in data and "pass" in data: username = data["user"] password = data["pass"] if "remember" in data and data["remember"] in valid_boolean_trues: remember = True else: remember = False if "usersession.id" in session: _logout(current_user) user = octoprint.server.userManager.find_user(username) if user is not None: if octoprint.server.userManager.check_password(username, password): if not user.is_active: return make_response( ("Your account is deactivated", 403, [])) if octoprint.server.userManager.enabled: user = octoprint.server.userManager.login_user(user) session["usersession.id"] = user.session g.user = user login_user(user, remember=remember) identity_changed.send(current_app._get_current_object(), identity=Identity(user.get_id())) remote_addr = get_remote_address(request) logging.getLogger(__name__).info( "Actively logging in user {} from {}".format( user.get_id(), remote_addr)) response = user.as_dict() response["_is_external_client"] = s().getBoolean(["server", "ipCheck", "enabled"]) \ and not util_net.is_lan_address(remote_addr, additional_private=s().get(["server", "ipCheck", "trustedSubnets"])) r = make_response(jsonify(response)) r.delete_cookie("active_logout") eventManager().fire(Events.USER_LOGGED_IN, payload=dict(username=user.get_id())) return r return make_response(("User unknown or password incorrect", 403, [])) elif "passive" in data: return passive_login() return make_response( "Neither user and pass attributes nor passive flag present", 400)
def performSystemAction(): logging.getLogger(__name__).warn( "Deprecated API call to /api/system made by {}, should be migrated to use /system/commands/custom/<action>" .format(get_remote_address(request))) data = request.values if hasattr(request, "json") and request.json: data = request.json if not "action" in data: return make_response("action to perform is not defined", 400) return executeSystemCommand("custom", data["action"])
def performSystemAction(): logging.getLogger(__name__).warning( "Deprecated API call to /api/system made by {}, should be migrated to use /system/commands/custom/<action>" .format(get_remote_address(request))) data = request.get_json(silent=True) if data is None: data = request.values if "action" not in data: abort(400, description="action is missing") return executeSystemCommand("custom", data["action"])
def performSystemAction(): logging.getLogger(__name__).warning( "Deprecated API call to /api/system made by {}, should be migrated to use /system/commands/custom/<action>" .format(get_remote_address(request))) data = request.get_json(silent=True) if data is None: data = request.values if "action" not in data: return make_response("action to perform is not defined", 400) return executeSystemCommand("custom", data["action"])
def login(): data = request.values if hasattr(request, "json") and request.json: data = request.json if octoprint.server.userManager.enabled and "user" in data and "pass" in data: username = data["user"] password = data["pass"] if "remember" in data and data["remember"] in valid_boolean_trues: remember = True else: remember = False if "usersession.id" in session: _logout(current_user) user = octoprint.server.userManager.findUser(username) if user is not None: if octoprint.server.userManager.checkPassword(username, password): if not user.is_active(): return make_response( ("Your account is deactivated", 403, [])) if octoprint.server.userManager.enabled: user = octoprint.server.userManager.login_user(user) session["usersession.id"] = user.session g.user = user login_user(user, remember=remember) identity_changed.send(current_app._get_current_object(), identity=Identity(user.get_id())) remote_addr = get_remote_address(request) logging.getLogger(__name__).info( "Actively logging in user {} from {}".format( user.get_id(), remote_addr)) response = user.asDict() response["_is_external_client"] = s().getBoolean(["server", "ipCheck", "enabled"]) \ and not util_net.is_lan_address(remote_addr, additional_private=s().get(["server", "ipCheck", "trustedSubnets"])) return jsonify(response) return make_response(("User unknown or password incorrect", 401, [])) elif "passive" in data: return passive_login() return NO_CONTENT
def login(): data = request.values if hasattr(request, "json") and request.json: data = request.json if octoprint.server.userManager.enabled and "user" in data and "pass" in data: username = data["user"] password = data["pass"] if "remember" in data and data["remember"] in valid_boolean_trues: remember = True else: remember = False if "usersession.id" in session: _logout(current_user) user = octoprint.server.userManager.findUser(username) if user is not None: if octoprint.server.userManager.checkPassword(username, password): if not user.is_active(): return make_response(("Your account is deactivated", 403, [])) if octoprint.server.userManager.enabled: user = octoprint.server.userManager.login_user(user) session["usersession.id"] = user.session g.user = user login_user(user, remember=remember) identity_changed.send(current_app._get_current_object(), identity=Identity(user.get_id())) remote_addr = get_remote_address(request) logging.getLogger(__name__).info("Actively logging in user {} from {}".format(user.get_id(), remote_addr)) response = user.asDict() response["_is_external_client"] = s().getBoolean(["server", "ipCheck", "enabled"]) \ and not util_net.is_lan_address(remote_addr, additional_private=s().get(["server", "ipCheck", "trustedSubnets"])) return jsonify(response) return make_response(("User unknown or password incorrect", 401, [])) elif "passive" in data: return passive_login() return NO_CONTENT
def performSystemAction(): logging.getLogger(__name__).warn("Deprecated API call to /api/system made by {}, should be migrated to use /system/commands/custom/<action>".format(get_remote_address(request))) data = request.values if hasattr(request, "json") and request.json: data = request.json if not "action" in data: return make_response("action to perform is not defined", 400) return executeSystemCommand("custom", data["action"])
def verifySessionKey(): logger.warn( "Client {} accessed the apps API which has been deprecated since 1.3.11 and will be removed in " "1.4.0. Clients should use the Application Keys Plugin workflow instead" .format(get_remote_address(request))) if not "application/json" in request.headers["Content-Type"]: return None, None, make_response("Expected content-type JSON", 400) data = request.get_json() if data is None: return make_response("Malformed JSON body in request", 400) for key in ("appid", "key", "_sig"): if not key in data: return make_response("Missing argument: {key}".format(key=key), 400) appid = str(data["appid"]) if not "appversion" in data: appversion = "any" else: appversion = str(data["appversion"]) key = str(data["key"]) # calculate message that was signed message = "{appid}:{appversion}:{key}".format(**locals()) # decode signature import base64 signature = data["_sig"] signature = base64.decodestring("\n".join( [signature[x:x + 64] for x in range(0, len(signature), 64)])) # fetch and validate app information lookup_key = appid + ":" + appversion apps = _get_registered_apps() if not lookup_key in apps or not apps[lookup_key][ "enabled"] or not "pubkey" in apps[lookup_key]: octoprint.server.appSessionManager.remove(key) return make_response( "Invalid app: {lookup_key}".format(lookup_key=lookup_key), 401) pubkey_string = apps[lookup_key]["pubkey"] pubkey_string = "\n".join( [pubkey_string[x:x + 64] for x in range(0, len(pubkey_string), 64)]) try: pubkey = rsa.PublicKey.load_pkcs1("-----BEGIN RSA PUBLIC KEY-----\n" + pubkey_string + "\n-----END RSA PUBLIC KEY-----\n") except Exception: octoprint.server.appSessionManager.remove(key) return make_response("Invalid pubkey stored in server", 500) # verify signature try: rsa.verify(message, signature, pubkey) except rsa.VerificationError: octoprint.server.appSessionManager.remove(key) return make_response("Invalid signature", 401) # generate new session key and return it result = octoprint.server.appSessionManager.verify(key) if not result: return make_response("Invalid key or already verified", 401) verified_key, valid_until = result return jsonify(key=verified_key, validUntil=valid_until)
def api_auth_callback(self): s = self._settings d = settings_defaults() code = flask.request.args.get("code") token_endpoint = s.get(['token_endpoint']) client_id = s.get(['client_id']) client_secret = s.get(['client_secret']) userinfo_endpoint = s.get(['userinfo_endpoint']) orguser_endpoint = s.get(['orguser_endpoint']) organization = s.get(['organization']) username_key = s.get(['username_key']) self._logger.info('token_endpoint: ' + str(token_endpoint)) client = WebApplicationClient(client_id) token_url, headers, body = client.prepare_token_request( token_endpoint, # authorization_response=flask.request.url, # redirect_url=flask.request.base_url, code=code ) headers['Accept'] = 'application/json' token_response = requests.post( token_url, headers=headers, data=body, auth=(client_id, client_secret), ) client.parse_request_body_response(json.dumps(token_response.json())) uri, headers, body = client.add_token(userinfo_endpoint) headers['Accept'] = 'application/json' userinfo_response = requests.get(uri, headers=headers, data=body) userinfo = userinfo_response.json() username = userinfo[username_key] uri, headers, body = client.add_token(orguser_endpoint.format(organization, username)) headers['Accept'] = 'application/json' orguser_response = requests.get(uri, headers=headers, data=body) if orguser_response.status_code == 204: # User is part of the specified organization, find user or create it if it doesn't exist user = self._user_manager.login_user(OAuth2PGCUser(username)) flask.session["usersession.id"] = user.session flask.g.user = user self._logger.info("authenticated: " + str(user.is_authenticated)) self._logger.info("user: "******"Actively logging in user {} from {}".format(user.get_id(), remote_addr)) r = flask.redirect('/') r.delete_cookie("active_logout") eventManager().fire(Events.USER_LOGGED_IN, payload=dict(username=user.get_id())) return r return flask.redirect('/?error=unauthorized')