diff --git a/src/resources/activity/activityControllers.js b/src/resources/activity/activityControllers.js
index cec720f870970e1a660b1ca228154cb9139c277b..f134126bd95ea794573236fcc880aaf643e4bb8d 100644
--- a/src/resources/activity/activityControllers.js
+++ b/src/resources/activity/activityControllers.js
@@ -1,10 +1,207 @@
 const { crudControllers } = require('../../utils/crud')
 const { Activity } = require('./activityModel')
+const { User } = require('../user/userModel')
+const { Attendance } = require('../attendance/attendanceModel')
+const { Comment } = require('../comment/commentModel')
+const { omit, pick } = require('lodash')
 
-exports.default = crudControllers(Activity, [
+const pickedKeys = [
   '_id',
   'title',
   'description',
   'date',
   'type',
-])
+  'createdAt',
+  'attendance',
+  'comment',
+]
+
+exports.default = crudControllers(Activity, pickedKeys)
+
+exports.default.createOne = async (req, res) => {
+  try {
+    // Invalid Date provided
+    if (!req.body.date || Date.parse(req.body.date) < new Date().getTime())
+      return res.status(403).json({ messages: ['Invalid date'] })
+
+    let activity = await Activity.create({ ...req.body })
+
+    // Create Initial participants
+    if (
+      !(
+        req.body.initialParticipants != null &&
+        req.body.initialParticipants == false
+      )
+    ) {
+      let acceptedUsers = await User.find({ role: 'accepted' }).lean().exec()
+      acceptedUsers = acceptedUsers.map(function getUserSchaccs(user) {
+        return { schacc: user.schacc }
+      })
+
+      let attendances = activity.attendance
+      for await (let user of acceptedUsers) {
+        const newAttendance = await Attendance.create({
+          activity: activity._id,
+          user: user.schacc,
+        })
+        attendances.push(newAttendance._id)
+      }
+
+      await Activity.findOneAndUpdate(
+        { _id: activity._id },
+        { attendance: attendances },
+        { new: true }
+      )
+        .lean()
+        .exec()
+    }
+
+    await activity
+      .populate({
+        path: 'comment',
+        select: '_id creator text createdAt',
+      })
+      .populate({
+        path: 'attendance',
+        select: '_id user state',
+      })
+      .execPopulate()
+
+    // conver to JS Object to overwrite .creator
+    let objActivity = activity.toObject()
+    objActivity.creator = objActivity._creator
+
+    res
+      .status(200)
+      .json({
+        data: pick(objActivity, pickedKeys),
+      })
+      .end()
+  } catch (err) {
+    if (err.name == 'ValidationError') {
+      // Throwed by Mongoose
+      let messages = []
+      for (field in err.errors) {
+        messages.push(err.errors[field].message)
+      }
+      return res.status(422).json({ messages })
+    }
+    console.error(err)
+    return res.status(500).json({ message: err.message })
+  }
+}
+
+exports.default.getOne = async (req, res) => {
+  try {
+    const activity = await Activity.findOne({ _id: req.params.id })
+      .populate({
+        path: 'comment',
+        select: '_id creator text createdAt',
+      })
+      .populate({
+        path: 'attendance',
+        select: '_id user state',
+      })
+      .select('-__v')
+      .lean()
+      .exec()
+
+    if (!activity)
+      return res.status(404).json({ messages: ['No such activity.'] })
+
+    return res.status(200).json({ data: pick(activity, pickedKeys) })
+  } catch (err) {
+    console.error(err)
+    return res.status(500).json({ message: err.message })
+  }
+}
+
+exports.default.getMany = async (req, res) => {
+  try {
+    const activity = await Activity.find()
+      .populate({
+        path: 'comment',
+        select: '_id creator text createdAt',
+      })
+      .populate({
+        path: 'attendance',
+        select: '_id user state',
+      })
+      .select('-__v')
+      .lean()
+      .exec()
+
+    if (!activity)
+      return res.status(404).json({ message: 'Activity not found!' })
+
+    res.status(200).json({
+      data: activity.map(function pickKeys(doc) {
+        return pick(doc, pickedKeys)
+      }),
+    })
+  } catch (err) {
+    console.error(err)
+    res.status(500).json({ message: err.message })
+  }
+}
+
+exports.default.removeOne = async (req, res) => {
+  try {
+    const activity = await Activity.findByIdAndDelete({
+      _id: req.params.id,
+    })
+      .populate({
+        path: 'comment',
+        select: '_id creator text createdAt',
+      })
+      .select('-__v')
+      .lean()
+      .exec()
+
+    if (!activity) {
+      return res.status(404).json({ message: 'Activity not found!' })
+    }
+
+    await Attendance.deleteMany({
+      _id: activity.attendance.map(function getAttendanceIds(element) {
+        return element._id
+      }),
+    })
+
+    await Comment.deleteMany({
+      _id: activity.comment.map(function getCommentIds(element) {
+        return element._id
+      }),
+    })
+
+    return res.status(200).json({ data: pick(activity, pickedKeys) })
+  } catch (err) {
+    console.error(err)
+    return res.status(500).json({ message: err.message })
+  }
+}
+
+exports.default.updateOne = async (req, res) => {
+  try {
+    const activity = await Activity.findOneAndUpdate(
+      { _id: req.params.id },
+      omit(req.body, ['attendance', 'comment']),
+      { new: true }
+    )
+      .populate({
+        path: 'comment',
+        select: '_id creator text createdAt',
+      })
+      .select('-__v')
+      .lean()
+      .exec()
+
+    if (!activity)
+      return res.status(404).json({ message: 'Activity not found!' })
+
+    res.status(200).json({ data: pick(activity, pickedKeys) })
+  } catch (err) {
+    console.error(err)
+    res.status(500).json({ message: err.message })
+  }
+}
diff --git a/src/resources/activity/activityModel.js b/src/resources/activity/activityModel.js
index fa90dd75f31c2d2f1892b761ae7d019ecbb805e9..36ba685103e811b9fcff0e8482f6b490e9d9f71d 100644
--- a/src/resources/activity/activityModel.js
+++ b/src/resources/activity/activityModel.js
@@ -36,9 +36,6 @@ const ActivitySchema = new mongoose.Schema(
   { 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/activityRouter.js b/src/resources/activity/activityRouter.js
index 6136da10fd53bf472ca8404afca75d9029e022b4..4f3ceee56c2496bd9b9a9a8e7414b0b5a2a36bd9 100644
--- a/src/resources/activity/activityRouter.js
+++ b/src/resources/activity/activityRouter.js
@@ -1,19 +1,20 @@
 const { Router } = require('express')
 const controllers = require('./activityControllers')
+const { isLoggedIn, isMentor } = require('../../middlewares/auth')
 
 const router = Router()
 
 // /api/item
 router
   .route('/')
-  .get(controllers.default.getMany)
-  .post(controllers.default.createOne)
+  .get(isLoggedIn, controllers.default.getMany)
+  .post(isLoggedIn, isMentor, controllers.default.createOne)
 
 // /api/item/:id
 router
   .route('/:id')
-  .get(controllers.default.getOne)
-  .put(controllers.default.updateOne)
-  .delete(controllers.default.removeOne)
+  .get(isLoggedIn, controllers.default.getOne)
+  .put(isLoggedIn, isMentor, controllers.default.updateOne)
+  .delete(isLoggedIn, isMentor, controllers.default.removeOne)
 
 exports.default = router
diff --git a/src/resources/attendance/attendanceControllers.js b/src/resources/attendance/attendanceControllers.js
index d2d9c94d1fa10c773d605f61c99ce81b81459a70..1db3ae4a8a14bec3e792f870bd6bf2367266ce6e 100644
--- a/src/resources/attendance/attendanceControllers.js
+++ b/src/resources/attendance/attendanceControllers.js
@@ -6,6 +6,8 @@ const pickedKeys = ['_id', 'activity', 'user', 'state', 'comment']
 
 exports.default = crudControllers(Attendance, pickedKeys)
 
+// On create update activity
+
 exports.default.getOne = async (req, res) => {
   try {
     const attendance = await Attendance.findOne({ _id: req.params.id })
diff --git a/src/resources/comment/commentControllers.js b/src/resources/comment/commentControllers.js
index aec82b07861967c7a5a7d9a1fbff3178ddadf0aa..1e3c2bb6900ddd71ef0a661a87aa51b0e5f1ce53 100644
--- a/src/resources/comment/commentControllers.js
+++ b/src/resources/comment/commentControllers.js
@@ -1,4 +1,119 @@
 const { crudControllers } = require('../../utils/crud')
 const { Comment } = require('./commentModel')
+const { omit, pick } = require('lodash')
 
-exports.default = crudControllers(Comment)
+exports.default = crudControllers(Comment, ['creator', 'text', 'date'])
+
+function invalidIdResponse(res) {
+  return res
+    .status(403)
+    .json({ messages: ['You cannot modify other users comment.'] })
+    .end()
+}
+
+exports.default.getOne = async (req, res) => {
+  try {
+    const comment = await Comment.findOne({
+      _id: req.params.id,
+    })
+      .populate('creator', ['fullName', 'nickName'])
+      .lean()
+      .exec()
+
+    if (comment.creator._id !== req.user._id && req.user.role !== 'mentor') {
+      return invalidIdResponse(res)
+    }
+
+    return res
+      .status(200)
+      .json({ data: omit(comment, ['_id', '__v', 'creator._id']) })
+      .end()
+  } catch (err) {
+    res.json(err)
+  }
+}
+
+exports.default.getMany = async (req, res) => {
+  try {
+    const comments = await Comment.find()
+      .populate('_creator', '-_id fullName nickName')
+      .select(['-__v'])
+      .lean()
+      .exec()
+
+    return res.status(200).json({ data: comments }).end()
+  } catch (err) {
+    console.log(err)
+    res.json(err)
+  }
+}
+
+exports.default.createOne = async (req, res) => {
+  try {
+    var comment = await Comment.create({
+      creator: req.user.schacc,
+      text: req.body.text,
+    }).catch((err) => console.log(err))
+
+    const retComment = await Comment.findById(comment._id)
+      .populate('_creator', '-_id fullName nickName schacc')
+      .lean()
+      .exec()
+
+    retComment.creator = retComment._creator
+
+    return res
+      .status(200)
+      .json({
+        data: pick(retComment, ['_id', 'creator', 'text', 'createdAt']),
+      })
+      .end()
+  } catch (err) {
+    console.log(err)
+  }
+}
+
+exports.default.updateOne = async (req, res) => {
+  try {
+    var comment = await Comment.findById(req.params.id).populate('creator')
+
+    if (comment.creator._id !== req.user._id) {
+      return invalidIdResponse(res)
+    }
+
+    var updatedComment = await Comment.findOneAndUpdate(
+      { _id: req.params.id },
+      { text: req.body.text },
+      { new: true }
+    )
+      .lean()
+      .exec()
+
+    return res.status(200).json({ data: updatedComment }).end()
+  } catch (err) {
+    console.log(err)
+  }
+}
+
+// TODO on delete remove from other models
+exports.default.removeOne = async (req, res) => {
+  try {
+    const comment = await Comment.findById({ _id: req.params.id })
+      .populate('creator')
+      .lean()
+      .exec()
+
+    if (comment.creator._id !== req.user._id) {
+      return invalidIdResponse(res)
+    }
+
+    const removed = await Comment.findByIdAndRemove({ _id: req.params.id })
+    if (!removed) {
+      return res.status(404).end()
+    }
+
+    return res.status(200).json({ data: comment }).end()
+  } catch (err) {
+    console.log(err)
+  }
+}
diff --git a/src/resources/comment/commentModel.js b/src/resources/comment/commentModel.js
index de782a9ad446e26e80493f5e21e8575fd220b51d..dd3ba0dbd31de531a38b70bf4eebada5e48353d6 100644
--- a/src/resources/comment/commentModel.js
+++ b/src/resources/comment/commentModel.js
@@ -9,9 +9,10 @@ const CommentSchema = new mongoose.Schema(
       type: String,
       required: true,
     },
-    date: {
-      type: Date,
+    isAnonim: {
+      type: Boolean,
       required: true,
+      default: false,
     },
   },
   { timestamps: true }
diff --git a/src/resources/comment/commentRouter.js b/src/resources/comment/commentRouter.js
index f5cb84a37c3648fb59b7d895200ca90c2e6b5eb8..d3e526cb47b55a9deca692514cd827a7e4830327 100644
--- a/src/resources/comment/commentRouter.js
+++ b/src/resources/comment/commentRouter.js
@@ -1,19 +1,20 @@
 const { Router } = require('express')
 const controllers = require('./commentControllers')
+const { isLoggedIn, isMentor } = require('../../middlewares/auth')
 
 const router = Router()
 
 // /api/item
 router
   .route('/')
-  .get(controllers.default.getMany)
-  .post(controllers.default.createOne)
+  .get(isLoggedIn, isMentor, controllers.default.getMany)
+  .post(isLoggedIn, controllers.default.createOne)
 
 // /api/item/:id
 router
   .route('/:id')
-  .get(controllers.default.getOne)
-  .put(controllers.default.updateOne)
-  .delete(controllers.default.removeOne)
+  .get(isLoggedIn, controllers.default.getOne)
+  .put(isLoggedIn, controllers.default.updateOne)
+  .delete(isLoggedIn, controllers.default.removeOne)
 
 exports.default = router
diff --git a/src/resources/solution/solutionControllers.js b/src/resources/solution/solutionControllers.js
index 524b0ebe157656e73a17df5322b43b8591d66058..19950f543b86e26ee71c863cf3ca3ca6b7373d2b 100644
--- a/src/resources/solution/solutionControllers.js
+++ b/src/resources/solution/solutionControllers.js
@@ -1,4 +1,188 @@
 const { crudControllers } = require('../../utils/crud')
 const { Solution } = require('./solutionModel')
+const { Task } = require('../task/taskModel')
+const { pick } = require('lodash')
 
 exports.default = crudControllers(Solution)
+
+exports.default.createOne = async (req, res) => {
+  try {
+    const task = await Task.findById(req.body.task)
+    let solution
+    if (req.user.role === 'mentor' && req.body.creator) {
+      // Mentor Creates/Updates a Solution to someone
+      solution = await Solution.findOneAndUpdate(
+        { creator: req.body.creator, task: req.body.task },
+        { ...req.body },
+        {
+          upsert: true, // Create new One if there is no match
+          returnOriginal: false,
+          setDefaultsOnInsert: true,
+          runValidators: true,
+        }
+      )
+        .lean()
+        .exec()
+    } else {
+      // Someone creates a solution
+      if (req.user.role != 'mentor') {
+        delete req.body.isAccepted
+        delete req.body.comment
+      }
+      if (task.deadline < new Date())
+        return res.status(400).json({
+          message: `Can't create new Solution! End date was ${task.deadline.toDateString()}`,
+        })
+
+      solution = await Solution.findOneAndUpdate(
+        { creator: req.user.schacc, task: req.body.task },
+        { ...req.body },
+        {
+          upsert: true, // Create new One if there is no match
+          returnOriginal: false,
+          setDefaultsOnInsert: true,
+          runValidators: true,
+        }
+      )
+        .lean()
+        .exec()
+    }
+    if (task.solutions.indexOf(solution._id) == -1) {
+      task.solutions.push(solution._id)
+      task.save()
+    }
+
+    let retSolution = await Solution.findById({ _id: solution._id })
+      .populate('_creator', '-_id fullName nickName schacc')
+      .populate('comment', 'text creator createdAt')
+      .lean()
+      .exec()
+
+    retSolution.creator = retSolution._creator
+    return res.status(200).json({
+      data: pick(retSolution, [
+        '_id',
+        'creator',
+        'title',
+        'description',
+        'file',
+        'task',
+        'comment',
+        'createdAt',
+        'updatedAt',
+        'isAccepted',
+      ]),
+    })
+  } catch (err) {
+    if (err.name == 'ValidationError') {
+      // Throwed by Mongoose
+      let messages = []
+      for (field in err.errors) {
+        messages.push(err.errors[field].message)
+      }
+      return res.status(422).json({ messages })
+    }
+    console.error(err)
+    return res.status(500).json({ message: err.message })
+  }
+}
+
+exports.default.getMany = async (req, res) => {
+  try {
+    let solutions = undefined
+
+    if (req.user.role === 'mentor')
+      solutions = await Solution.find()
+        .populate('_creator', '-_id fullName nickName schacc')
+        .populate('comment', 'text creator createdAt')
+        .select('-__v')
+        .lean()
+        .exec()
+    else
+      solutions = await Solution.find({ user: req.user._id })
+        .populate('_creator', '-_id fullName nickName')
+        .populate('comment', '-_id text creator createdAt')
+        .select('-__v')
+        .lean()
+        .exec()
+
+    return res.status(200).json({
+      data: solutions.map((e) => {
+        e.creator = e._creator
+        return pick(e, [
+          '_id',
+          'creator',
+          'title',
+          'description',
+          'file',
+          'task',
+          'comment',
+          'createdAt',
+          'updatedAt',
+          'isAccepted',
+        ])
+      }),
+    })
+  } catch (err) {
+    if (err.name == 'ValidationError') {
+      // Throwed by Mongoose
+      let messages = []
+      for (field in err.errors) {
+        messages.push(err.errors[field].message)
+      }
+      return res.status(422).json({ messages })
+    }
+    console.error(err)
+    return res.status(500).json({ message: err.message })
+  }
+}
+
+exports.default.getOne = async (req, res) => {
+  try {
+    let solution = await Solution.findById({ _id: req.params.id })
+      .populate('_creator', '-_id fullName nickName')
+      .populate('comment', 'text creator createdAt')
+      .select('-__v')
+      .lean()
+      .exec()
+
+    if (!solution)
+      return res.status(404).json({ messages: ['No such solution.'] })
+
+    if (req.user.schacc !== solution.creator && req.user.role !== 'mentor') {
+      return res
+        .status(403)
+        .json({ message: `You don't have permission for this solution.` })
+    }
+
+    return res.status(200).json({
+      data: pick(solution, [
+        '_id',
+        'creator',
+        'title',
+        'description',
+        'file',
+        'task',
+        'comment',
+        'createdAt',
+        'updatedAt',
+        'isAccepted',
+      ]),
+    })
+  } catch (err) {
+    if (err.name == 'ValidationError') {
+      // Throwed by Mongoose
+      let messages = []
+      for (field in err.errors) {
+        messages.push(err.errors[field].message)
+      }
+      return res.status(422).json({ messages })
+    }
+    console.error(err)
+    return res.status(500).json({ message: err.message })
+  }
+}
+
+exports.default.notSupported = async (req, res) => {
+  res.status(404).json({ data: { message: 'Not supported operation!' } })
+}
diff --git a/src/resources/solution/solutionModel.js b/src/resources/solution/solutionModel.js
index cc973a356d3aa438e5070efe4ffd8aafe4b181c5..e54cdcfbc6a7651d0981d40448d3fa7f87684c69 100644
--- a/src/resources/solution/solutionModel.js
+++ b/src/resources/solution/solutionModel.js
@@ -2,6 +2,11 @@ const mongoose = require('mongoose')
 
 const SolutionSchema = new mongoose.Schema(
   {
+    task: {
+      type: mongoose.Schema.Types.ObjectId,
+      ref: 'task',
+      required: true,
+    },
     title: {
       type: String,
       required: true,
@@ -14,9 +19,8 @@ const SolutionSchema = new mongoose.Schema(
       type: String,
       required: true,
     },
-    user: {
-      type: mongoose.Schema.Types.ObjectId,
-      ref: 'user',
+    creator: {
+      type: String,
       required: true,
     },
     comment: [
@@ -29,13 +33,18 @@ const SolutionSchema = new mongoose.Schema(
     isAccepted: {
       type: Boolean,
       required: true,
+      default: false,
     },
   },
   { timestamps: true }
 )
 
-// Careful with the docs, there are some deprecated ones
-// https://mongoosejs.com/docs/guide.html
+SolutionSchema.virtual('_creator', {
+  ref: 'user',
+  localField: 'creator',
+  foreignField: 'schacc',
+  justOne: true,
+})
 
 const Solution = mongoose.model('solution', SolutionSchema)
 
diff --git a/src/resources/solution/solutionRouter.js b/src/resources/solution/solutionRouter.js
index f123b0dd11e2ebeecdc6e434d2db4395cbca999c..7ec1a2f7723ad24da5e01153400d4018d14c8789 100644
--- a/src/resources/solution/solutionRouter.js
+++ b/src/resources/solution/solutionRouter.js
@@ -1,19 +1,20 @@
 const { Router } = require('express')
 const controllers = require('./solutionControllers')
+const { isLoggedIn, isAcceptedOrMentor } = require('../../middlewares/auth')
 
 const router = Router()
 
 // /api/item
 router
   .route('/')
-  .get(controllers.default.getMany)
-  .post(controllers.default.createOne)
+  .get(isLoggedIn, isAcceptedOrMentor, controllers.default.getMany)
+  .post(isLoggedIn, isAcceptedOrMentor, controllers.default.createOne)
 
 // /api/item/:id
 router
   .route('/:id')
-  .get(controllers.default.getOne)
-  .put(controllers.default.updateOne)
-  .delete(controllers.default.removeOne)
+  .get(isLoggedIn, isAcceptedOrMentor, controllers.default.getOne)
+  .delete(isLoggedIn, isAcceptedOrMentor, controllers.default.notSupported)
+  .put(isLoggedIn, isAcceptedOrMentor, controllers.default.notSupported)
 
 exports.default = router
diff --git a/src/resources/task/taskControllers.js b/src/resources/task/taskControllers.js
index 129937434f8712460cd87c931eda5eb92373d386..300f7bcd0156d92c79f51acde5a75b2f244ebd60 100644
--- a/src/resources/task/taskControllers.js
+++ b/src/resources/task/taskControllers.js
@@ -32,6 +32,7 @@ exports.default.getOne = async (req, res) => {
           'createData',
           'bit',
           'creator',
+          'solutions',
         ]),
       })
     } else {
@@ -69,6 +70,7 @@ exports.default.getMany = async (req, res) => {
           'createData',
           'bit',
           'creator',
+          'solutions',
         ])
       }),
     })
