🏡 index : ~doyle/chartered.git

author Jordan Doyle <jordan@doyle.la> 2021-10-06 1:55:39.0 +01:00:00
committer Jordan Doyle <jordan@doyle.la> 2021-10-06 1:55:39.0 +01:00:00
commit
7e6f0b519e0f41d9228c8ede68b94b1d9673e85b [patch]
tree
962eba96c61fcd74944715b8af9c364b477c3afb
parent
d8f6bec3c3123093e1d50de37793325bcbe38d43
download
7e6f0b519e0f41d9228c8ede68b94b1d9673e85b.tar.gz

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(-)

diff --git a/Cargo.lock b/Cargo.lock
index 2ad5784..3a4329c 100644
--- a/Cargo.lock
+++ a/Cargo.lock
@@ -265,6 +265,7 @@
 "libsqlite3-sys",
 "option_set",
 "rand",
 "reqwest",
 "serde",
 "serde_json",
 "thiserror",
diff --git a/chartered-db/Cargo.toml b/chartered-db/Cargo.toml
index a95249d..efe6d99 100644
--- a/chartered-db/Cargo.toml
+++ a/chartered-db/Cargo.toml
@@ -22,6 +22,7 @@
libsqlite3-sys = { version = "*", features = ["bundled"] } # https://github.com/rusqlite/rusqlite/issues/914
option_set = "0.1"
rand = "0.8"
reqwest = "0.11"
serde = { version = "1", features = ["derive"] }
serde_json = "1"
thiserror = "1"
diff --git a/chartered-db/src/schema.rs b/chartered-db/src/schema.rs
index 3d9160d..6010788 100644
--- a/chartered-db/src/schema.rs
+++ a/chartered-db/src/schema.rs
@@ -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>,
    }
}

diff --git a/chartered-db/src/users.rs b/chartered-db/src/users.rs
index 9b92cec..a6a9780 100644
--- a/chartered-db/src/users.rs
+++ a/chartered-db/src/users.rs
@@ -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};
    /// Lookup the user in the database by username, or create the user if it doesn't yet

    /// exist. The user will be created with no password so it cannot be logged into using

    /// standard `password` auth, and must be logged into using OAuth.

    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)?;

diff --git a/chartered-frontend/src/useAuth.tsx b/chartered-frontend/src/useAuth.tsx
index b682846..8703e54 100644
--- a/chartered-frontend/src/useAuth.tsx
+++ a/chartered-frontend/src/useAuth.tsx
@@ -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;
}

diff --git a/chartered-web/src/main.rs b/chartered-web/src/main.rs
index af12155..7e9b95d 100644
--- a/chartered-web/src/main.rs
+++ a/chartered-web/src/main.rs
@@ -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!())]
diff --git a/migrations/2021-08-31-214501_create_crates_table/up.sql b/migrations/2021-08-31-214501_create_crates_table/up.sql
index 4f94311..3992d01 100644
--- a/migrations/2021-08-31-214501_create_crates_table/up.sql
+++ a/migrations/2021-08-31-214501_create_crates_table/up.sql
@@ -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");
diff --git a/chartered-frontend/src/pages/crate/Members.tsx b/chartered-frontend/src/pages/crate/Members.tsx
index c697b37..762a657 100644
--- a/chartered-frontend/src/pages/crate/Members.tsx
+++ a/chartered-frontend/src/pages/crate/Members.tsx
@@ -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>
diff --git a/chartered-web/src/endpoints/web_api/auth/mod.rs b/chartered-web/src/endpoints/web_api/auth/mod.rs
index bfc7e1a..3711f44 100644
--- a/chartered-web/src/endpoints/web_api/auth/mod.rs
+++ a/chartered-web/src/endpoints/web_api/auth/mod.rs
@@ -7,8 +7,8 @@
};
use chartered_db::{
    users::{User, UserSession},
    ConnectionPool,
    uuid::Uuid,
    ConnectionPool,
};
use futures::future::Future;
use serde::Serialize;
diff --git a/chartered-web/src/endpoints/web_api/auth/openid.rs b/chartered-web/src/endpoints/web_api/auth/openid.rs
index 63dee0f..46abb30 100644
--- a/chartered-web/src/endpoints/web_api/auth/openid.rs
+++ a/chartered-web/src/endpoints/web_api/auth/openid.rs
@@ -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?;