feat: ci: dockerize gotrue auth server (#13)
* feat: ci: dockerize gotrue auth server * feat: build: add gotrue to docker-compose * fix: build: docker-compose + test * feat: ci: simplify tests * feat: ci: add back needed services for compilation * fix: ci: github secrets * fix: ci: use signup * fix: ci: add export * fix: test: generate unique email for registration to avoid conflict
This commit is contained in:
parent
c8ae099e90
commit
b28d5dda4c
|
|
@ -11,8 +11,9 @@ env:
|
|||
CARGO_TERM_COLOR: always
|
||||
SQLX_VERSION: 0.6.2
|
||||
SQLX_FEATURES: "rustls,postgres"
|
||||
APP__GOTRUE__BASE_URL: ${{ secrets.APP__GOTRUE__BASE_URL }}
|
||||
APP__GOTRUE__JWT_SECRET: ${{ secrets.APP__GOTRUE__JWT_SECRET }}
|
||||
APP__GOTRUE__BASE_URL: http://localhost:3000
|
||||
APP__GOTRUE__JWT_SECRET: hello123
|
||||
GOTRUE_SMTP_PASS: ${{ secrets.GOTRUE_SMTP_PASS }}
|
||||
|
||||
jobs:
|
||||
test:
|
||||
|
|
@ -31,6 +32,7 @@ jobs:
|
|||
image: redis:7
|
||||
ports:
|
||||
- 6379:6379
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: dtolnay/rust-toolchain@stable
|
||||
|
|
@ -52,11 +54,21 @@ jobs:
|
|||
- name: Check sqlx-data.json is up-to-date
|
||||
run: |
|
||||
cargo sqlx prepare --check -- --bin appflowy_cloud
|
||||
- name: Run Docker-Compose
|
||||
run: |
|
||||
docker-compose up -d
|
||||
- name: Add registered user
|
||||
run: |
|
||||
export GOTRUE_MAILER_AUTOCONFIRM=true
|
||||
docker-compose up -d
|
||||
curl localhost:9998/signup \
|
||||
--data-raw '{"email":"xigahi8979@tipent.com","password":"Hello123!"}' \
|
||||
--header 'Content-Type: application/json'
|
||||
export GOTRUE_MAILER_AUTOCONFIRM=false
|
||||
docker-compose up -d
|
||||
|
||||
- name: Run tests
|
||||
run: |
|
||||
cargo build
|
||||
cargo run &
|
||||
sleep 5 # wait some time for server to be ready
|
||||
cargo test
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -1,11 +1,12 @@
|
|||
FROM lukemathwalker/cargo-chef:latest-rust-1.65.0 as chef
|
||||
FROM lukemathwalker/cargo-chef:latest-rust-1.69.0 as chef
|
||||
|
||||
WORKDIR /app
|
||||
RUN apt update && apt install lld clang -y
|
||||
|
||||
FROM chef as planner
|
||||
COPY . .
|
||||
# Compute a lock-like file for our project
|
||||
RUN cargo chef prepare --recipe-path recipe.json
|
||||
RUN cargo chef prepare --recipe-path recipe.json
|
||||
|
||||
FROM chef as builder
|
||||
COPY --from=planner /app/recipe.json recipe.json
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
CREATE USER supabase_admin LOGIN CREATEROLE CREATEDB REPLICATION BYPASSRLS;
|
||||
|
||||
-- Supabase super admin
|
||||
CREATE USER supabase_auth_admin NOINHERIT CREATEROLE LOGIN NOREPLICATION PASSWORD 'root';
|
||||
CREATE SCHEMA IF NOT EXISTS auth AUTHORIZATION supabase_auth_admin;
|
||||
GRANT CREATE ON DATABASE postgres TO supabase_auth_admin;
|
||||
ALTER USER supabase_auth_admin SET search_path = 'auth';
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
#!/usr/bin/env bash
|
||||
|
||||
cd "$(dirname "$0")"
|
||||
set -e
|
||||
|
||||
git clone https://github.com/supabase/gotrue.git
|
||||
cp gotrue.env.docker gotrue/.env.docker
|
||||
cd gotrue
|
||||
|
||||
# avoid port conflict with host postgres
|
||||
sed -i "s/'5432:5432'/'5433:5432'/" docker-compose-dev.yml
|
||||
|
||||
make dev &
|
||||
|
||||
while true; do
|
||||
curl localhost:9999/health && break
|
||||
echo "waiting for gotrue to be ready..."
|
||||
sleep 1
|
||||
done
|
||||
|
|
@ -9,8 +9,11 @@ database:
|
|||
port: 5432
|
||||
username: "postgres"
|
||||
password: "password"
|
||||
database_name: "appflowy"
|
||||
database_name: "postgres"
|
||||
websocket:
|
||||
heartbeat_interval: 8
|
||||
client_timeout: 10
|
||||
redis_uri: "redis://127.0.0.1:6379"
|
||||
gotrue:
|
||||
base_url: "http://gotrue:9999"
|
||||
jwt_secret: "hello123"
|
||||
|
|
|
|||
|
|
@ -1,18 +1,46 @@
|
|||
version: '3'
|
||||
services:
|
||||
postgres:
|
||||
image: postgres:14
|
||||
image: postgres
|
||||
environment:
|
||||
- POSTGRES_USER=${POSTGRES_USER:-postgres}
|
||||
- POSTGRES_DB=${POSTGRES_DB:-postgres}
|
||||
- POSTGRES_PASSWORD=${POSTGRES_PASSWORD:-password}
|
||||
- POSTGRES_HOST=${POSTGRES_HOST:-postgres}
|
||||
ports:
|
||||
- "5433:5432"
|
||||
- 5433:5432
|
||||
volumes:
|
||||
- ./build/init.sql:/docker-entrypoint-initdb.d/init.sql
|
||||
|
||||
redis:
|
||||
image: redis:7
|
||||
image: redis
|
||||
ports:
|
||||
- "6380:6379"
|
||||
- 6380:6379
|
||||
|
||||
gotrue:
|
||||
image: supabase/gotrue
|
||||
restart: on-failure
|
||||
depends_on:
|
||||
- postgres
|
||||
environment:
|
||||
- GOTRUE_SITE_URL=http://localhost:3000 # redirected site
|
||||
- GOTRUE_JWT_SECRET=${GOTRUE_JWT_SECRET:-hello123}
|
||||
- GOTRUE_DB_DRIVER=postgres
|
||||
- DATABASE_URL=postgres://supabase_auth_admin:root@postgres:5432/postgres
|
||||
- API_EXTERNAL_URL=http://localhost:9998 # verify site
|
||||
- PORT=9999
|
||||
- GOTRUE_SMTP_HOST=smtp.gmail.com
|
||||
- GOTRUE_SMTP_PORT=465
|
||||
- GOTRUE_SMTP_USER=noreply@appflowy.io
|
||||
- GOTRUE_SMTP_PASS=${GOTRUE_SMTP_PASS:-}
|
||||
- GOTRUE_SMTP_ADMIN_EMAIL=internal@appflowy.io
|
||||
- GOTRUE_RATE_LIMIT_EMAIL_SENT=${GOTRUE_RATE_LIMIT_EMAIL_SENT:-100000}
|
||||
- GOTRUE_SMTP_MAX_FREQUENCY=1ns
|
||||
- GOTRUE_MAILER_URLPATHS_CONFIRMATION=/verify
|
||||
- GOTRUE_MAILER_AUTOCONFIRM=${GOTRUE_MAILER_AUTOCONFIRM:-false}
|
||||
ports:
|
||||
- 9998:9999
|
||||
|
||||
appflowy_cloud:
|
||||
restart: on-failure
|
||||
environment:
|
||||
|
|
@ -24,5 +52,6 @@ services:
|
|||
depends_on:
|
||||
- redis
|
||||
- postgres
|
||||
- gotrue
|
||||
ports:
|
||||
- 8000:8000
|
||||
|
|
|
|||
|
|
@ -69,7 +69,7 @@ pub struct AccessTokenResponse {
|
|||
pub access_token: String,
|
||||
pub token_type: String,
|
||||
pub expires_in: i64,
|
||||
pub expires_at: i64,
|
||||
pub expires_at: Option<i64>, // older versions of GoTrue do not return this
|
||||
pub refresh_token: String,
|
||||
pub user: User,
|
||||
pub provider_access_token: Option<String>,
|
||||
|
|
|
|||
|
|
@ -3,3 +3,4 @@ mod sign_in;
|
|||
mod sign_out;
|
||||
mod sign_up;
|
||||
mod update;
|
||||
mod utils;
|
||||
|
|
|
|||
|
|
@ -1,13 +1,16 @@
|
|||
use appflowy_cloud::client::http::Client;
|
||||
|
||||
use crate::client::constants::LOCALHOST_URL;
|
||||
use crate::client::{
|
||||
constants::LOCALHOST_URL,
|
||||
utils::{generate_unique_email, REGISTERED_EMAIL, REGISTERED_PASSWORD},
|
||||
};
|
||||
|
||||
#[tokio::test]
|
||||
async fn sign_in_unknown_user() {
|
||||
let email = generate_unique_email();
|
||||
let password = "Hello123!";
|
||||
let mut c = Client::from(reqwest::Client::new(), LOCALHOST_URL);
|
||||
let resp = c
|
||||
.sign_in_password("unknown999@appflowy.io", "Hello123!")
|
||||
.await;
|
||||
let resp = c.sign_in_password(&email, password).await;
|
||||
let resp = resp.unwrap();
|
||||
match resp {
|
||||
Ok(()) => panic!("should not be ok"),
|
||||
|
|
@ -22,16 +25,14 @@ async fn sign_in_unknown_user() {
|
|||
async fn sign_in_wrong_password() {
|
||||
let mut c = Client::from(reqwest::Client::new(), LOCALHOST_URL);
|
||||
|
||||
let email = generate_unique_email();
|
||||
let password = "Hello123!";
|
||||
{
|
||||
let _ = c
|
||||
.sign_up("unknown123@appflowy.io", "Hello123!")
|
||||
.await
|
||||
.unwrap();
|
||||
let _ = c.sign_up(&email, password).await.unwrap();
|
||||
}
|
||||
|
||||
let resp = c
|
||||
.sign_in_password("unknown123@appflowy.io", "Hllo123!")
|
||||
.await;
|
||||
let wrong_password = "Hllo123!";
|
||||
let resp = c.sign_in_password(&email, wrong_password).await;
|
||||
let resp = resp.unwrap();
|
||||
match resp {
|
||||
Ok(()) => panic!("should not be ok"),
|
||||
|
|
@ -46,16 +47,13 @@ async fn sign_in_wrong_password() {
|
|||
async fn sign_in_unconfirmed_email() {
|
||||
let mut c = Client::from(reqwest::Client::new(), LOCALHOST_URL);
|
||||
|
||||
let email = generate_unique_email();
|
||||
let password = "Hello123!";
|
||||
{
|
||||
let _ = c
|
||||
.sign_up("unknown123@appflowy.io", "Hello123!")
|
||||
.await
|
||||
.unwrap();
|
||||
let _ = c.sign_up(&email, password).await.unwrap();
|
||||
}
|
||||
|
||||
let resp = c
|
||||
.sign_in_password("unknown123@appflowy.io", "Hello123!")
|
||||
.await;
|
||||
let resp = c.sign_in_password(&email, password).await;
|
||||
let resp = resp.unwrap();
|
||||
match resp {
|
||||
Ok(()) => panic!("should not be ok"),
|
||||
|
|
@ -70,10 +68,9 @@ async fn sign_in_unconfirmed_email() {
|
|||
async fn sign_in_success() {
|
||||
let mut c = Client::from(reqwest::Client::new(), LOCALHOST_URL);
|
||||
|
||||
// pre-registered and confirmed email
|
||||
let email = "xigahi8979@tipent.com";
|
||||
|
||||
let resp = c.sign_in_password(email, "Hello123!").await;
|
||||
let resp = c
|
||||
.sign_in_password(REGISTERED_EMAIL, REGISTERED_PASSWORD)
|
||||
.await;
|
||||
let resp = resp.unwrap();
|
||||
match resp {
|
||||
Ok(()) => {},
|
||||
|
|
|
|||
|
|
@ -1,6 +1,9 @@
|
|||
use appflowy_cloud::client::http::Client;
|
||||
|
||||
use crate::client::constants::LOCALHOST_URL;
|
||||
use crate::client::{
|
||||
constants::LOCALHOST_URL,
|
||||
utils::{REGISTERED_EMAIL, REGISTERED_PASSWORD},
|
||||
};
|
||||
|
||||
#[tokio::test]
|
||||
async fn sign_out_but_not_sign_in() {
|
||||
|
|
@ -13,9 +16,7 @@ async fn sign_out_but_not_sign_in() {
|
|||
async fn sign_out_after_sign_in() {
|
||||
let mut c = Client::from(reqwest::Client::new(), LOCALHOST_URL);
|
||||
|
||||
// pre-registered and confirmed email
|
||||
let email = "xigahi8979@tipent.com";
|
||||
c.sign_in_password(email, "Hello123!")
|
||||
c.sign_in_password(REGISTERED_EMAIL, REGISTERED_PASSWORD)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
|
|
|
|||
|
|
@ -1,27 +1,30 @@
|
|||
use crate::client::constants::LOCALHOST_URL;
|
||||
use crate::client::{constants::LOCALHOST_URL, utils::generate_unique_email};
|
||||
use appflowy_cloud::client::http::Client;
|
||||
|
||||
#[tokio::test]
|
||||
async fn sign_up_success() {
|
||||
let email = generate_unique_email();
|
||||
let password = "Hello!123#";
|
||||
let c = Client::from(reqwest::Client::new(), LOCALHOST_URL);
|
||||
let resp = c
|
||||
.sign_up("exampleuser@appflowy.io", "Hello!123#")
|
||||
.await
|
||||
.unwrap();
|
||||
let resp = c.sign_up(&email, password).await.unwrap();
|
||||
assert!(resp.confirmation_sent_at.is_some());
|
||||
assert!(resp.confirmed_at.is_none());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn sign_up_invalid_email() {
|
||||
let invalid_email = "not_email_address";
|
||||
let password = "Hello!123#";
|
||||
let c = Client::from(reqwest::Client::new(), LOCALHOST_URL);
|
||||
let resp = c.sign_up("exampleuser", "Hello!123#").await;
|
||||
let resp = c.sign_up(invalid_email, password).await;
|
||||
assert!(resp.is_err());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn sign_up_invalid_password() {
|
||||
let email = generate_unique_email();
|
||||
let password = "123";
|
||||
let c = Client::from(reqwest::Client::new(), LOCALHOST_URL);
|
||||
let resp = c.sign_up("exampleuser@appflowy.io", "123").await;
|
||||
let resp = c.sign_up(&email, password).await;
|
||||
assert!(resp.is_err());
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,46 +1,52 @@
|
|||
use appflowy_cloud::client::http::Client;
|
||||
|
||||
use crate::client::constants::LOCALHOST_URL;
|
||||
use crate::client::{
|
||||
constants::LOCALHOST_URL,
|
||||
utils::{generate_unique_email, REGISTERED_EMAIL, REGISTERED_PASSWORD},
|
||||
};
|
||||
|
||||
#[tokio::test]
|
||||
async fn update_but_not_logged_in() {
|
||||
let mut c = Client::from(reqwest::Client::new(), LOCALHOST_URL);
|
||||
let res = c.update("new_email_182@somemail.com", "Hello123!!").await;
|
||||
let new_email = generate_unique_email();
|
||||
let new_password = "Hello123!";
|
||||
let res = c.update(&new_email, new_password).await;
|
||||
assert!(res.is_err());
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn update_password_same_password() {
|
||||
let mut c = Client::from(reqwest::Client::new(), LOCALHOST_URL);
|
||||
let email = "xigahi8979@tipent.com";
|
||||
let password = "Hello123!";
|
||||
c.sign_in_password(email, password).await.unwrap().unwrap();
|
||||
|
||||
let res = c.update(email, "Hello123!").await;
|
||||
assert!(res.is_err());
|
||||
c.sign_in_password(REGISTERED_EMAIL, REGISTERED_PASSWORD)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
c.update(REGISTERED_EMAIL, REGISTERED_PASSWORD)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn update_password_and_revert() {
|
||||
let email = "xigahi8979@tipent.com";
|
||||
let old_password = "Hello123!";
|
||||
let new_password = "Hello456!";
|
||||
{
|
||||
// change password to new_password
|
||||
let mut c = Client::from(reqwest::Client::new(), LOCALHOST_URL);
|
||||
c.sign_in_password(email, old_password)
|
||||
c.sign_in_password(REGISTERED_EMAIL, REGISTERED_PASSWORD)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
c.update(email, new_password).await.unwrap();
|
||||
c.update(REGISTERED_EMAIL, new_password).await.unwrap();
|
||||
}
|
||||
{
|
||||
// revert password to old_password
|
||||
let mut c = Client::from(reqwest::Client::new(), LOCALHOST_URL);
|
||||
c.sign_in_password(email, new_password)
|
||||
c.sign_in_password(REGISTERED_EMAIL, new_password)
|
||||
.await
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
c.update(email, old_password).await.unwrap();
|
||||
c.update(REGISTERED_EMAIL, REGISTERED_PASSWORD)
|
||||
.await
|
||||
.unwrap();
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,8 +1,7 @@
|
|||
use std::time::SystemTime;
|
||||
|
||||
use appflowy_cloud::client::http::Client;
|
||||
|
||||
pub const LOCALHOST_URL: &str = "http://localhost:8000"; //TODO: change to default port, use https
|
||||
pub const REGISTERED_EMAIL: &str = "xigahi8979@tipent.com";
|
||||
pub const REGISTERED_PASSWORD: &str = "Hello123!";
|
||||
|
||||
pub fn timestamp_nano() -> u128 {
|
||||
SystemTime::now()
|
||||
|
|
@ -11,12 +10,6 @@ pub fn timestamp_nano() -> u128 {
|
|||
.as_nanos()
|
||||
}
|
||||
|
||||
pub async fn register_deep_fake(c: &mut Client) -> (String, String, String) {
|
||||
let email = format!("deep_fake{}@appflowy.io", timestamp_nano());
|
||||
let user = "user1";
|
||||
let password = "DeepFakePassword!123";
|
||||
c.register(user, &email, password).await.unwrap();
|
||||
|
||||
assert!(c.logged_in_token().is_some());
|
||||
(email, user.to_string(), password.to_string())
|
||||
pub fn generate_unique_email() -> String {
|
||||
format!("{}@appflowy.io", timestamp_nano())
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue