Skip to content

Commit

Permalink
Adding support for discord oauth verification (#2710)
Browse files Browse the repository at this point in the history
  • Loading branch information
silva-fj committed May 13, 2024
1 parent 566445c commit a4f73b5
Show file tree
Hide file tree
Showing 19 changed files with 664 additions and 78 deletions.
1 change: 1 addition & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -727,6 +727,7 @@ jobs:
- test_name: lit-test-failed-parentchain-extrinsic
- test_name: lit-scheduled-enclave-test
- test_name: lit-twitter-identity-test
- test_name: lit-discord-identity-test
steps:
- uses: actions/checkout@v4

Expand Down
2 changes: 2 additions & 0 deletions local-setup/.env.dev
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,8 @@ TWITTER_AUTH_TOKEN_V2=
TWITTER_CLIENT_ID=
TWITTER_CLIENT_SECRET=
DISCORD_AUTH_TOKEN=
DISCORD_CLIENT_ID=
DISCORD_CLIENT_SECRET=
ACHAINABLE_AUTH_KEY=
ONEBLOCK_NOTION_KEY=
NODEREAL_API_KEY=
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -70,22 +70,32 @@ export default {
TwitterValidationData: {
_enum: {
PublicTweet: "PublicTweet",
OAuth2: "OAuth2",
OAuth2: "TwitterOAuth2",
},
},
PublicTweet: {
tweet_id: "Vec<u8>",
},
OAuth2: {
TwitterOAuth2: {
code: "Vec<u8>",
state: "Vec<u8>",
redirect_uri: "Vec<u8>",
},
DiscordValidationData: {
_enum: {
PublicMessage: "PublicMessage",
OAuth2: "DiscordOAuth2",
},
},
PublicMessage: {
channel_id: "Vec<u8>",
message_id: "Vec<u8>",
guild_id: "Vec<u8>",
},
DiscordOAuth2: {
code: "Vec<u8>",
redirect_uri: "Vec<u8>",
},
Web3ValidationData: {
_enum: {
Substrate: "Web3CommonValidationData",
Expand Down
2 changes: 2 additions & 0 deletions tee-worker/docker/docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -122,6 +122,8 @@ services:
- TWITTER_CLIENT_ID=
- TWITTER_CLIENT_SECRET=
- DISCORD_OFFICIAL_URL=http://localhost:19527
- DISCORD_CLIENT_ID=
- DISCORD_CLIENT_SECRET=
- LITENTRY_DISCORD_MICROSERVICE_URL=http://localhost:19527
- DISCORD_AUTH_TOKEN=
- ACHAINABLE_URL=http://localhost:19527
Expand Down
24 changes: 24 additions & 0 deletions tee-worker/docker/lit-discord-identity-test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
services:
lit-discord-identity-test:
image: litentry/litentry-cli:latest
container_name: litentry-discord-identity-test
volumes:
- ../ts-tests:/ts-tests
- ../client-api:/client-api
- ../cli:/usr/local/worker-cli
build:
context: ..
dockerfile: build.Dockerfile
target: deployed-client
depends_on:
litentry-node:
condition: service_healthy
litentry-worker-1:
condition: service_healthy
networks:
- litentry-test-network
entrypoint: "bash -c '/usr/local/worker-cli/lit_ts_integration_test.sh discord_identity.test.ts 2>&1' "
restart: "no"
networks:
litentry-test-network:
driver: bridge
6 changes: 6 additions & 0 deletions tee-worker/docker/multiworker-docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -123,6 +123,8 @@ services:
- TWITTER_CLIENT_ID=
- TWITTER_CLIENT_SECRET=
- DISCORD_OFFICIAL_URL=http://localhost:19527
- DISCORD_CLIENT_ID=
- DISCORD_CLIENT_SECRET=
- LITENTRY_DISCORD_MICROSERVICE_URL=http://localhost:19527
- DISCORD_AUTH_TOKEN=
- ACHAINABLE_URL=http://localhost:19527
Expand Down Expand Up @@ -184,6 +186,8 @@ services:
- TWITTER_CLIENT_ID=
- TWITTER_CLIENT_SECRET=
- DISCORD_OFFICIAL_URL=http://localhost:19527
- DISCORD_CLIENT_ID=
- DISCORD_CLIENT_SECRET=
- LITENTRY_DISCORD_MICROSERVICE_URL=http://localhost:19527
- DISCORD_AUTH_TOKEN=
- ACHAINABLE_URL=http://localhost:19527
Expand Down Expand Up @@ -245,6 +249,8 @@ services:
- TWITTER_CLIENT_ID=
- TWITTER_CLIENT_SECRET=
- DISCORD_OFFICIAL_URL=http://localhost:19527
- DISCORD_CLIENT_ID=
- DISCORD_CLIENT_SECRET=
- LITENTRY_DISCORD_MICROSERVICE_URL=http://localhost:19527
- DISCORD_AUTH_TOKEN=
- ACHAINABLE_URL=http://localhost:19527
Expand Down
103 changes: 99 additions & 4 deletions tee-worker/litentry/core/data-providers/src/discord_official.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,13 @@ use itc_rest_client::{
};
use log::*;
use serde::{Deserialize, Serialize};
use std::{format, string::String, vec, vec::Vec};
use std::{
collections::HashMap,
format,
string::{String, ToString},
vec,
vec::Vec,
};

#[derive(Serialize, Deserialize, Debug)]
pub struct DiscordMessage {
Expand All @@ -52,6 +58,23 @@ pub struct DiscordUser {
pub discriminator: String,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct DiscordUserAccessTokenData {
pub client_id: String,
pub client_secret: String,
pub code: String,
pub redirect_uri: String,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct DiscordUserAccessToken {
pub access_token: String,
pub refresh_token: String,
pub token_type: String,
pub expires_in: u32,
pub scope: String,
}

impl RestPath<String> for DiscordUser {
fn get_path(path: String) -> Result<String, HttpError> {
Ok(path)
Expand All @@ -64,6 +87,12 @@ impl RestPath<String> for DiscordMessage {
}
}

impl RestPath<String> for DiscordUserAccessToken {
fn get_path(path: String) -> Result<String, HttpError> {
Ok(path)
}
}

impl UserInfo for DiscordMessage {
fn get_user_id(&self) -> Option<String> {
Some(self.author.id.clone())
Expand All @@ -89,6 +118,14 @@ impl DiscordOfficialClient {
DiscordOfficialClient { client }
}

pub fn with_access_token(url: &str, token_type: &str, access_token: &str) -> Self {
let mut headers = Headers::new();
headers.insert(CONNECTION.as_str(), "close");
headers.insert(AUTHORIZATION.as_str(), format!("{} {}", token_type, access_token).as_str());
let client = build_client_with_cert(url, headers);
DiscordOfficialClient { client }
}

pub fn query_message(
&mut self,
channel_id: Vec<u8>,
Expand All @@ -114,6 +151,29 @@ impl DiscordOfficialClient {
.get_with::<String, DiscordUser>(path, query.as_slice())
.map_err(|e| Error::RequestError(format!("{:?}", e)))
}

pub fn request_user_access_token(
&mut self,
data: DiscordUserAccessTokenData,
) -> Result<DiscordUserAccessToken, Error> {
debug!("Discord create access token");

let path = "/api/oauth2/token".to_string();

let mut body = HashMap::new();
body.insert("client_id".to_string(), data.client_id);
body.insert("client_secret".to_string(), data.client_secret);
body.insert("grant_type".to_string(), "authorization_code".to_string());
body.insert("code".to_string(), data.code);
body.insert("redirect_uri".to_string(), data.redirect_uri);

let user_token = self
.client
.post_form_urlencoded_capture::<String, DiscordUserAccessToken>(path, body)
.map_err(|e| Error::RequestError(format!("{:?}", e)))?;

Ok(user_token)
}
}

#[cfg(test)]
Expand Down Expand Up @@ -144,9 +204,44 @@ mod tests {

let message = result.unwrap();
assert_eq!(message.id, message_id);
assert_eq!(message.author.id, "001");
assert_eq!(message.author.username, "elon");
assert_eq!(message.content, "Hello, litentry.");
assert_eq!(message.author.id, "002");
assert_eq!(message.author.username, "alice");
assert_eq!(
message.content,
"63e9a4e993c5dad5f8a19a22057d6c6a86172cf5380711467675061c7ed11bf8"
);
assert_eq!(message.channel_id, channel_id)
}

#[test]
fn get_user_info_work() {
let data_provider_config = init();

let user_id = "@me";

let mut client = DiscordOfficialClient::new(&data_provider_config);
let result = client.get_user_info(user_id.to_string());
assert!(result.is_ok(), "query discord error: {:?}", result);

let user = result.unwrap();
assert_eq!(user.id, "001".to_string());
assert_eq!(user.username, "bob");
assert_eq!(user.discriminator, "0");
}

#[test]
fn request_user_access_token_work() {
let data_provider_config = init();

let data = DiscordUserAccessTokenData {
client_id: "test-client-id".to_string(),
client_secret: "test-client-secret".to_string(),
code: "test-code".to_string(),
redirect_uri: "http://localhost:3000/redirect".to_string(),
};
let mut client = DiscordOfficialClient::new(&data_provider_config);

let result = client.request_user_access_token(data);
assert!(result.is_ok(), "error: {:?}", result);
}
}
18 changes: 18 additions & 0 deletions tee-worker/litentry/core/data-providers/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,6 +171,8 @@ pub struct DataProviderConfig {
pub twitter_client_id: String,
pub twitter_client_secret: String,
pub discord_official_url: String,
pub discord_client_id: String,
pub discord_client_secret: String,
pub litentry_discord_microservice_url: String,
pub discord_auth_token: String,
pub achainable_url: String,
Expand Down Expand Up @@ -219,6 +221,8 @@ impl DataProviderConfig {
twitter_client_id: "".to_string(),
twitter_client_secret: "".to_string(),
discord_official_url: "https://discordapp.com".to_string(),
discord_client_id: "".to_string(),
discord_client_secret: "".to_string(),
litentry_discord_microservice_url: "https://tee-microservice.litentry.io:9528"
.to_string(),
discord_auth_token: "".to_string(),
Expand Down Expand Up @@ -367,6 +371,12 @@ impl DataProviderConfig {
if let Ok(v) = env::var("DISCORD_AUTH_TOKEN") {
config.set_discord_auth_token(v);
}
if let Ok(v) = env::var("DISCORD_CLIENT_ID") {
config.set_discord_client_id(v);
}
if let Ok(v) = env::var("DISCORD_CLIENT_SECRET") {
config.set_discord_client_secret(v);
}
if let Ok(v) = env::var("ACHAINABLE_AUTH_KEY") {
config.set_achainable_auth_key(v);
}
Expand Down Expand Up @@ -408,6 +418,14 @@ impl DataProviderConfig {
self.discord_official_url = v;
Ok(())
}
pub fn set_discord_client_id(&mut self, v: String) {
debug!("set_discord_client_id: {:?}", v);
self.discord_client_id = v;
}
pub fn set_discord_client_secret(&mut self, v: String) {
debug!("set_discord_client_secret: {:?}", v);
self.discord_client_secret = v;
}
pub fn set_litentry_discord_microservice_url(&mut self, v: String) -> Result<(), Error> {
check_url(&v)?;
debug!("set_litentry_discord_microservice_url: {:?}", v);
Expand Down
10 changes: 10 additions & 0 deletions tee-worker/litentry/core/identity-verification/src/web2/discord.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
use crate::{Error, Result};
use lc_data_providers::discord_official::DiscordMessage;
use litentry_primitives::ErrorDetail;
use std::vec::Vec;

pub fn payload_from_discord(discord: &DiscordMessage) -> Result<Vec<u8>> {
let data = &discord.content;
hex::decode(data.strip_prefix("0x").unwrap_or(data.as_str()))
.map_err(|_| Error::LinkIdentityFailed(ErrorDetail::ParseError))
}
Loading

0 comments on commit a4f73b5

Please sign in to comment.