diff --git a/Cargo.lock b/Cargo.lock
index 74e717033bf9feabad07745c1cf7069b27ce0bd3..15abde0bc4c0670495f2f1b8a3c536a3b96be734 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -95,6 +95,11 @@ dependencies = [
  "rand 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)",
 ]
 
+[[package]]
+name = "bitfield"
+version = "0.13.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+
 [[package]]
 name = "bitflags"
 version = "1.2.1"
@@ -1553,6 +1558,7 @@ name = "revolt"
 version = "0.1.0"
 dependencies = [
  "bcrypt 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "bitfield 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)",
  "bson 0.14.0 (registry+https://github.com/rust-lang/crates.io-index)",
  "chrono 0.4.10 (registry+https://github.com/rust-lang/crates.io-index)",
  "dotenv 0.15.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -2677,6 +2683,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
 "checksum base64 0.11.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b41b7ea54a0c9d92199de89e20e58d49f02f8e699814ef3fdf266f6f748d15c7"
 "checksum base64 0.9.3 (registry+https://github.com/rust-lang/crates.io-index)" = "489d6c0ed21b11d038c31b6ceccca973e65d73ba3bd8ecb9a2babf5546164643"
 "checksum bcrypt 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "28dff1c1a22f9401213d983f6c309e807e72c33d5dc5514fe5005b0205c46e8f"
+"checksum bitfield 0.13.2 (registry+https://github.com/rust-lang/crates.io-index)" = "46afbd2983a5d5a7bd740ccb198caf5b82f45c40c09c0eed36052d91cb92e719"
 "checksum bitflags 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "cf1de2fe8c75bc145a2f577add951f8134889b4795d47466a54a5c846d691693"
 "checksum block-buffer 0.7.3 (registry+https://github.com/rust-lang/crates.io-index)" = "c0940dc441f31689269e10ac70eb1002a3a1d3ad1390e030043662eb7fe4688b"
 "checksum block-cipher-trait 0.6.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1c924d49bd09e7c06003acda26cd9742e796e34282ec6c1189404dee0c1f4774"
diff --git a/Cargo.toml b/Cargo.toml
index f9c50dd2b2e07907170fe72af942f9565196f1d3..46faf38f660b61ede0fe7b4fba00c37f1e67d936 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -26,3 +26,4 @@ ws = "0.9.1"
 hashbrown = "0.7.0"
 serde_json = "1.0.47"
 rocket_cors = "0.5.1"
