Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added a mutation to edit specific member details #15

Merged
merged 3 commits into from
Nov 24, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
53 changes: 53 additions & 0 deletions docs/mutations.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

## Contents
- [addMember](#addmember)
- [editMember](#editmember)
- [markAttendance](#markattendance)
- [addAttendance](#addattendance)

Expand Down Expand Up @@ -41,6 +42,58 @@ discordId: String

---

### editMember
Edit details of an existing member.

#### GraphQL Mutation
```graphql
mutation {
editMember(id:0,hostel:"hostel",year:2,macaddress:"mac_address",discordId:"discord_id",hmacSignature:"hmac_signature") {
id
hostel
discord_id
}
}
```

#### Arguments (all required)
```graphql
id: Int!
hostel: String!
year: Int!
macaddress: String!
discordId: String!
hmacSignature: String!
```

**Note:** Follow the below format if you want to leave some fields unchanged
- `''` (*empty string*) for type `String`
- Feilds: `hostel,macaddress,discordId`
- `0` for type `Int`
- Feilds: `year`

For example, If you want to update only `discordId`:

```graphql
mutation {
editMember(id:1,hostel:"",year:0,macaddress:"",discordId:"discord_id",hmacSignature:"hmac_signature") {
id
hostel
discord_id
}
}
```

Note: `id` and `hmacSignature` can't be empty

#### HMAC Format

```
"{secret_key}{id}{hostel}{year}{macaddress}{discord_id}"
```

---

### markAttendance
Record attendance for a member.

Expand Down
54 changes: 54 additions & 0 deletions src/graphql/mutations.rs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,60 @@ impl MutationRoot {
Ok(member)
}

async fn edit_member(
&self,
ctx: &Context<'_>,
id: i32,
hostel: String,
year: i32,
macaddress: String,
discord_id: String,
hmac_signature: String,
) -> Result<Member,sqlx::Error> {
let pool = ctx.data::<Arc<PgPool>>().expect("Pool not found in context");

let secret_key = ctx.data::<String>().expect("HMAC secret not found in context");

let mut mac = HmacSha256::new_from_slice(secret_key.as_bytes()).expect("HMAC can take key of any size");

let message = format!("{}{}{}{}{}", id, hostel, year, macaddress, discord_id);
mac.update(message.as_bytes());

let expected_signature = mac.finalize().into_bytes();

// Convert the received HMAC signature from the client to bytes for comparison
let received_signature = hex::decode(hmac_signature)
.map_err(|_| sqlx::Error::Protocol("Invalid HMAC signature".into()))?;


if expected_signature.as_slice() != received_signature.as_slice() {

return Err(sqlx::Error::Protocol("HMAC verification failed".into()));
}

let member = sqlx::query_as::<_, Member>(
"
UPDATE Member
SET
hostel = CASE WHEN $1 = '' THEN hostel ELSE $1 END,
year = CASE WHEN $2 = 0 THEN year ELSE $2 END,
macaddress = CASE WHEN $3 = '' THEN macaddress ELSE $3 END,
discord_id = CASE WHEN $4 = '' THEN discord_id ELSE $4 END
WHERE id = $5
RETURNING *
"
)

.bind(hostel)
.bind(year)
.bind(macaddress)
.bind(discord_id)
.bind(id)
.fetch_one(pool.as_ref())
.await?;

Ok(member)
}

//Mutation for adding attendance to the Attendance table
async fn add_attendance(
Expand Down