Collect some extra info about the user from OAuth
Diff
Cargo.lock | 1 +
chartered-db/Cargo.toml | 1 +
chartered-db/src/schema.rs | 5 +++++
chartered-db/src/users.rs | 29 ++++++++++++++++++++++++++++-
chartered-frontend/src/useAuth.tsx | 2 +-
chartered-web/src/main.rs | 4 ++--
migrations/2021-08-31-214501_create_crates_table/up.sql | 7 ++++++-
chartered-frontend/src/pages/crate/Members.tsx | 4 ++--
chartered-web/src/endpoints/web_api/auth/mod.rs | 2 +-
chartered-web/src/endpoints/web_api/auth/openid.rs | 5 +++++
10 files changed, 50 insertions(+), 10 deletions(-)
@@ -265,6 +265,7 @@
"libsqlite3-sys",
"option_set",
"rand",
"reqwest",
"serde",
"serde_json",
"thiserror",
@@ -22,6 +22,7 @@
libsqlite3-sys = { version = "*", features = ["bundled"] }
option_set = "0.1"
rand = "0.8"
reqwest = "0.11"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
thiserror = "1"
@@ -84,6 +84,11 @@
id -> Integer,
uuid -> Binary,
username -> Text,
name -> Nullable<Text>,
nick -> Nullable<Text>,
email -> Nullable<Text>,
external_profile_url -> Nullable<Text>,
picture_url -> Nullable<Text>,
}
}
@@ -15,6 +15,11 @@
pub id: i32,
pub uuid: SqlUuid,
pub username: String,
pub name: Option<String>,
pub nick: Option<String>,
pub email: Option<String>,
pub external_profile_url: Option<String>,
pub picture_url: Option<String>,
}
impl User {
@@ -113,8 +118,21 @@
.await?
}
pub async fn find_or_create(conn: ConnectionPool, given_username: String) -> Result<User> {
use crate::schema::users::dsl::{username, uuid};
pub async fn find_or_create(
conn: ConnectionPool,
given_username: String,
given_name: Option<String>,
given_nick: Option<String>,
given_email: Option<String>,
given_external_profile_url: Option<reqwest::Url>,
given_picture_url: Option<reqwest::Url>,
) -> Result<User> {
use crate::schema::users::dsl::{
email, external_profile_url, name, nick, picture_url, username, uuid,
};
tokio::task::spawn_blocking(move || {
let conn = conn.get()?;
@@ -131,7 +149,12 @@
diesel::insert_into(users::table)
.values((
username.eq(&given_username),
uuid.eq(SqlUuid::random())
uuid.eq(SqlUuid::random()),
name.eq(&given_name),
nick.eq(&given_nick),
email.eq(&given_email),
external_profile_url.eq(given_external_profile_url.map(|v| v.to_string())),
picture_url.eq(given_picture_url.map(|v| v.to_string())),
))
.execute(&conn)?;
@@ -20,7 +20,7 @@
oauthLogin: (provider: string) => Promise<void>;
logout: () => Promise<void>;
getAuthKey: () => Promise<string | null>;
getUserUuid: () => Promise<string>;
getUserUuid: () => string;
handleLoginResponse: (json: LoginResponse) => any;
}
@@ -10,11 +10,11 @@
http::{header, Method},
AddExtensionLayer, Router,
};
use clap::Clap;
use std::path::PathBuf;
use std::sync::Arc;
use tower::ServiceBuilder;
use tower_http::cors::{Any, CorsLayer};
use clap::Clap;
use std::path::PathBuf;
#[derive(Clap)]
#[clap(version = clap::crate_version!(), author = clap::crate_authors!())]
@@ -1,7 +1,12 @@
CREATE TABLE users (
id INTEGER NOT NULL PRIMARY KEY AUTOINCREMENT,
uuid BINARY(128) NOT NULL UNIQUE,
username VARCHAR(255) NOT NULL UNIQUE
username VARCHAR(255) NOT NULL UNIQUE,
name VARCHAR(255),
nick VARCHAR(255),
email VARCHAR(255),
external_profile_url VARCHAR(2048),
picture_url VARCHAR(2048)
);
INSERT INTO users (id, uuid, username) VALUES (1, X'936DA01F9ABD4D9D80C702AF85C822A8', "admin");
@@ -1,5 +1,6 @@
import React = require("react");
import { useState } from "react";
import { Link } from "react-router-dom";
import {
PersonPlus,
Trash,
@@ -10,7 +11,6 @@
import {
authenticatedEndpoint,
RoundedPicture,
RoundedPicture,
useAuthenticatedRequest,
} from "../../util";
import { useAuth } from "../../useAuth";
@@ -218,7 +218,7 @@
</td>
<td className="align-middle">
<strong>{member.username}</strong>
<strong><Link to={`/users/${member.uuid}`} class="text-decoration-none">{member.username}</Link></strong>
{auth.getUserUuid() === member.uuid ? <>
<br />
<em>(that's you!)</em>
@@ -7,8 +7,8 @@
};
use chartered_db::{
users::{User, UserSession},
ConnectionPool,
uuid::Uuid,
ConnectionPool,
};
use futures::future::Future;
use serde::Serialize;
@@ -102,6 +102,11 @@
let user = User::find_or_create(
db.clone(),
format!("{}:{}", state.provider, userinfo.sub.unwrap()),
userinfo.name,
userinfo.nickname,
userinfo.email,
userinfo.profile,
userinfo.picture,
)
.await?;