+bitfield = "0.13.2"
diff --git a/src/database/channel.rs b/src/database/channel.rs
index ac35285b3ee33ae65e629540f207cbc5c759c8ec..1aba7e2a4dafd418938fbdb422880350afefb0b7 100644
--- a/src/database/channel.rs
+++ b/src/database/channel.rs
@@ -6,7 +6,7 @@ pub struct Channel {
     pub id: String,
     #[serde(rename = "type")]
     pub channel_type: u8,
-
+   
     pub last_message: Option<String>,
 
     // for Direct Messages
@@ -15,6 +15,7 @@ pub struct Channel {
 
     // for Guilds
     pub name: Option<String>,
+    pub guild: Option<String>,
 
     // for Guilds and Group DMs
     pub description: Option<String>,
diff --git a/src/database/guild.rs b/src/database/guild.rs
index c9254d2393af8dba9d9b4fda192ef06daddc2076..51a74aa5b9e02fbd6e78b14aaf315fb9aaf9e041 100644
--- a/src/database/guild.rs
+++ b/src/database/guild.rs
@@ -1,4 +1,56 @@
 use serde::{Deserialize, Serialize};
+use bson::{bson, doc};
+
+use super::get_collection;
+use mongodb::options::FindOneOptions;
+
+bitfield! {
+    pub struct MemberPermissions(MSB0 [u8]);
+    u8;
+    pub get_access, set_access: 7;
+    pub get_create_invite, set_create_invite: 6;
+    pub get_kick_members, set_kick_members: 5;
+    pub get_ban_members, set_ban_members: 4;
+    pub get_read_messages, set_read_messages: 3;
+    pub get_send_messages, set_send_messages: 2;
+}
+
+pub fn find_member_permissions<C: Into<Option<String>>>(id: String, guild: String, channel: C) -> u8 {
+    let col = get_collection("guilds");
+
+    match col.find_one(
+        doc! {
+            "_id": &guild,
+            "members": {
+                "$elemMatch": {
+                    "id": &id,
+                }
+            }
+        },
+        FindOneOptions::builder()
+            .projection(
+                doc! {
+                    "members.$": 1,
+                    "owner": 1,
+                    "default_permissions": 1,
+                }
+            )
+            .build()
+    ) {
+        Ok(result) => {
+            if let Some(doc) = result {
+                if doc.get_str("owner").unwrap() == id {
+                    return u8::MAX;
+                }
+                
+                doc.get_i32("default_permissions").unwrap() as u8
+            } else {
+                0
+            }
+        },
+        Err(_) => 0
+    }
+}
 
 #[derive(Serialize, Deserialize, Debug)]
 pub struct Member {
@@ -24,4 +76,6 @@ pub struct Guild {
     pub channels: Vec<String>,
     pub members: Vec<Member>,
     pub invites: Vec<Invite>,
+
+    pub default_permissions: u32,
 }
diff --git a/src/main.rs b/src/main.rs
index 13ade671775a1f5cd645fc2fb053c6769e6ad989..a3de253a052a1bd60e53474e4710b387768c898e 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -3,6 +3,8 @@
 extern crate rocket;
 #[macro_use]
 extern crate rocket_contrib;
+#[macro_use]
+extern crate bitfield;
 
 pub mod database;
 pub mod email;
diff --git a/src/routes/guild.rs b/src/routes/guild.rs
index 684b8b49564fef2552cfdc6b86dec8a4dad6361b..37538c219fea31b002f4806c87993b68f46a98cc 100644
--- a/src/routes/guild.rs
+++ b/src/routes/guild.rs
@@ -1,4 +1,4 @@
-use crate::database::{self, channel::Channel, guild::Guild, user::User};
+use crate::database::{self, channel::Channel, guild::{ Guild, find_member_permissions }, user::User};
 
 use bson::{bson, doc, from_bson, Bson};
 use rocket_contrib::json::{Json, JsonValue};
@@ -40,7 +40,11 @@ pub fn my_guilds(user: User) -> JsonValue {
 
 /// fetch a guild
 #[get("/<target>")]
-pub fn guild(user: User, target: Guild) -> JsonValue {
+pub fn guild(user: User, target: Guild) -> Option<JsonValue> {
+    if find_member_permissions(user.id.clone(), target.id.clone(), None) == 0 {
+        return None;
+    }
+
     let mut targets = vec![];
     for channel in target.channels {
         targets.push(Bson::String(channel));
@@ -69,18 +73,18 @@ pub fn guild(user: User, target: Guild) -> JsonValue {
                 }));
             }
 
-            json!({
+            Some(json!({
                 "id": target.id,
                 "name": target.name,
                 "description": target.description,
                 "owner": target.owner,
                 "channels": channels,
-            })
+            }))
         }
-        Err(_) => json!({
+        Err(_) => Some(json!({
             "success": false,
             "error": "Failed to fetch channels."
-        }),
+        })),
     }
 }
 
@@ -91,7 +95,7 @@ pub struct CreateGuild {
     nonce: String,
 }
 
-/// send a message to a channel
+/// create a new guild
 #[post("/create", data = "<info>")]
 pub fn create_guild(user: User, info: Json<CreateGuild>) -> JsonValue {
     if !user.email_verification.verified {
@@ -120,12 +124,14 @@ pub fn create_guild(user: User, info: Json<CreateGuild>) -> JsonValue {
         });
     }
 
+    let id = Ulid::new().to_string();
     let channel_id = Ulid::new().to_string();
     if let Err(_) = channels.insert_one(
         doc! {
             "_id": channel_id.clone(),
             "type": ChannelType::GUILDCHANNEL as u32,
             "name": "general",
+            "guild": id.clone(),
         },
         None,
     ) {
@@ -135,7 +141,6 @@ pub fn create_guild(user: User, info: Json<CreateGuild>) -> JsonValue {
         });
     }
 
-    let id = Ulid::new().to_string();
     if col
         .insert_one(
             doc! {
@@ -153,6 +158,7 @@ pub fn create_guild(user: User, info: Json<CreateGuild>) -> JsonValue {
                     }
                 ],
                 "invites": [],
+                "default_permissions": 51,
             },
             None,
         )