Skip to content

Commit d5aa762

Browse files
committed
Merge branch 'develop'
2 parents 8f8bd51 + 02b920d commit d5aa762

File tree

12 files changed

+99
-38
lines changed

12 files changed

+99
-38
lines changed

Diff for: .gitignore

+2
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
/lambda.mk
22
/target
33

4+
.vscode
5+
46
/config/*.toml
57
!/config/main_sample.toml

Diff for: Dockerfile

+5
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,11 @@ ADD Cargo.lock .
1313

1414
RUN source ~/.cargo/env && cargo fetch
1515

16+
ARG COMMIT=""
17+
ARG NOW=""
18+
ENV KV_SERVER_BUILD_AT=${NOW}
19+
ENV KV_SERVER_CURRENT_COMMIT_ID=${COMMIT}
20+
1621
ADD . .
1722
RUN source ~/.cargo/env && cargo build --release --example lambda
1823

Diff for: Makefile

+1-1
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ lambda-delete:
3030
@aws lambda delete-function --function-name ${func}
3131

3232
lambda-container-build:
33-
@docker build --platform linux/amd64 -t nextid/kv-server-lambda:latest .
33+
@docker build --platform linux/amd64 --build-arg=COMMIT=$(git rev-parse --short HEAD) --build-arg=NOW=$(date +%s) -t nextid/kv-server-lambda:latest .
3434

3535
pg-connect:
3636
@echo "kv_server\n" | docker-compose exec pg psql -Ukv_server kv_server_development

Diff for: docs/api.apib

+13-9
Original file line numberDiff line numberDiff line change
@@ -30,17 +30,19 @@ for Rust.
3030

3131
+ Parameters
3232

33-
- persona (string, required) - Persona pubilc key (hexstring started with `0x`).
33+
- persona (string, required) - Deprecated. Use `avatar` instead.
34+
- avatar (string, required) - Persona public key (hexstring started with `0x`).
3435

3536
+ Example
3637

37-
`GET /v1/kv?persona=0x04c7cacde73af939c35d527b34e0556ea84bab27e6c0ed7c6c59be70f6d2db59c206b23529977117dc8a5d61fa848f94950422b79d1c142bcf623862e49f9e6575`
38+
`GET /v1/kv?avatar=0x04c7cacde73af939c35d527b34e0556ea84bab27e6c0ed7c6c59be70f6d2db59c206b23529977117dc8a5d61fa848f94950422b79d1c142bcf623862e49f9e6575`
3839

3940
+ Response 200 (application/json)
4041

4142
+ Attributes (object)
4243

43-
+ persona (string, required) - Persona public key (uncomressed hexstring started with `0x`).
44+
+ persona (string, required) - Deprecated. Use `avatar` instead.
45+
+ avatar (string, required) - Avatar public key (uncompressed hexstring started with `0x`).
4446
+ proofs (array[object], required) - All proofs belong to this persona
4547
+ platform (string, required) - Platform (incl. `nextid`, which means public key itself).
4648
+ identity (string, required) - Identity.
@@ -49,7 +51,7 @@ for Rust.
4951
+ Body
5052

5153
{
52-
"persona": "0x04c7cacde73af939c35d527b34e0556ea84bab27e6c0ed7c6c59be70f6d2db59c206b23529977117dc8a5d61fa848f94950422b79d1c142bcf623862e49f9e6575",
54+
"avatar": "0x04c7cacde73af939c35d527b34e0556ea84bab27e6c0ed7c6c59be70f6d2db59c206b23529977117dc8a5d61fa848f94950422b79d1c142bcf623862e49f9e6575",
5355
"proofs": [{
5456
"platform": "nextid",
5557
"identity": "0x04c7cacde73.....",
@@ -69,7 +71,7 @@ for Rust.
6971

7072
+ Response 404 (application/json)
7173

72-
Persona not found (no KV was ever created).
74+
Avatar not found (no KV was ever created).
7375

7476
## Get signature payload for updating [POST /v1/kv/payload]
7577

@@ -79,15 +81,16 @@ Persona not found (no KV was ever created).
7981

8082
+ Attributes (object)
8183

82-
+ persona (string, required) - Persona public key (both comressed / uncompressed and with/without `0x` are OK).
84+
+ persona (string, required) - Deprecated. Use `avatar` instead.
85+
+ avatar (string, required) - Avatar public key (both comressed / uncompressed and with/without `0x` are OK).
8386
+ platform (string, required) - Platform (incl. `nextid`, which means public key itself).
8487
+ identity (string, required) - Identity.
8588
+ patch (object, required) - Patch to current data
8689

8790
+ Body
8891

8992
{
90-
"persona": "0x04c7cacde73af939c35d527b34e0556ea84bab27e6c0ed7c6c59be70f6d2db59c206b23529977117dc8a5d61fa848f94950422b79d1c142bcf623862e49f9e6575",
93+
"avatar": "0x04c7cacde73af939c35d527b34e0556ea84bab27e6c0ed7c6c59be70f6d2db59c206b23529977117dc8a5d61fa848f94950422b79d1c142bcf623862e49f9e6575",
9194
"platform": "nextid",
9295
"identity": "0x04c7cacde73af939c35d527b34e0556ea84bab27e6c0ed7c6c59be70f6d2db59c206b23529977117dc8a5d61fa848f94950422b79d1c142bcf623862e49f9e6575",
9396
"patch": {
@@ -124,7 +127,8 @@ Persona not found (no KV was ever created).
124127

125128
+ Attributes (object)
126129

127-
+ persona (string, required) - Persona public key.
130+
+ persona (string, required) - Deprecated. Use `avatar` instead.
131+
+ avatar (string, required) - Avatar public key.
128132
+ platform (string, required) - Platform (incl. `nextid`, which means public key itself).
129133
+ identity (string, required) - Identity.
130134
+ uuid (string, required) - UUID generated by server in `POST /v1/kv/payload`.
@@ -135,7 +139,7 @@ Persona not found (no KV was ever created).
135139
+ Body
136140

137141
{
138-
"persona": "0x04c7cacde73af939c35d527b34e0556ea84bab27e6c0ed7c6c59be70f6d2db59c206b23529977117dc8a5d61fa848f94950422b79d1c142bcf623862e49f9e6575",
142+
"avatar": "0x04c7cacde73af939c35d527b34e0556ea84bab27e6c0ed7c6c59be70f6d2db59c206b23529977117dc8a5d61fa848f94950422b79d1c142bcf623862e49f9e6575",
139143
"platform": "nextid",
140144
"identity": "0x04c7cacde73af939c35d527b34e0556ea84bab27e6c0ed7c6c59be70f6d2db59c206b23529977117dc8a5d61fa848f94950422b79d1c142bcf623862e49f9e6575",
141145
"uuid": "40c13c92-31e5-40d1-aebb-143d8e5b9c5e",
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
-- This file should undo anything in `up.sql`
2+
3+
CREATE UNIQUE INDEX idx_platform_identity
4+
ON kv((lower(platform)), (lower(identity)));
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
-- Your SQL goes here
2+
3+
DROP INDEX IF EXISTS idx_platform_identity;

Diff for: src/controller/healthz.rs

+4
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,17 @@ use serde::Serialize;
88
#[derive(Serialize)]
99
struct HealthzResponse {
1010
pub hello: String,
11+
pub build_at: String,
12+
pub commit_version: String,
1113
}
1214

1315
pub async fn controller(_req: Request) -> Result<Response, Error> {
1416
json_response(
1517
StatusCode::OK,
1618
&HealthzResponse {
1719
hello: "kv server".to_string(),
20+
build_at: option_env!("KV_SERVER_BUILD_AT").unwrap_or("UNKNOWN").to_string(),
21+
commit_version: option_env!("KV_SERVER_CURRENT_COMMIT_ID").unwrap_or("UNKNOWN").to_string(),
1822
},
1923
)
2024
}

Diff for: src/controller/payload.rs

+17-6
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,8 @@ use serde::{Deserialize, Serialize};
1010

1111
#[derive(Debug, Clone, Serialize, Deserialize)]
1212
struct PayloadRequest {
13-
pub persona: String,
13+
pub persona: Option<String>,
14+
pub avatar: Option<String>,
1415
pub platform: String,
1516
pub identity: String,
1617
pub patch: serde_json::Value,
@@ -25,7 +26,13 @@ struct PayloadResponse {
2526

2627
pub async fn controller(req: Request) -> Result<Response, Error> {
2728
let params: PayloadRequest = json_parse_body(&req)?;
28-
let keypair = Secp256k1KeyPair::from_pubkey_hex(&params.persona)?;
29+
30+
let keypair = Secp256k1KeyPair::from_pubkey_hex(
31+
&params
32+
.avatar
33+
.or(params.persona)
34+
.ok_or_else(|| Error::ParamError("avatar not found".into()))?,
35+
)?;
2936
can_set_kv(&keypair.public_key, &params.platform, &params.identity).await?;
3037
let conn = establish_connection();
3138
let mut new_kvchain = NewKVChain::for_persona(&conn, &keypair.public_key)?;
@@ -54,8 +61,10 @@ mod tests {
5461
use serde_json::json;
5562

5663
use crate::{
57-
crypto::util::{compress_public_key, hex_public_key}, model::kv_chains::KVChain, schema::kv_chains::dsl::*,
58-
util::{vec_to_base64, naive_now},
64+
crypto::util::{compress_public_key, hex_public_key},
65+
model::kv_chains::KVChain,
66+
schema::kv_chains::dsl::*,
67+
util::{naive_now, vec_to_base64},
5968
};
6069

6170
use super::*;
@@ -89,7 +98,8 @@ mod tests {
8998
} = Secp256k1KeyPair::generate();
9099

91100
let req_body = PayloadRequest {
92-
persona: compress_public_key(&public_key),
101+
persona: Some(compress_public_key(&public_key)),
102+
avatar: None,
93103
platform: "facebook".into(),
94104
identity: Faker.fake(),
95105
patch: json!({"test":"abc"}),
@@ -120,7 +130,8 @@ mod tests {
120130
let old_kv_chain = generate_data(&conn, &public_key).unwrap();
121131

122132
let req_body = PayloadRequest {
123-
persona: compress_public_key(&public_key),
133+
persona: None,
134+
avatar: Some(compress_public_key(&public_key)),
124135
platform: "facebook".into(),
125136
identity: Faker.fake(),
126137
patch: json!({"test":"abc"}),

Diff for: src/controller/query.rs

+9-6
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ use super::json_response;
1414
#[derive(Debug, Clone, Serialize, Deserialize)]
1515
pub struct QueryResponse {
1616
pub persona: String,
17+
pub avatar: String,
1718
pub proofs: Vec<QueryResponseSingleProof>,
1819
}
1920

@@ -26,13 +27,14 @@ pub struct QueryResponseSingleProof {
2627

2728
pub async fn controller(req: Request) -> Result<Response, Error> {
2829
let params = query_parse(req);
29-
let persona_hex = params
30-
.get("persona")
31-
.ok_or(Error::ParamMissing("persona".into()))?;
30+
let avatar_hex = params
31+
.get("avatar")
32+
.or(params.get("persona"))
33+
.ok_or(Error::ParamMissing("avatar".into()))?;
3234
let Secp256k1KeyPair {
3335
public_key,
3436
secret_key: _,
35-
} = Secp256k1KeyPair::from_pubkey_hex(persona_hex)?;
37+
} = Secp256k1KeyPair::from_pubkey_hex(avatar_hex)?;
3638

3739
let conn = establish_connection();
3840
let response = query_response(&conn, &public_key)?;
@@ -49,6 +51,7 @@ pub fn query_response(
4951
let persona_hex = hex_public_key(persona_public_key);
5052
let mut response = QueryResponse {
5153
persona: format!("0x{}", persona_hex),
54+
avatar: format!("0x{}", persona_hex),
5255
proofs: vec![],
5356
};
5457
for proof in results.iter() {
@@ -86,7 +89,7 @@ mod tests {
8689
let resp = controller(req).await.unwrap();
8790
let body: QueryResponse = serde_json::from_str(resp.body()).unwrap();
8891
assert_eq!(0, body.proofs.len());
89-
assert_eq!(format!("0x{}", pubkey_hex), body.persona);
92+
assert_eq!(format!("0x{}", pubkey_hex), body.avatar);
9093
}
9194

9295
#[tokio::test]
@@ -109,7 +112,7 @@ mod tests {
109112
let resp = controller(req).await.unwrap();
110113
let body: QueryResponse = serde_json::from_str(resp.body()).unwrap();
111114
assert_eq!(1, body.proofs.len());
112-
assert_eq!(format!("0x{}", hex_public_key(&public_key)), body.persona);
115+
assert_eq!(format!("0x{}", hex_public_key(&public_key)), body.avatar);
113116
assert_eq!("twitter", body.proofs.first().unwrap().platform);
114117
assert_eq!(json!({}), body.proofs.first().unwrap().content);
115118
}

Diff for: src/controller/upload.rs

+20-8
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,8 @@ use serde::{Deserialize, Serialize};
1212

1313
#[derive(Debug, Clone, Deserialize, Serialize)]
1414
struct UploadRequest {
15-
pub persona: String,
15+
pub persona: Option<String>,
16+
pub avatar: Option<String>,
1617
pub platform: String,
1718
pub identity: String,
1819
pub signature: String,
@@ -24,7 +25,11 @@ struct UploadRequest {
2425
pub async fn controller(request: Request) -> Result<Response, Error> {
2526
let req: UploadRequest = json_parse_body(&request)?;
2627
let sig = base64_to_vec(&req.signature)?;
27-
let persona = Secp256k1KeyPair::from_pubkey_hex(&req.persona)?;
28+
let persona = Secp256k1KeyPair::from_pubkey_hex(
29+
&req.avatar
30+
.or(req.persona)
31+
.ok_or_else(|| Error::ParamError("avatar not found".into()))?,
32+
)?;
2833
let uuid = uuid::Uuid::parse_str(&req.uuid)?;
2934
can_set_kv(&persona.public_key, &req.platform, &req.identity).await?;
3035

@@ -36,7 +41,8 @@ pub async fn controller(request: Request) -> Result<Response, Error> {
3641
new_kv.patch = req.patch.clone();
3742
new_kv.uuid = uuid;
3843
new_kv.created_at = timestamp_to_naive(req.created_at);
39-
new_kv.signature_payload = serde_json::to_string(&new_kv.generate_signature_payload()?).unwrap();
44+
new_kv.signature_payload =
45+
serde_json::to_string(&new_kv.generate_signature_payload()?).unwrap();
4046

4147
// Validate signature
4248
new_kv.validate()?;
@@ -58,7 +64,7 @@ mod tests {
5864
controller::query::QueryResponse,
5965
crypto::util::{compress_public_key, hex_public_key},
6066
model::{establish_connection, kv},
61-
util::{vec_to_base64, naive_now},
67+
util::{naive_now, vec_to_base64},
6268
};
6369
use fake::{Fake, Faker};
6470
use http::Method;
@@ -81,7 +87,8 @@ mod tests {
8187
new_kv_chain.signature = new_kv_chain.sign(&keypair).unwrap();
8288

8389
let req_body = UploadRequest {
84-
persona: compress_public_key(&keypair.public_key),
90+
persona: None,
91+
avatar: Some(compress_public_key(&keypair.public_key)),
8592
platform: new_kv_chain.platform.clone(),
8693
identity: new_kv_chain.identity,
8794
signature: vec_to_base64(&new_kv_chain.signature),
@@ -99,7 +106,10 @@ mod tests {
99106
assert_eq!(resp.status(), StatusCode::CREATED);
100107
let resp_body: QueryResponse = serde_json::from_str(resp.body()).unwrap();
101108
assert_eq!(1, resp_body.proofs.len());
102-
assert_eq!(format!("0x{}", hex_public_key(&keypair.public_key)), resp_body.persona);
109+
assert_eq!(
110+
format!("0x{}", hex_public_key(&keypair.public_key)),
111+
resp_body.persona
112+
);
103113
assert_eq!(
104114
new_kv_chain.platform,
105115
resp_body.proofs.first().unwrap().platform
@@ -137,7 +147,8 @@ mod tests {
137147
new_kv_chain.signature = sig;
138148

139149
let req_body = UploadRequest {
140-
persona: compress_public_key(&keypair.public_key),
150+
persona: Some(compress_public_key(&keypair.public_key)),
151+
avatar: None,
141152
platform: new_kv_chain.platform.clone(),
142153
identity: new_kv_chain.identity,
143154
signature: vec_to_base64(&new_kv_chain.signature),
@@ -162,7 +173,8 @@ mod tests {
162173
#[tokio::test]
163174
async fn test_actual_case_1() {
164175
let req_body = UploadRequest{
165-
persona: "0x0289689d4846db795310b3fb6dea7ab8aba2b6734ddd3b3744a412ab174bf8cbfc".into(),
176+
persona: Some("0x0289689d4846db795310b3fb6dea7ab8aba2b6734ddd3b3744a412ab174bf8cbfc".into()),
177+
avatar: None,
166178
platform: "twitter".into(),
167179
identity: "weipingzhu2".into(),
168180
signature: "De/UN6E7HosqZxhpG3+CRD7m8T+ozcdvKO/JCXTr/X9Hek0KP2SQFZQtZQOv/F9XgwufvHeGyD387I7QwJAxqRs=".into(),

Diff for: src/crypto/secp256k1.rs

+18-5
Original file line numberDiff line numberDiff line change
@@ -211,7 +211,14 @@ impl Secp256k1KeyPair {
211211
mod tests {
212212
use serde_json::json;
213213

214-
use crate::{crypto::util::hex_public_key, model::{kv_chains::{SignPayload, NewKVChain}, self}, util};
214+
use crate::{
215+
crypto::util::hex_public_key,
216+
model::{
217+
self,
218+
kv_chains::{NewKVChain, SignPayload},
219+
},
220+
util,
221+
};
215222

216223
use super::*;
217224

@@ -226,7 +233,7 @@ mod tests {
226233
let payload = SignPayload {
227234
version: "1".into(),
228235
uuid: uuid::Uuid::parse_str("fd042b27-0f21-476d-9e23-478c98ac6700")?,
229-
persona: hex_public_key(&public_key),
236+
avatar: hex_public_key(&public_key),
230237
platform: "twitter".into(),
231238
identity: "weipingzhu2".into(),
232239
patch: json!({
@@ -264,7 +271,7 @@ mod tests {
264271
let payload = SignPayload {
265272
version: "1".into(),
266273
uuid: uuid::Uuid::parse_str("b333f060-2cdd-4a7f-8fb1-c790c0fadc20")?,
267-
persona: hex_public_key(&public_key),
274+
avatar: hex_public_key(&public_key),
268275
platform: "nextid".into(),
269276
identity: "0x03b0a3ebb1fb9b7f3ba7653dfb8776e9db5de537e8cd6c4b9cc927cbbcdc394018".into(),
270277
patch: json!({"com.maskbook.tip":[{"created_at":"1650188620","identity":"0x8c5494d05b4f18639834a0f1f4577d5c0a67adf0","invalid_reason":"","isDefault":0,"isPublic":1,"is_valid":true,"last_checked_at":"1650188620","platform":"ethereum"},{"created_at":"1650195158","identity":"0x2ec8ebb0a8eaa40e4ce620cf9f84a96df68d4669","invalid_reason":"","isDefault":1,"isPublic":1,"is_valid":true,"last_checked_at":"1650195158","platform":"ethereum"}]}),
@@ -273,7 +280,10 @@ mod tests {
273280
};
274281
let expected_payload = r#"{"version":"1","uuid":"b333f060-2cdd-4a7f-8fb1-c790c0fadc20","persona":"04b0a3ebb1fb9b7f3ba7653dfb8776e9db5de537e8cd6c4b9cc927cbbcdc394018b99ab0ebafec620820056af9fe162dda5c536b408aedacbd2cdd79db7f56ef91","platform":"nextid","identity":"0x03b0a3ebb1fb9b7f3ba7653dfb8776e9db5de537e8cd6c4b9cc927cbbcdc394018","patch":{"com.maskbook.tip":[{"created_at":"1650188620","identity":"0x8c5494d05b4f18639834a0f1f4577d5c0a67adf0","invalid_reason":"","isDefault":0,"isPublic":1,"is_valid":true,"last_checked_at":"1650188620","platform":"ethereum"},{"created_at":"1650195158","identity":"0x2ec8ebb0a8eaa40e4ce620cf9f84a96df68d4669","invalid_reason":"","isDefault":1,"isPublic":1,"is_valid":true,"last_checked_at":"1650195158","platform":"ethereum"}]},"created_at":1650209531,"previous":null}"#;
275282

276-
assert_eq!(serde_json::to_string(&payload)?, expected_payload.to_string());
283+
assert_eq!(
284+
serde_json::to_string(&payload)?,
285+
expected_payload.to_string()
286+
);
277287
let signature = util::base64_to_vec(&"CNn87foZQt8AY+yRA/ys2/99zlD6gEnph3ujaIdQXxlKdHB41Ev+/rS/fzIULuWrljGreVbR/hRHL7RB51jIfRs=".into())?;
278288
let pubkey_recovered =
279289
Secp256k1KeyPair::recover_from_personal_signature(&signature, &expected_payload)?;
@@ -288,7 +298,10 @@ mod tests {
288298
new_kv.uuid = payload.uuid;
289299
new_kv.created_at = util::timestamp_to_naive(payload.created_at);
290300

291-
assert_eq!(expected_payload, serde_json::to_string(&new_kv.generate_signature_payload()?)?);
301+
assert_eq!(
302+
expected_payload,
303+
serde_json::to_string(&new_kv.generate_signature_payload()?)?
304+
);
292305

293306
Ok(())
294307
}

0 commit comments

Comments
 (0)