Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

oauth2 cloud login #205

Merged
merged 8 commits into from
Dec 29, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,148 changes: 1,115 additions & 33 deletions Cargo.lock

Large diffs are not rendered by default.

21 changes: 20 additions & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,23 @@ log = "^0.4.17"
cpython = { version = "0.7", features = ["extension-module"] }
flate2 = "1.0.24"
fluvio = { version = "0.15" }
fluvio-future = { version = "0.4.2", features = ["task", "io"] }
fluvio-future = { version = "0.4.2", features = ["task", "io", "native2_tls", "subscriber"] }

thiserror = "1.0.21"
fluvio-types = "0.4.0"
serde = "1.0.117"
tracing = "0.1.37"

url = "2.1.1"
dirs = "4.0.0"
http-types = "2.6.0"
tokio = { version = "1.3.0", default-features = false, features = ["macros"] }
async-h1 = "2.3.3"
async-std = "1.6.5"
serde_urlencoded = "0.7.1"
md-5 = "0.10.0"
hex = "0.4.2"
webbrowser = "0.7.1"
toml = "0.5.7"
serde_json = "1.0.59"
rpassword = "5.0.0"
3 changes: 3 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,9 @@ integration-tests: build-dev
macos-ci-tests: build-dev
cd macos-ci-tests && $(PYTHON) -m unittest

manual-tests: build-dev
cd manual-tests/ && $(PYTHON) -m unittest

ci-build: # This is for testing builds
CIBW_BUILD="cp311-manylinux_x86_64 cp311-manylinux_aarch64 cp311-macosx_x86_64 cp311-macosx_universal2 cp311-macosx_arm64" CIBW_SKIP="cp27-*" CIBW_BEFORE_ALL_LINUX="{package}/tools/cibw_before_all_linux.sh" $(PYTHON) -m cibuildwheel --platform linux --output-dir wheelhouse

Expand Down
13 changes: 13 additions & 0 deletions fluvio/cloud.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
from ._fluvio_python import Cloud

DEFAULT_REMOTE = "https://infinyon.cloud"


def login(
useOauth2=True,
remote=DEFAULT_REMOTE,
profile=None,
email=None,
password=None,
):
Cloud.login(useOauth2, remote, profile, email, password)
11 changes: 11 additions & 0 deletions manual-tests/test_cloud_login.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import unittest
from fluvio.cloud import login


class TestFluvioCloudLogin(unittest.TestCase):
def test_login(self):
login()
# Comment/uncomment these as needed.
#login(profile='test-profile')
#login(useOauth2=False, email='youremail@gmail.com', password='PUT_YOURPASSWORD_HERE')
#login(useOauth2=False)
5 changes: 2 additions & 3 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,12 @@

setup(
name='fluvio',
version="0.14.1-beta.0",
version="0.14.1-beta.1",
long_description=open('README.md').read(),
long_description_content_type='text/markdown',
author = "Fluvio Contributors",
description='Python client library for Fluvio',
python_requires='>=3.7',
python_requires='>=3.8',
url='https://www.fluvio.io/',
keywords=['fluvio', 'streaming', 'stream'],
license='APACHE',
Expand All @@ -30,7 +30,6 @@
# that you indicate you support Python 3. These classifiers are *not*
# checked by 'pip install'. See instead 'python_requires' below.
'Programming Language :: Python :: 3',
'Programming Language :: Python :: 3.7',
'Programming Language :: Python :: 3.8',
'Programming Language :: Python :: 3.9',
'Programming Language :: Python :: 3.10',
Expand Down
69 changes: 69 additions & 0 deletions src/cloud/error.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
use fluvio::FluvioError;
use http_types::url::ParseError;
use http_types::StatusCode;
use std::io::Error as IoError;
use std::path::PathBuf;
use thiserror::Error;
use toml::de::Error as TomlError;

#[derive(Error, Debug)]
pub enum CloudLoginError {
#[error("Unable to access the default Fluvio directory")]
FluvioDirError,
/// Failed to parse request URL
#[error("Failed to parse URL: {url_string}")]
UrlError {
source: ParseError,
url_string: String,
},
#[error("Failed to make HTTP request to Infinyon cloud")]
HttpError(#[source] HttpError),
#[error("Failed to get token from Auth0")]
FailedToGetAuth0Token,
#[error("Failed to authenticate with Auth0: {0}")]
Auth0LoginError(String),
#[error("Account not found with email provided by third party service, please create account through WEB UI.")]
Auth0AccountNotFound,
#[error("Timeout while waiting for user authentication through third party service.")]
Auth0TimeoutError,
#[error("Unable to url encode the string")]
UrlEncode(#[from] serde_urlencoded::ser::Error),
#[error("Failed to save cloud credentials")]
UnableToSaveCredentials(#[source] IoError),
/// Failed to do some IO.
#[error(transparent)]
IoError(#[from] IoError),
#[error("Failed to create logins dir {path}")]
UnableToCreateLoginsDir { source: IoError, path: PathBuf },
#[error("Cluster for \"{0}\" does not exist")]
ClusterDoesNotExist(String),
#[error("Profile not available yet, please try again later.")]
ProfileNotAvailable,
#[error("Failed to parse login token from file")]
UnableToParseCredentials(#[from] TomlError),
#[error("Failed to load cloud credentials")]
UnableToLoadCredentials(#[source] IoError),
#[error("Failed to download cloud profile: Status code {0}: {1}")]
ProfileDownloadError(StatusCode, &'static str),
/// Failed to open Infinyon Cloud login file
#[error("Not logged in")]
NotLoggedIn,
#[error("Fluvio client error")]
FluvioError(#[from] FluvioError),
#[error("Failed to authenticate with username: {0}")]
AuthenticationError(String),
#[error("Account not active. Please validate email address.")]
AccountNotActive,
}

#[derive(Error, Debug)]
#[error("An HTTP error occurred: {inner}")]
pub struct HttpError {
inner: http_types::Error,
}

impl From<http_types::Error> for CloudLoginError {
fn from(inner: http_types::Error) -> Self {
Self::HttpError(HttpError { inner })
}
}
42 changes: 42 additions & 0 deletions src/cloud/http.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
use async_h1::client;
use http_types::{headers::USER_AGENT, Error, Request, Response, StatusCode};
use tracing::debug;

pub const FLUVIO_CLI_USER_AGENT: &str = "Fluvio Python Client";

pub async fn execute(req: Request) -> Result<Response, Error> {
debug!(?req, "executing request");
let mut req = req;
let host = req
.url()
.host_str()
.ok_or_else(|| Error::from_str(StatusCode::BadRequest, "missing hostname"))?
.to_string();

let is_https = req.url().scheme() == "https";

let addr = req
.url()
.socket_addrs(|| if is_https { Some(443) } else { Some(80) })?
.into_iter()
.next()
.ok_or_else(|| Error::from_str(StatusCode::BadRequest, "missing valid address"))?;

let tcp_stream = fluvio_future::net::TcpStream::connect(addr).await?;

req.append_header(
USER_AGENT,
format!("{}/{}", FLUVIO_CLI_USER_AGENT, env!("CARGO_PKG_VERSION")),
);

let result = if is_https {
let tls_connector = fluvio_future::native_tls::TlsConnector::default();
let tls_stream = tls_connector.connect(host, tcp_stream).await?;
client::connect(tls_stream, req).await
} else {
client::connect(tcp_stream, req).await
};

debug!(?result, "http result");
result
}
Loading