diff --git a/README.md b/README.md
index c2e3756ac234bfc4be5aba2a7bc31912ef75e313..620a51b9229699821cb0961af2a1dc6a5436c3c7 100644
--- a/README.md
+++ b/README.md
@@ -1 +1,4 @@
 inital readme
+
+cookieKey1 = random
+cookieKey2 = random
diff --git a/package-lock.json b/package-lock.json
index dc481fc23b5f58b173fdc5da528b533e8bc98a3b..3e1c267cb4c0781134a9f1bd1c2bed559412e995 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1049,6 +1049,14 @@
       "integrity": "sha512-3YDiu347mtVtjpyV3u5kVqQLP242c06zwDOgpeRnybmXlYYsLbtTrUBUm8i8srONt+FWobl5aibnU1030PeeuA==",
       "dev": true
     },
+    "axios": {
+      "version": "0.19.2",
+      "resolved": "https://registry.npmjs.org/axios/-/axios-0.19.2.tgz",
+      "integrity": "sha512-fjgm5MvRHLhx+osE2xoekY70AhARk3a6hkN+3Io1jc00jtquGvxYlKlsFUhmUET0V5te6CcZI7lcv2Ym61mjHA==",
+      "requires": {
+        "follow-redirects": "1.5.10"
+      }
+    },
     "babel-jest": {
       "version": "26.1.0",
       "resolved": "https://registry.npmjs.org/babel-jest/-/babel-jest-26.1.0.tgz",
@@ -1180,6 +1188,11 @@
         }
       }
     },
+    "base64url": {
+      "version": "3.0.1",
+      "resolved": "https://registry.npmjs.org/base64url/-/base64url-3.0.1.tgz",
+      "integrity": "sha512-ir1UPr3dkwexU7FdV8qBBbNDRUhMmIekYMFZfi+C/sLNnRESKPl23nB9b2pltqfOQNnGzsDdId90AEtG5tCx4A=="
+    },
     "basic-auth": {
       "version": "2.0.1",
       "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz",
@@ -1722,6 +1735,16 @@
       "resolved": "https://registry.npmjs.org/cookie/-/cookie-0.4.0.tgz",
       "integrity": "sha512-+Hp8fLp57wnUSt0tY0tHEXh4voZRDnoIrZPqlo3DPiI4y9lwg/jqx+1Om94/W6ZaPDOUbnjOt/99w66zk+l1Xg=="
     },
+    "cookie-session": {
+      "version": "1.4.0",
+      "resolved": "https://registry.npmjs.org/cookie-session/-/cookie-session-1.4.0.tgz",
+      "integrity": "sha512-0hhwD+BUIwMXQraiZP/J7VP2YFzqo6g4WqZlWHtEHQ22t0MeZZrNBSCxC1zcaLAs8ApT3BzAKizx9gW/AP9vNA==",
+      "requires": {
+        "cookies": "0.8.0",
+        "debug": "2.6.9",
+        "on-headers": "~1.0.2"
+      }
+    },
     "cookie-signature": {
       "version": "1.0.6",
       "resolved": "https://registry.npmjs.org/cookie-signature/-/cookie-signature-1.0.6.tgz",
@@ -1733,6 +1756,22 @@
       "integrity": "sha512-Mw+adcfzPxcPeI+0WlvRrr/3lGVO0bD75SxX6811cxSh1Wbxx7xZBGK1eVtDf6si8rg2lhnUjsVLMFMfbRIuwA==",
       "dev": true
     },
+    "cookies": {
+      "version": "0.8.0",
+      "resolved": "https://registry.npmjs.org/cookies/-/cookies-0.8.0.tgz",
+      "integrity": "sha512-8aPsApQfebXnuI+537McwYsDtjVxGm8gTIzQI3FDW6t5t/DAhERxtnbEPN/8RX+uZthoz4eCOgloXaE5cYyNow==",
+      "requires": {
+        "depd": "~2.0.0",
+        "keygrip": "~1.1.0"
+      },
+      "dependencies": {
+        "depd": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz",
+          "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw=="
+        }
+      }
+    },
     "copy-descriptor": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz",
@@ -2832,6 +2871,24 @@
       "integrity": "sha512-r5wGx7YeOwNWNlCA0wQ86zKyDLMQr+/RB8xy74M4hTphfmjlijTSSXGuH8rnvKZnfT9i+75zmd8jcKdMR4O6jA==",
       "dev": true
     },
