Skip to content

Commit 0975d3f

Browse files
authored
Merge pull request #15 from he1senbrg/dev
Added a mutation to edit specific member details
2 parents 3f7c4c2 + aa7b1aa commit 0975d3f

File tree

2 files changed

+107
-0
lines changed

2 files changed

+107
-0
lines changed

docs/mutations.md

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
## Contents
44
- [addMember](#addmember)
5+
- [editMember](#editmember)
56
- [markAttendance](#markattendance)
67
- [addAttendance](#addattendance)
78

@@ -41,6 +42,58 @@ discordId: String
4142

4243
---
4344

45+
### editMember
46+
Edit details of an existing member.
47+
48+
#### GraphQL Mutation
49+
```graphql
50+
mutation {
51+
editMember(id:0,hostel:"hostel",year:2,macaddress:"mac_address",discordId:"discord_id",hmacSignature:"hmac_signature") {
52+
id
53+
hostel
54+
discord_id
55+
}
56+
}
57+
```
58+
59+
#### Arguments (all required)
60+
```graphql
61+
id: Int!
62+
hostel: String!
63+
year: Int!
64+
macaddress: String!
65+
discordId: String!
66+
hmacSignature: String!
67+
```
68+
69+
**Note:** Follow the below format if you want to leave some fields unchanged
70+
- `''` (*empty string*) for type `String`
71+
- Feilds: `hostel,macaddress,discordId`
72+
- `0` for type `Int`
73+
- Feilds: `year`
74+
75+
For example, If you want to update only `discordId`:
76+
77+
```graphql
78+
mutation {
79+
editMember(id:1,hostel:"",year:0,macaddress:"",discordId:"discord_id",hmacSignature:"hmac_signature") {
80+
id
81+
hostel
82+
discord_id
83+
}
84+
}
85+
```
86+
87+
Note: `id` and `hmacSignature` can't be empty
88+
89+
#### HMAC Format
90+
91+
```
92+
"{secret_key}{id}{hostel}{year}{macaddress}{discord_id}"
93+
```
94+
95+
---
96+
4497
### markAttendance
4598
Record attendance for a member.
4699

src/graphql/mutations.rs

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,60 @@ impl MutationRoot {
5353
Ok(member)
5454
}
5555

56+
async fn edit_member(
57+
&self,
58+
ctx: &Context<'_>,
59+
id: i32,
60+
hostel: String,
61+
year: i32,
62+
macaddress: String,
63+
discord_id: String,
64+
hmac_signature: String,
65+
) -> Result<Member,sqlx::Error> {
66+
let pool = ctx.data::<Arc<PgPool>>().expect("Pool not found in context");
67+
68+
let secret_key = ctx.data::<String>().expect("HMAC secret not found in context");
69+
70+
let mut mac = HmacSha256::new_from_slice(secret_key.as_bytes()).expect("HMAC can take key of any size");
71+
72+
let message = format!("{}{}{}{}{}", id, hostel, year, macaddress, discord_id);
73+
mac.update(message.as_bytes());
74+
75+
let expected_signature = mac.finalize().into_bytes();
76+
77+
// Convert the received HMAC signature from the client to bytes for comparison
78+
let received_signature = hex::decode(hmac_signature)
79+
.map_err(|_| sqlx::Error::Protocol("Invalid HMAC signature".into()))?;
80+
81+
82+
if expected_signature.as_slice() != received_signature.as_slice() {
83+
84+
return Err(sqlx::Error::Protocol("HMAC verification failed".into()));
85+
}
86+
87+
let member = sqlx::query_as::<_, Member>(
88+
"
89+
UPDATE Member
90+
SET
91+
hostel = CASE WHEN $1 = '' THEN hostel ELSE $1 END,
92+
year = CASE WHEN $2 = 0 THEN year ELSE $2 END,
93+
macaddress = CASE WHEN $3 = '' THEN macaddress ELSE $3 END,
94+
discord_id = CASE WHEN $4 = '' THEN discord_id ELSE $4 END
95+
WHERE id = $5
96+
RETURNING *
97+
"
98+
)
99+
100+
.bind(hostel)
101+
.bind(year)
102+
.bind(macaddress)
103+
.bind(discord_id)
104+
.bind(id)
105+
.fetch_one(pool.as_ref())
106+
.await?;
107+
108+
Ok(member)
109+
}
56110

57111
//Mutation for adding attendance to the Attendance table
58112
async fn add_attendance(

0 commit comments

Comments
 (0)