Skip to content

Commit

Permalink
refactor: cache FxA OAuth client (#1212)
Browse files Browse the repository at this point in the history
Closes #1209
  • Loading branch information
ethowitz authored Feb 6, 2022
1 parent eac6b55 commit 04b2437
Show file tree
Hide file tree
Showing 3 changed files with 44 additions and 24 deletions.
14 changes: 8 additions & 6 deletions src/tokenserver/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,15 +44,17 @@ impl ServerState {
let oauth_verifier = Box::new(TestModeOAuthVerifier);

#[cfg(not(feature = "tokenserver_test_mode"))]
let oauth_verifier = Box::new(OAuthVerifier {
fxa_oauth_server_url: settings.fxa_oauth_server_url.clone(),
});
let oauth_verifier = Box::new(
OAuthVerifier::new(settings.fxa_oauth_server_url.as_deref())
.expect("failed to create Tokenserver OAuth verifier"),
);

oauth_verifier
} else {
Box::new(OAuthVerifier {
fxa_oauth_server_url: settings.fxa_oauth_server_url.clone(),
})
Box::new(
OAuthVerifier::new(settings.fxa_oauth_server_url.as_deref())
.expect("failed to create Tokenserver OAuth verifier"),
)
};
let use_test_transactions = false;

Expand Down
36 changes: 26 additions & 10 deletions src/tokenserver/support.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use actix_web::Error;
use pyo3::prelude::{IntoPy, PyAny, PyErr, PyModule, PyObject, Python};
use pyo3::prelude::{IntoPy, Py, PyAny, PyErr, PyModule, PyObject, Python};
use pyo3::types::{IntoPyDict, PyString};
use serde::{Deserialize, Serialize};

Expand Down Expand Up @@ -100,27 +100,43 @@ impl Clone for Box<dyn VerifyToken> {
#[derive(Clone)]
/// An adapter to the PyFxA Python library.
pub struct OAuthVerifier {
pub fxa_oauth_server_url: Option<String>,
inner: Py<PyAny>,
}

impl OAuthVerifier {
const FILENAME: &'static str = "verify.py";

pub fn new(fxa_oauth_server_url: Option<&str>) -> Result<Self, Error> {
let inner: Py<PyAny> = Python::with_gil::<_, Result<Py<PyAny>, PyErr>>(|py| {
let code = include_str!("verify.py");
let module = PyModule::from_code(py, code, Self::FILENAME, Self::FILENAME)?;
let kwargs = fxa_oauth_server_url.map(|url| [("server_url", url)].into_py_dict(py));
let object: Py<PyAny> = module
.getattr("FxaOAuthClient")?
.call((), kwargs)
.map_err(|e| {
e.print_and_set_sys_last_vars(py);
e
})?
.into();

Ok(object)
})
.map_err(pyerr_to_actix_error)?;

Ok(Self { inner })
}
}

impl VerifyToken for OAuthVerifier {
/// Verifies an OAuth token. Returns `TokenData` for valid tokens and an `Error` for invalid
/// tokens.
fn verify_token(&self, token: &str) -> Result<TokenData, TokenserverError> {
let maybe_token_data_string = Python::with_gil(|py| {
let code = include_str!("verify.py");
let module = PyModule::from_code(py, code, Self::FILENAME, Self::FILENAME)?;
let kwargs = self
.fxa_oauth_server_url
.clone()
.map(|url| [("server_url", url)].into_py_dict(py));
let result: &PyAny = module
let client = self.inner.as_ref(py);
let result: &PyAny = client
.getattr("verify_token")?
.call((token,), kwargs)
.call((token,), None)
.map_err(|e| {
e.print_and_set_sys_last_vars(py);
e
Expand Down
18 changes: 10 additions & 8 deletions src/tokenserver/verify.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,13 +5,15 @@
DEFAULT_OAUTH_SCOPE = 'https://identity.mozilla.com/apps/oldsync'


def verify_token(token, server_url=None):
client = Client(server_url=server_url)
class FxaOAuthClient:
def __init__(self, server_url=None):
self._client = Client(server_url=server_url)

try:
token_data = client.verify_token(token, DEFAULT_OAUTH_SCOPE)
def verify_token(self, token):
try:
token_data = self._client.verify_token(token, DEFAULT_OAUTH_SCOPE)

# Serialize the data to make it easier to parse in Rust
return json.dumps(token_data)
except (ClientError, TrustError):
return None
# Serialize the data to make it easier to parse in Rust
return json.dumps(token_data)
except (ClientError, TrustError):
return None

0 comments on commit 04b2437

Please sign in to comment.