+    "follow-redirects": {
+      "version": "1.5.10",
+      "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.5.10.tgz",
+      "integrity": "sha512-0V5l4Cizzvqt5D44aTXbFZz+FtyXV1vrDN6qrelxtfYQKW0KO0W2T/hkE8xvGa/540LkZlkaUjO4ailYTFtHVQ==",
+      "requires": {
+        "debug": "=3.1.0"
+      },
+      "dependencies": {
+        "debug": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
+          "integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
+          "requires": {
+            "ms": "2.0.0"
+          }
+        }
+      }
+    },
     "for-in": {
       "version": "1.0.2",
       "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz",
@@ -4209,6 +4266,14 @@
       "resolved": "https://registry.npmjs.org/kareem/-/kareem-2.3.1.tgz",
       "integrity": "sha512-l3hLhffs9zqoDe8zjmb/mAN4B8VT3L56EUvKNqLFVs9YlFA+zx7ke1DO8STAdDyYNkeSo1nKmjuvQeI12So8Xw=="
     },
+    "keygrip": {
+      "version": "1.1.0",
+      "resolved": "https://registry.npmjs.org/keygrip/-/keygrip-1.1.0.tgz",
+      "integrity": "sha512-iYSchDJ+liQ8iwbSI2QqsQOvqv58eJCEanyJPJi+Khyu8smkcKSFUCbPwzFcL7YVtZ6eONjqRX/38caJ7QjRAQ==",
+      "requires": {
+        "tsscmp": "1.0.6"
+      }
+    },
     "keyv": {
       "version": "3.1.0",
       "resolved": "https://registry.npmjs.org/keyv/-/keyv-3.1.0.tgz",
@@ -4719,6 +4784,11 @@
       "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==",
       "dev": true
     },
+    "oauth": {
+      "version": "0.9.15",
+      "resolved": "https://registry.npmjs.org/oauth/-/oauth-0.9.15.tgz",
+      "integrity": "sha1-vR/vr2hslrdUda7VGWQS/2DPucE="
+    },
     "oauth-sign": {
       "version": "0.9.0",
       "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
@@ -4930,6 +5000,32 @@
       "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=",
       "dev": true
     },
+    "passport": {
+      "version": "0.4.1",
+      "resolved": "https://registry.npmjs.org/passport/-/passport-0.4.1.tgz",
+      "integrity": "sha512-IxXgZZs8d7uFSt3eqNjM9NQ3g3uQCW5avD8mRNoXV99Yig50vjuaez6dQK2qC0kVWPRTujxY0dWgGfT09adjYg==",
+      "requires": {
+        "passport-strategy": "1.x.x",
+        "pause": "0.0.1"
+      }
+    },
+    "passport-oauth2": {
+      "version": "1.5.0",
+      "resolved": "https://registry.npmjs.org/passport-oauth2/-/passport-oauth2-1.5.0.tgz",
+      "integrity": "sha512-kqBt6vR/5VlCK8iCx1/KpY42kQ+NEHZwsSyt4Y6STiNjU+wWICG1i8ucc1FapXDGO15C5O5VZz7+7vRzrDPXXQ==",
+      "requires": {
+        "base64url": "3.x.x",
+        "oauth": "0.9.x",
+        "passport-strategy": "1.x.x",
+        "uid2": "0.0.x",
+        "utils-merge": "1.x.x"
+      }
+    },
+    "passport-strategy": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/passport-strategy/-/passport-strategy-1.0.0.tgz",
+      "integrity": "sha1-tVOaqPwiWj0a0XlHbd8ja0QPUuQ="
+    },
     "path-exists": {
       "version": "4.0.0",
       "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz",
@@ -4959,6 +5055,11 @@
       "resolved": "https://registry.npmjs.org/path-to-regexp/-/path-to-regexp-0.1.7.tgz",
       "integrity": "sha1-32BBeABfUi8V60SQ5yR6G/qmf4w="
     },
+    "pause": {
+      "version": "0.0.1",
+      "resolved": "https://registry.npmjs.org/pause/-/pause-0.0.1.tgz",
+      "integrity": "sha1-HUCLP9t2kjuVQ9lvtMnf1TXZy10="
+    },
     "performance-now": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
@@ -6394,6 +6495,11 @@
       "integrity": "sha512-i/6DQjL8Xf3be4K/E6Wgpekn5Qasl1usyw++dAA35Ue5orEn65VIxOA+YvNNl9HV3qv70T7CNwjODHZrLwvd1Q==",
       "dev": true
     },
+    "tsscmp": {
+      "version": "1.0.6",
+      "resolved": "https://registry.npmjs.org/tsscmp/-/tsscmp-1.0.6.tgz",
+      "integrity": "sha512-LxhtAkPDTkVCMQjt2h6eBVY28KCjikZqZfMcC15YBeNjkgUpdCfBu5HoiOTDu86v6smE8yOjyEktJ8hlbANHQA=="
+    },
     "tsutils": {
       "version": "3.17.1",
       "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-3.17.1.tgz",
@@ -6457,6 +6563,11 @@
         "is-typedarray": "^1.0.0"
       }
     },
