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

Perf and monitoring improvements to builder-api #775

Merged
merged 3 commits into from Nov 3, 2018
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.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

82 changes: 48 additions & 34 deletions components/builder-api/src/server/authorize.rs
Expand Up @@ -15,64 +15,68 @@
use actix_web::HttpRequest;
use hab_net::privilege::FeatureFlags;

use bldr_core::access_token::{BUILDER_ACCOUNT_ID, BUILDER_ACCOUNT_NAME};

use protocol::originsrv;

use db::models::account::*;
use db::models::origin::*;

use server::error::{Error, Result};
use server::AppState;

pub fn authorize_session(req: &HttpRequest<AppState>, origin_opt: Option<&str>) -> Result<u64> {
let account_id = {
pub fn authorize_session(
req: &HttpRequest<AppState>,
origin_opt: Option<&str>,
) -> Result<originsrv::Session> {
let session = {
let extensions = req.extensions();
match extensions.get::<originsrv::Session>() {
Some(session) => {
let flags = FeatureFlags::from_bits(session.get_flags()).unwrap(); // unwrap Ok
if flags.contains(FeatureFlags::BUILD_WORKER) {
return Ok(session.get_id());
return Ok(session.clone());
}
session.get_id()
session.clone()
}
None => return Err(Error::Authentication),
}
};

let conn = req.state().db.get_conn().map_err(Error::DbError)?;

if let Some(origin) = origin_opt {
match Origin::check_membership(origin, account_id, &*conn).map_err(Error::DieselError) {
Ok(is_member) if is_member => (),
_ => return Err(Error::Authorization),
}
}
let mut memcache = req.state().memcache.borrow_mut();

Ok(account_id)
}

// TODO - Merge into authorize_session when we are able to cache the name
pub fn get_session_user_name(req: &HttpRequest<AppState>, account_id: u64) -> String {
if account_id == BUILDER_ACCOUNT_ID {
return BUILDER_ACCOUNT_NAME.to_string();
}

let conn = match req.state().db.get_conn() {
Ok(conn) => conn,
Err(err) => {
warn!("Failed to get account, id={}, err={:?}", account_id, err);
return "".to_string();
match memcache.get_origin_member(origin, session.get_id()) {
Some(val) => {
trace!(
"Origin membership {} {} Cache Hit!",
origin,
session.get_id()
);
if val {
return Ok(session);
} else {
return Err(Error::Authorization);
}
}
None => trace!(
"Origin membership {} {} Cache Miss!",
origin,
session.get_id()
),
}
};

match Account::get_by_id(account_id, &*conn) {
Ok(account) => account.name.to_string(),
Err(err) => {
warn!("Failed to get account, id={}, err={:?}", account_id, err);
"".to_string()
match check_origin_member(req, origin, session.get_id()) {
Ok(is_member) => {
memcache.set_origin_member(origin, session.get_id(), is_member);

match is_member {
true => (),
false => return Err(Error::Authorization),
}
}
_ => return Err(Error::Authorization),
}
}

Ok(session)
}

pub fn check_origin_owner(
Expand All @@ -87,3 +91,13 @@ pub fn check_origin_owner(
Err(err) => Err(err),
}
}

pub fn check_origin_member(
req: &HttpRequest<AppState>,
origin: &str,
account_id: u64,
) -> Result<bool> {
let conn = req.state().db.get_conn().map_err(Error::DbError)?;

Origin::check_membership(origin, account_id, &*conn).map_err(Error::DieselError)
}
17 changes: 13 additions & 4 deletions components/builder-api/src/server/framework/middleware.rs
Expand Up @@ -21,6 +21,7 @@ use base64;
use protobuf;

use bldr_core;
use bldr_core::access_token::{BUILDER_ACCOUNT_ID, BUILDER_ACCOUNT_NAME};
use bldr_core::metrics::CounterMetric;
use hab_net::{ErrCode, NetError};
use oauth_client::types::OAuth2User;
Expand All @@ -32,7 +33,6 @@ use db::models::account::*;

use hab_net::privilege::FeatureFlags;
use server::error;
use server::resources::profile::do_get_access_tokens;
use server::services::metrics::Counter;
use server::AppState;

Expand Down Expand Up @@ -107,20 +107,23 @@ fn authenticate(req: &HttpRequest<AppState>, token: &str) -> error::Result<origi
}
// Pull the session out of the current token provided so we can validate
// it against the db's tokens
let session = bldr_core::access_token::validate_access_token(
let mut session = bldr_core::access_token::validate_access_token(
&req.state().config.api.key_path,
token,
).map_err(|_| NetError::new(ErrCode::BAD_TOKEN, "net:auth:bad-token"))?;

if session.get_id() == bldr_core::access_token::BUILDER_ACCOUNT_ID {
if session.get_id() == BUILDER_ACCOUNT_ID {
trace!("Builder token identified");
session.set_name(BUILDER_ACCOUNT_NAME.to_owned());
memcache.set_session(token, &session, None);
return Ok(session);
}

// If we can't find a token in the cache, we need to round-trip to the
// db to see if we have a valid session token.
match do_get_access_tokens(&req, session.get_id()) {
let conn = req.state().db.get_conn().map_err(error::Error::DbError)?;

match AccountToken::list(session.get_id(), &*conn).map_err(error::Error::DieselError) {
Ok(access_tokens) => {
assert!(access_tokens.len() <= 1); // Can only have max of 1 for now
match access_tokens.first() {
Expand All @@ -133,6 +136,12 @@ fn authenticate(req: &HttpRequest<AppState>, token: &str) -> error::Result<origi
"net:auth:revoked-token",
)));
}

let account = Account::get_by_id(session.get_id(), &*conn)
.map_err(error::Error::DieselError)?;
session.set_name(account.name);
session.set_email(account.email);

memcache.set_session(&new_token, &session, None);
return Ok(session);
}
Expand Down