@@ -87,6 +89,7 @@ exports.default.createOne = async (req, res) => {
         'createData',
         'bit',
         'creator',
+        'solutions',
       ])
     )
     res.status(201).json({
@@ -98,6 +101,7 @@ exports.default.createOne = async (req, res) => {
         'createData',
         'bit',
         'creator',
+        'solutions',
       ]),
     })
   } catch (err) {
diff --git a/src/resources/task/taskModel.js b/src/resources/task/taskModel.js
index 1832ca9012baa87b6c0f31eaa607aa641d89f7b2..e7fe37c0efb8746867d0cda88443585079c8e99d 100644
--- a/src/resources/task/taskModel.js
+++ b/src/resources/task/taskModel.js
@@ -25,6 +25,13 @@ const TaskSchema = new mongoose.Schema(
     creator: {
       type: String,
     },
+    solutions: [
+      {
+        type: mongoose.Schema.Types.ObjectId,
+        ref: 'solution',
+        required: true,
+      },
+    ],
   },
   { timestamps: true }
 )
diff --git a/src/server.js b/src/server.js
index c315bc67bffecfb26edc4e2d534ae62da2e83787..65284691938e82c04024b0a7ae12dcc353305e0e 100644
--- a/src/server.js
+++ b/src/server.js
@@ -44,7 +44,7 @@ app.use(
 app.use(passport.initialize())
 app.use(passport.session())
 
-if (!config.default.isTest) {
+if (!config.default.isTest || config.default.isDev) {
   require('./utils/oauthSetup')
   app.get(
     '/api/v1/login/authsch',