+    "uid2": {
+      "version": "0.0.3",
+      "resolved": "https://registry.npmjs.org/uid2/-/uid2-0.0.3.tgz",
+      "integrity": "sha1-SDEm4Rd03y9xuLY53NeZw3YWK4I="
+    },
     "undefsafe": {
       "version": "2.0.3",
       "resolved": "https://registry.npmjs.org/undefsafe/-/undefsafe-2.0.3.tgz",
diff --git a/package.json b/package.json
index 0e3e37281350807feb1db900d40feecb74d3a9b9..dc69eedd5e846f38d255be157829d8c0e805dbcf 100644
--- a/package.json
+++ b/package.json
@@ -16,7 +16,9 @@
   "author": "DevTeam",
   "license": "MIT",
   "dependencies": {
+    "axios": "^0.19.2",
     "body-parser": "^1.19.0",
+    "cookie-session": "^1.4.0",
     "cors": "^2.8.5",
     "cuid": "^2.1.8",
     "dotenv": "^8.2.0",
@@ -24,6 +26,8 @@
     "lodash": "^4.17.18",
     "mongoose": "^5.9.22",
     "morgan": "^1.10.0",
+    "passport": "^0.4.1",
+    "passport-oauth2": "^1.5.0",
     "validator": "^13.1.1"
   },
   "devDependencies": {
diff --git a/src/auth.js b/src/auth.js
new file mode 100644
index 0000000000000000000000000000000000000000..0dc9c2016a41af030464e065d938d7b4b8d4ba3f
--- /dev/null
+++ b/src/auth.js
@@ -0,0 +1,13 @@
+// Is authenticated
+const isLoggedIn = (req, res, next) => {
+  if (req.user) {
+    next()
+  } else {
+    res.status(401).end()
+  }
+}
+
+// Permissions
+// TODO
+
+exports.isLoggedIn = isLoggedIn
diff --git a/src/resources/activity/activity.controllers.js b/src/resources/activity/activity.controllers.js
new file mode 100644
index 0000000000000000000000000000000000000000..b6e0c4ebfe7cea7d57b2099ed2853d8d0489807e
--- /dev/null
+++ b/src/resources/activity/activity.controllers.js
@@ -0,0 +1,4 @@
+const { crudControllers } = require('../../utils/crud')
+const { Activity } = require('./activity.model')
+
+exports.default = crudControllers(Activity)
diff --git a/src/resources/activity/activity.model.js b/src/resources/activity/activity.model.js
new file mode 100644
index 0000000000000000000000000000000000000000..2cd33663b5ebc7c275649264ce6f8f1cc0c798b6
--- /dev/null
+++ b/src/resources/activity/activity.model.js
@@ -0,0 +1,37 @@
+const mongoose = require('mongoose')
+
+const ActivitySchema = new mongoose.Schema(
+  {
+    title: {
+      type: String,
+      required: true,
+    },
+    description: {
+      type: String,
+      required: true,
+    },
+    date: {
+      type: Date,
+      required: true,
+    },
+    type: {
+      type: ['class', 'optional', 'camp'],
+      required: true,
+    },
+    comment: [
+      {
+        type: mongoose.Schema.Types.ObjectId,
+        ref: 'comment',
+        required: true,
+      },
+    ],
+  },
+  { timestamps: true }
+)
+
+// Careful with the docs, there are some deprecated ones
+// https://mongoosejs.com/docs/guide.html
+
+const Activity = mongoose.model('activity', ActivitySchema)
+
+exports.Activity = Activity
diff --git a/src/resources/activity/activity.router.js b/src/resources/activity/activity.router.js
new file mode 100644
index 0000000000000000000000000000000000000000..4f5f72d3756b662dd468035d59a00941ff211fc4
--- /dev/null
+++ b/src/resources/activity/activity.router.js
@@ -0,0 +1,19 @@
+const { Router } = require('express')
+const controllers = require('./activity.controllers')
+
+const router = Router()
+
+// /api/item
+router
+  .route('/')
+  .get(controllers.default.getMany)
+  .post(controllers.default.createOne)
+
+// /api/item/:id
+router
+  .route('/:id')
+  .get(controllers.default.getOne)
+  .put(controllers.default.updateOne)
+  .delete(controllers.default.removeOne)
+
+exports.default = router
diff --git a/src/resources/application/application.controllers.js b/src/resources/application/application.controllers.js
new file mode 100644
index 0000000000000000000000000000000000000000..a434abde670df6c55245bd2e76a91f2b8245421e
--- /dev/null
+++ b/src/resources/application/application.controllers.js
@@ -0,0 +1,4 @@
+const { crudControllers } = require('../../utils/crud')
+const { Application } = require('./application.model')
+
+exports.default = crudControllers(Application)
diff --git a/src/resources/application/application.model.js b/src/resources/application/application.model.js
new file mode 100644
index 0000000000000000000000000000000000000000..50683f2058ad245e052c2ae1c9ca75a3ea60b7e0
--- /dev/null
+++ b/src/resources/application/application.model.js
@@ -0,0 +1,28 @@
+const mongoose = require('mongoose')
+
+const ApplicationSchema = new mongoose.Schema({
+  motivation: {
+    type: String,
+    required: true,
+  },
+  expectation: {
+    type: String,
+    required: true,
+  },
+  solution: {
+    type: String,
+    required: true,
+  },
+  groups: {
+    type: mongoose.Schema.Types.ObjectId,
+    ref: 'groups',
+    required: true,
+  },
+})
+
+// Careful with the docs, there are some deprecated ones
+// https://mongoosejs.com/docs/guide.html
+
+const Application = mongoose.model('application', ApplicationSchema)
+
+exports.Application = Application
diff --git a/src/resources/application/application.router.js b/src/resources/application/application.router.js
new file mode 100644
index 0000000000000000000000000000000000000000..814cb581e1c0c1631233e00dcb459bba9355291f
--- /dev/null
+++ b/src/resources/application/application.router.js
@@ -0,0 +1,19 @@
+const { Router } = require('express')
+const controllers = require('./application.controllers')
+
+const router = Router()
+
+// /api/item
+router
+  .route('/')
+  .get(controllers.default.getMany)
+  .post(controllers.default.createOne)
+
+// /api/item/:id
+router
+  .route('/:id')
+  .get(controllers.default.getOne)
+  .put(controllers.default.updateOne)
+  .delete(controllers.default.removeOne)
+
+exports.default = router
diff --git a/src/resources/attendance/attendance.controllers.js b/src/resources/attendance/attendance.controllers.js
new file mode 100644
index 0000000000000000000000000000000000000000..2d314a47618d9cb4e9cb78b69d19aeaa7e91ed26
--- /dev/null
+++ b/src/resources/attendance/attendance.controllers.js
@@ -0,0 +1,4 @@
+const { crudControllers } = require('../../utils/crud')
+const { Attendance } = require('./attendance.model')
+
+exports.default = crudControllers(Attendance)
diff --git a/src/resources/attendance/attendance.model.js b/src/resources/attendance/attendance.model.js
new file mode 100644
index 0000000000000000000000000000000000000000..08bd0b4839be56b81fa9ae52828700f685fe93cf
--- /dev/null
+++ b/src/resources/attendance/attendance.model.js
@@ -0,0 +1,31 @@
+const mongoose = require('mongoose')
+
+const AttendanceSchema = new mongoose.Schema(
+  {
+    activity: {
+      type: mongoose.Schema.Types.ObjectId,
+      ref: 'activity',
+      required: true,
+    },
+    user: {
+      type: mongoose.Schema.Types.ObjectId,
+      ref: 'user',
+      required: true,
+    },
+    comment: [
+      {
+        type: mongoose.Schema.Types.ObjectId,
+        ref: 'comment',
+        required: true,
+      },
+    ],
+  },
+  { timestamps: true }
+)
+
+// Careful with the docs, there are some deprecated ones
+// https://mongoosejs.com/docs/guide.html
+
+const Attendance = mongoose.model('attendance', AttendanceSchema)
+
+exports.Attendance = Attendance
diff --git a/src/resources/attendance/attendance.router.js b/src/resources/attendance/attendance.router.js
new file mode 100644
index 0000000000000000000000000000000000000000..42474e976c0bebb97a3adb1234d13f000dd339ce
--- /dev/null
+++ b/src/resources/attendance/attendance.router.js
@@ -0,0 +1,19 @@
+const { Router } = require('express')
+const controllers = require('./attendance.controllers')
+
+const router = Router()
+
+// /api/item
+router
+  .route('/')
+  .get(controllers.default.getMany)
+  .post(controllers.default.createOne)
+
+// /api/item/:id
+router
+  .route('/:id')
+  .get(controllers.default.getOne)
+  .put(controllers.default.updateOne)
+  .delete(controllers.default.removeOne)
+
+exports.default = router
diff --git a/src/resources/comment/comment.controllers.js b/src/resources/comment/comment.controllers.js
new file mode 100644
index 0000000000000000000000000000000000000000..4577b5f6871dbf3fe1c5f7f0c78cd276b15e2558
--- /dev/null
+++ b/src/resources/comment/comment.controllers.js
@@ -0,0 +1,4 @@
+const { crudControllers } = require('../../utils/crud')
+const { Comment } = require('./comment.model')
+
+exports.default = crudControllers(Comment)
diff --git a/src/resources/comment/comment.model.js b/src/resources/comment/comment.model.js
new file mode 100644
index 0000000000000000000000000000000000000000..3a9b22d84eefe0fb2b5b669919a9d1e77667c8bc
--- /dev/null
+++ b/src/resources/comment/comment.model.js
@@ -0,0 +1,27 @@
+const mongoose = require('mongoose')
+
+const CommentSchema = new mongoose.Schema(
+  {
+    creator: {
+      type: mongoose.Schema.Types.ObjectId,
+      ref: 'user',
+      required: true,
+    },
+    text: {
+      type: String,
+      required: true,
+    },
+    date: {
+      type: Date,
+      required: true,
+    },
+  },
+  { timestamps: true }
+)
+
+// Careful with the docs, there are some deprecated ones
+// https://mongoosejs.com/docs/guide.html
+
+const Comment = mongoose.model('comment', CommentSchema)
+
+exports.Comment = Comment
diff --git a/src/resources/comment/comment.router.js b/src/resources/comment/comment.router.js
new file mode 100644
index 0000000000000000000000000000000000000000..a04b49ca2119b7dc149f87a95f4dd9f7e97a0d81
--- /dev/null
+++ b/src/resources/comment/comment.router.js
@@ -0,0 +1,19 @@
+const { Router } = require('express')
+const controllers = require('./comment.controllers')
+
+const router = Router()
+
+// /api/item
+router
+  .route('/')
+  .get(controllers.default.getMany)
+  .post(controllers.default.createOne)
+
+// /api/item/:id
+router
+  .route('/:id')
+  .get(controllers.default.getOne)
+  .put(controllers.default.updateOne)
+  .delete(controllers.default.removeOne)
+
+exports.default = router
diff --git a/src/resources/groups/groups.controllers.js b/src/resources/groups/groups.controllers.js
new file mode 100644
index 0000000000000000000000000000000000000000..a7fa91dca2ab8638cc6570e8ba3c084f0b0372d8
--- /dev/null
+++ b/src/resources/groups/groups.controllers.js
@@ -0,0 +1,4 @@
+const { crudControllers } = require('../../utils/crud')
+const { Groups } = require('./groups.model')
+
+exports.default = crudControllers(Groups)
diff --git a/src/resources/groups/groups.model.js b/src/resources/groups/groups.model.js
new file mode 100644
index 0000000000000000000000000000000000000000..4fa47345a87903dbff26f6c5b7c13787329e4eb9
--- /dev/null
+++ b/src/resources/groups/groups.model.js
@@ -0,0 +1,23 @@
+const mongoose = require('mongoose')
+
+const GroupsSchema = new mongoose.Schema({
+  name: {
+    type: String,
+    required: true,
+  },
+  description: {
+    type: String,
+    required: true,
+  },
+  groupPath: {
+    type: String,
+    required: true,
+  },
+})
+
+// Careful with the docs, there are some deprecated ones
+// https://mongoosejs.com/docs/guide.html
+
+const Groups = mongoose.model('groups', GroupsSchema)
+
+exports.Groups = Groups
diff --git a/src/resources/groups/groups.router.js b/src/resources/groups/groups.router.js
new file mode 100644
index 0000000000000000000000000000000000000000..01f3d6ad5773a05c85d5be440cca319d3c0f3ec2
--- /dev/null
+++ b/src/resources/groups/groups.router.js
@@ -0,0 +1,19 @@
+const { Router } = require('express')
+const controllers = require('./groups.controllers')
+
+const router = Router()
+
+// /api/item
+router
+  .route('/')
+  .get(controllers.default.getMany)
+  .post(controllers.default.createOne)
+
+// /api/item/:id
+router
+  .route('/:id')
+  .get(controllers.default.getOne)
+  .put(controllers.default.updateOne)
+  .delete(controllers.default.removeOne)
+
+exports.default = router
diff --git a/src/resources/mentors/mentors.controllers.js b/src/resources/mentors/mentors.controllers.js
new file mode 100644
index 0000000000000000000000000000000000000000..ba1487026ea10948cda4325826257bd9b4717b1f
--- /dev/null
+++ b/src/resources/mentors/mentors.controllers.js
@@ -0,0 +1,4 @@
+const { crudControllers } = require('../../utils/crud')
+const { Mentors } = require('./mentors.model')
+
+exports.default = crudControllers(Mentors)
diff --git a/src/resources/mentors/mentors.model.js b/src/resources/mentors/mentors.model.js
new file mode 100644
index 0000000000000000000000000000000000000000..b669fdb2e2699db6597680a5c964d7707345c72d
--- /dev/null
+++ b/src/resources/mentors/mentors.model.js
@@ -0,0 +1,20 @@
+const mongoose = require('mongoose')
+
+const MentorsSchema = new mongoose.Schema({
+  user: {
+    type: mongoose.Schema.Types.ObjectId,
+    ref: 'user',
+    required: true,
+  },
+  description: {
+    type: String,
+    required: true,
+  },
+})
+
+// Careful with the docs, there are some deprecated ones
+// https://mongoosejs.com/docs/guide.html
+
+const Mentors = mongoose.model('mentors', MentorsSchema)
+
+exports.Mentors = Mentors
diff --git a/src/resources/mentors/mentors.router.js b/src/resources/mentors/mentors.router.js
new file mode 100644
index 0000000000000000000000000000000000000000..05bcd92147ceefc52d2928a43243178e626fd379
--- /dev/null
+++ b/src/resources/mentors/mentors.router.js
@@ -0,0 +1,19 @@
+const { Router } = require('express')
+const controllers = require('./mentors.controllers')
+
+const router = Router()
+
+// /api/item
+router
+  .route('/')
+  .get(controllers.default.getMany)
+  .post(controllers.default.createOne)
+
+// /api/item/:id
+router
+  .route('/:id')
+  .get(controllers.default.getOne)
+  .put(controllers.default.updateOne)
+  .delete(controllers.default.removeOne)
+
+exports.default = router
diff --git a/src/resources/news/news.controllers.js b/src/resources/news/news.controllers.js
new file mode 100644
index 0000000000000000000000000000000000000000..55537f6a266f9476ecd14c6ec95270499c657ecc
--- /dev/null
+++ b/src/resources/news/news.controllers.js
@@ -0,0 +1,4 @@
+const { crudControllers } = require('../../utils/crud')
+const { News } = require('./news.model')
+
+exports.default = crudControllers(News)
diff --git a/src/resources/news/news.model.js b/src/resources/news/news.model.js
new file mode 100644
index 0000000000000000000000000000000000000000..58e0f5d462b6a763027dab2c22de20360237e46d
--- /dev/null
+++ b/src/resources/news/news.model.js
@@ -0,0 +1,27 @@
+const mongoose = require('mongoose')
+
+const NewsSchema = new mongoose.Schema(
+  {
+    title: {
+      type: String,
+      required: true,
+    },
+    body: {
+      type: String,
+      required: true,
+    },
+    creator: {
+      type: mongoose.Schema.Types.ObjectId,
+      ref: 'user',
+      required: true,
+    },
+  },
+  { timestamps: true }
+)
+
+// Careful with the docs, there are some deprecated ones
+// https://mongoosejs.com/docs/guide.html
+
+const News = mongoose.model('news', NewsSchema)
+
+exports.News = News
diff --git a/src/resources/news/news.router.js b/src/resources/news/news.router.js
new file mode 100644
index 0000000000000000000000000000000000000000..3e2af196072ce77111bd14add41d357840994094
--- /dev/null
+++ b/src/resources/news/news.router.js
@@ -0,0 +1,19 @@
+const { Router } = require('express')
+const controllers = require('./news.controllers')
+
+const router = Router()
+
+// /api/item
+router
+  .route('/')
+  .get(controllers.default.getMany)
+  .post(controllers.default.createOne)
+
+// /api/item/:id
+router
+  .route('/:id')
+  .get(controllers.default.getOne)
+  .put(controllers.default.updateOne)
+  .delete(controllers.default.removeOne)
+
+exports.default = router
diff --git a/src/resources/solution/solution.controllers.js b/src/resources/solution/solution.controllers.js
new file mode 100644
index 0000000000000000000000000000000000000000..e8c0e56d2a6dd3f4af402395c06dcdc34e57ccee
--- /dev/null
+++ b/src/resources/solution/solution.controllers.js
@@ -0,0 +1,4 @@
+const { crudControllers } = require('../../utils/crud')
+const { Solution } = require('./solution.model')
+
+exports.default = crudControllers(Solution)
diff --git a/src/resources/solution/solution.model.js b/src/resources/solution/solution.model.js
new file mode 100644
index 0000000000000000000000000000000000000000..cc973a356d3aa438e5070efe4ffd8aafe4b181c5
--- /dev/null
+++ b/src/resources/solution/solution.model.js
@@ -0,0 +1,42 @@
+const mongoose = require('mongoose')
+
+const SolutionSchema = new mongoose.Schema(
+  {
+    title: {
+      type: String,
+      required: true,
+    },
+    description: {
+      type: String,
+      required: true,
+    },
+    file: {
+      type: String,
+      required: true,
+    },
+    user: {
+      type: mongoose.Schema.Types.ObjectId,
+      ref: 'user',
+      required: true,
+    },
+    comment: [
+      {
+        type: mongoose.Schema.Types.ObjectId,
+        ref: 'comment',
+        required: true,
+      },
+    ],
+    isAccepted: {
+      type: Boolean,
+      required: true,
+    },
+  },
+  { timestamps: true }
+)
+
+// Careful with the docs, there are some deprecated ones
+// https://mongoosejs.com/docs/guide.html
+
+const Solution = mongoose.model('solution', SolutionSchema)
+
+exports.Solution = Solution
diff --git a/src/resources/solution/solution.router.js b/src/resources/solution/solution.router.js
new file mode 100644
index 0000000000000000000000000000000000000000..3eea31136673449593a90c59f910feea952b963f
--- /dev/null
+++ b/src/resources/solution/solution.router.js
@@ -0,0 +1,19 @@
+const { Router } = require('express')
+const controllers = require('./solution.controllers')
+
+const router = Router()
+
+// /api/item
+router
+  .route('/')
+  .get(controllers.default.getMany)
+  .post(controllers.default.createOne)
+
+// /api/item/:id
+router
+  .route('/:id')
+  .get(controllers.default.getOne)
+  .put(controllers.default.updateOne)
+  .delete(controllers.default.removeOne)
+
+exports.default = router
diff --git a/src/resources/task/task.controllers.js b/src/resources/task/task.controllers.js
new file mode 100644
index 0000000000000000000000000000000000000000..0f3d2311bd9d06c436ded3f19d6e7139b5b08deb
--- /dev/null
+++ b/src/resources/task/task.controllers.js
@@ -0,0 +1,4 @@
+const { crudControllers } = require('../../utils/crud')
+const { Task } = require('./task.model')
+
+exports.default = crudControllers(Task)
diff --git a/src/resources/task/task.model.js b/src/resources/task/task.model.js
new file mode 100644
index 0000000000000000000000000000000000000000..a3141a1b3abf4e27771c55613ae0278c2693cac3
--- /dev/null
+++ b/src/resources/task/task.model.js
@@ -0,0 +1,34 @@
+const mongoose = require('mongoose')
+
+const TaskSchema = new mongoose.Schema(
+  {
+    title: {
+      type: String,
+      required: true,
+    },
+    description: {
+      type: String,
+      required: true,
+    },
+    deadline: {
+      type: Date,
+      required: true,
+    },
+    createData: {
+      type: String,
+      required: false,
+    },
+    bit: {
+      type: Number,
+      require: true,
+    },
+  },
+  { timestamps: true }
+)
+
+// Careful with the docs, there are some deprecated ones
+// https://mongoosejs.com/docs/guide.html
+
+const Task = mongoose.model('task', TaskSchema)
+
+exports.Task = Task
diff --git a/src/resources/task/task.router.js b/src/resources/task/task.router.js
new file mode 100644
index 0000000000000000000000000000000000000000..92db0c11a2e623d5f5c9b8d494d25eb021a11c8d
--- /dev/null
+++ b/src/resources/task/task.router.js
@@ -0,0 +1,19 @@
+const { Router } = require('express')
+const controllers = require('./task.controllers')
+
+const router = Router()
+
+// /api/item
+router
+  .route('/')
+  .get(controllers.default.getMany)
+  .post(controllers.default.createOne)
+
+// /api/item/:id
+router
+  .route('/:id')
+  .get(controllers.default.getOne)
+  .put(controllers.default.updateOne)
+  .delete(controllers.default.removeOne)
+
+exports.default = router
diff --git a/src/resources/user/user.model.js b/src/resources/user/user.model.js
index ee8c821ae927b8376665d5ec3db1637dc2ebf1a5..5264973289d838e259993fa3b3aae56aaab4a923 100644
--- a/src/resources/user/user.model.js
+++ b/src/resources/user/user.model.js
@@ -3,6 +3,10 @@ const isEmail = require('validator/lib/isEmail')
 
 const UserSchema = new mongoose.Schema(
   {
+    internal_id: {
+      type: String,
+      required: true,
+    },
     schacc: {
       type: String,
       required: true,
diff --git a/src/routers.js b/src/routers.js
new file mode 100644
index 0000000000000000000000000000000000000000..61c09d9540f977398ddfa200fc5fc8fe9f2fea50
--- /dev/null
+++ b/src/routers.js
@@ -0,0 +1,23 @@
+const userRouter = require('./resources/user/user.router')
+const mentorRouter = require('./resources/mentors/mentors.router')
+const applicationRouter = require('./resources/application/application.router')
+const newsRouter = require('./resources/news/news.router')
+const groupsRouter = require('./resources/groups/groups.router')
+const activityRouter = require('./resources/activity/activity.router')
+const solutionRouter = require('./resources/solution/solution.router')
+const commentRouter = require('./resources/comment/comment.router')
+const attendanceRouter = require('./resources/attendance/attendance.router')
+const taskRouter = require('./resources/task/task.router')
+
+exports.routers = {
+  userRouter: userRouter.default,
+  mentorRouter: mentorRouter.default,
+  applicationRouter: applicationRouter.default,
+  newsRouter: newsRouter.default,
+  groupsRouter: groupsRouter.default,
+  activityRouter: activityRouter.default,
+  solutionRouter: solutionRouter.default,
+  commentRouter: commentRouter.default,
+  attendanceRouter: attendanceRouter.default,
+  taskRouter: taskRouter.default,
+}
diff --git a/src/server.js b/src/server.js
index 6e652d768ead36778090582307ddf8b3a15cf501..af6c13a232a7e8b07f7f059c99549956ba14da16 100644
--- a/src/server.js
+++ b/src/server.js
@@ -1,9 +1,13 @@
 const express = require('express')
 const { json, urlencoded } = require('body-parser')
-const config = require('./config')
 const cors = require('cors')
 const morgan = require('morgan')
-const userRouter = require('./resources/user/user.router')
+const passport = require('passport')
+const cookieSession = require('cookie-session')
+
+require('dotenv').config()
+require('./utils/oauth.setup')
+const routers = require('./routers')
 
 const app = express()
 
@@ -14,7 +18,50 @@ app.use(json())
 app.use(urlencoded({ extended: true }))
 app.use(morgan('dev'))
 
-// app.use('/api/v1', defaultProtectMiddleware)
-app.use('/api/v1/user', userRouter.default)
+app.use(
+  cookieSession({
+    name: 'session',
+    keys: [process.env.cookieKey1, process.env.cookieKey2],
+  })
+)
+
+// Authentication
+app.use(passport.initialize())
+app.use(passport.session())
+
+app.get(
+  '/api/v1/login/authsch',
+  passport.authenticate('oauth2', {
+    scope: ['basic', 'displayName', 'mail', 'linkedAccounts'],
+  })
+)
+
+app.get(
+  '/api/v1/login/complete/authsch',
+  passport.authenticate('oauth2', {
+    failureRedirect: '/', // TODO failed
+  }),
+  function (req, res) {
+    res.redirect('/') // TODO good
+  }
+)
+
+app.get('/api/v1/logout', (req, res) => {
+  req.session = null
+  req.logout()
+  res.redirect('/')
+})
+
+// API Routes
+app.use('/api/v1/user', routers.routers.userRouter)
+app.use('/api/v1/mentor', routers.routers.mentorRouter)
+app.use('/api/v1/application', routers.routers.applicationRouter)
+app.use('/api/v1/news', routers.routers.newsRouter)
+app.use('/api/v1/groups', routers.routers.groupsRouter)
+app.use('api/v1/solution', routers.routers.solutionRouter)
+app.use('api/v1/comment', routers.routers.commentRouter)
+app.use('api/v1/attendance', routers.routers.attendanceRouter)
+app.use('api/v1/task', routers.routers.taskRouter)
+app.use('api/v1/activity', routers.routers.activityRouter)
 
 exports.app = app
diff --git a/src/utils/oauth.setup.js b/src/utils/oauth.setup.js
new file mode 100644
index 0000000000000000000000000000000000000000..65f21b169e7ed1246f1f22e6d2fd37a8046c5f36
--- /dev/null
+++ b/src/utils/oauth.setup.js
@@ -0,0 +1,50 @@
+const passport = require('passport')
+const { User } = require('../resources/user/user.model')
+const Oauth2Strategy = require('passport-oauth2').Strategy
+const axios = require('axios').default
+
+passport.serializeUser(function (user, done) {
+  done(null, user._id)
+})
+
+passport.deserializeUser(function (userId, done) {
+  User.findById(userId, function (err, user) {
+    done(err, user)
+  })
+})
+
+const strategy = new Oauth2Strategy(
+  {
+    authorizationURL: process.env.AUTHORIZATION_URL,
+    tokenURL: process.env.TOKEN_URL,
+    clientID: process.env.CLIENT_ID,
+    clientSecret: process.env.CLIENT_SECRET,
+    callbackURL: process.env.CALLBACK_URL,
+  },
+  async function (accessToken, refreshToken, profile, done) {
+    user = await User.findOne({ internal_id: profile.internal_id })
+    if (!user) {
+      user = await User.create({
+        internal_id: profile.internal_id,
+        schacc: profile.linkedAccounts.schacc,
+        fullName: profile.displayName,
+        secondaryEmail: profile.mail,
+      })
+    }
+    return done(null, user)
+  }
+)
+
+strategy.userProfile = async function (accessToken, done) {
+  try {
+    const response = await axios.get(
+      `https://auth.sch.bme.hu/api/profile/?access_token=${accessToken}`
+    )
+    return done(null, response.data)
+  } catch (error) {
+    console.error(error)
+    // TODO error handling
+  }
+}
+
+passport.use(strategy)