Beispiel #1
0
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)
Beispiel #2
0
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)
Beispiel #3
0
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)
Beispiel #4
0
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"])
Beispiel #5
0
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"])
Beispiel #6
0
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"])
Beispiel #7
0
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
Beispiel #8
0
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
Beispiel #9
0
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"])
Beispiel #10
0
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')