// use super::{ // db::{self, UserId}, // errors::TideResultExt, // }; // use crate::Request; // use anyhow::{anyhow, Context}; // use rand::thread_rng; // use rpc::auth as zed_auth; // use scrypt::{ // password_hash::{PasswordHash, PasswordHasher, PasswordVerifier, SaltString}, // Scrypt, // }; // use std::convert::TryFrom; // use surf::StatusCode; // use tide::Error; // pub async fn process_auth_header(request: &Request) -> tide::Result { // let mut auth_header = request // .header("Authorization") // .ok_or_else(|| { // Error::new( // StatusCode::BadRequest, // anyhow!("missing authorization header"), // ) // })? // .last() // .as_str() // .split_whitespace(); // let user_id = UserId(auth_header.next().unwrap_or("").parse().map_err(|_| { // Error::new( // StatusCode::BadRequest, // anyhow!("missing user id in authorization header"), // ) // })?); // let access_token = auth_header.next().ok_or_else(|| { // Error::new( // StatusCode::BadRequest, // anyhow!("missing access token in authorization header"), // ) // })?; // let state = request.state().clone(); // let mut credentials_valid = false; // for password_hash in state.db.get_access_token_hashes(user_id).await? { // if verify_access_token(&access_token, &password_hash)? { // credentials_valid = true; // break; // } // } // if !credentials_valid { // Err(Error::new( // StatusCode::Unauthorized, // anyhow!("invalid credentials"), // ))?; // } // Ok(user_id) // } // const MAX_ACCESS_TOKENS_TO_STORE: usize = 8; // pub async fn create_access_token(db: &dyn db::Db, user_id: UserId) -> tide::Result { // let access_token = zed_auth::random_token(); // let access_token_hash = // hash_access_token(&access_token).context("failed to hash access token")?; // db.create_access_token_hash(user_id, &access_token_hash, MAX_ACCESS_TOKENS_TO_STORE) // .await?; // Ok(access_token) // } // fn hash_access_token(token: &str) -> tide::Result { // // Avoid slow hashing in debug mode. // let params = if cfg!(debug_assertions) { // scrypt::Params::new(1, 1, 1).unwrap() // } else { // scrypt::Params::recommended() // }; // Ok(Scrypt // .hash_password( // token.as_bytes(), // None, // params, // &SaltString::generate(thread_rng()), // )? // .to_string()) // } // pub fn encrypt_access_token(access_token: &str, public_key: String) -> tide::Result { // let native_app_public_key = // zed_auth::PublicKey::try_from(public_key).context("failed to parse app public key")?; // let encrypted_access_token = native_app_public_key // .encrypt_string(&access_token) // .context("failed to encrypt access token with public key")?; // Ok(encrypted_access_token) // } // pub fn verify_access_token(token: &str, hash: &str) -> tide::Result { // let hash = PasswordHash::new(hash)?; // Ok(Scrypt.verify_password(token.as_bytes(), &hash).is_ok()) // }