diff --git a/src/ClientServer/Controllers/Core/Exercises/DownloadAssetController.cs b/src/ClientServer/Controllers/Core/Exercises/DownloadAssetController.cs
index 10c201388188deab8628172ef059c010ddc0b5e6..640deae10e239dcfa4c0c2bf8a10367a4b322eab 100644
--- a/src/ClientServer/Controllers/Core/Exercises/DownloadAssetController.cs
+++ b/src/ClientServer/Controllers/Core/Exercises/DownloadAssetController.cs
@@ -15,14 +15,26 @@ using Microsoft.Extensions.Primitives;
 namespace ClientServer.Controllers.Core.Exercises
 {
     [Route(Constants.ApiPrefix + "assets")]
-    public class TestAssetController : ControllerWithDb
+    public class DownloadAssetController : ControllerWithDb
     {
-        public TestAssetController(SyndromDbContext context) : base(context)
+        /*
+         * no participation --> not allowed to download asset
+         * if we set this the browser will not download the json response as a file?? (TODO check that)
+         * Response.StatusCode = 406;
+         *
+         *
+         * we don't need methods to download exercise description or custom project description assets
+         * because the frontend already loads the content and thus can locally "download" the file (via blobs)
+         */
+        
+        
+
+        public DownloadAssetController(SyndromDbContext context) : base(context)
         {
         }
 
         /// <summary>
-        /// gets (downloads) the test asset
+        /// gets (downloads) the normal/submit test asset
         /// </summary>
         /// <param name="generatedCode">the release code</param>
         /// <param name="testId">the test id</param>
@@ -37,17 +49,27 @@ namespace ClientServer.Controllers.Core.Exercises
 
             int userId = GetUserId();
 
+            int exerciseId;
 
             if (asTutor)
             {
                 //check if the user is really a tutor for this exercise (group)
 
-                var targetUserGroupId =
+                var exerciseDataTuple =
                     await _context.ExerciseReleases.Where(p => p.GeneratedCode == generatedCode)
-                        .Select(p => p.Exercise.UserGroupId)
+                        .Select(p => new {p.Exercise.UserGroupId, p.ExerciseId})
                         .FirstOrDefaultAsync();
 
-                if (!await base.HasGroupPermission(targetUserGroupId,
+                if (exerciseDataTuple == null)
+                {
+                    Response.StatusCode = 406;
+                    await
+                        Response.WriteAsync(
+                            Jc.Serialize(new BasicResponse(ResponseCode.NotFound, "participation not found")));
+                    return;
+                }
+
+                if (!await base.HasGroupPermission(exerciseDataTuple.UserGroupId,
                     permission => permission != null && permission.CanAssessExercises))
                 {
                     Response.StatusCode = 406;
@@ -56,6 +78,8 @@ namespace ClientServer.Controllers.Core.Exercises
                             Jc.Serialize(new BasicResponse(ResponseCode.NoPermission, "no permission")));
                     return;
                 }
+
+                exerciseId = exerciseDataTuple.ExerciseId;
             }
             else
             {
@@ -76,6 +100,15 @@ namespace ClientServer.Controllers.Core.Exercises
                     return;
                 }
 
+                if (participation.ExerciseRelease == null)
+                {
+                    Response.StatusCode = 406;
+                    await
+                        Response.WriteAsync(
+                            Jc.Serialize(new BasicResponse(ResponseCode.NotFound, "exercise release not found")));
+                    return;
+                }
+
                 if (isSubmitTest)
                 {
                     //submit tests are only displayed when the release is finished...
@@ -93,14 +126,17 @@ namespace ClientServer.Controllers.Core.Exercises
                         return;
                     }
                 }
+
+                exerciseId = participation.ExerciseRelease.ExerciseId;
             }
 
 
-            var asset = await this.GetTestNormalOrSubmitTestAsset(testId, assetId, isSubmitTest);
+            var asset = await this._GetTestNormalOrSubmitTestAsset(testId, assetId, exerciseId, isSubmitTest);
 
             if (asset == null)
             {
                 //already handled
+                return;
             }
             else if (asset.Content == null)
             {
@@ -129,24 +165,28 @@ namespace ClientServer.Controllers.Core.Exercises
         /// </summary>
         /// <param name="testId">the test id</param>
         /// <param name="assetId">the asset id</param>
+        /// <param name="exerciseId"></param>
         /// <param name="isSubmitTest">true: submit test, false: not</param>
         /// <returns>the asset or null if not found or error</returns>
-        private async Task<TempTestAsset> GetTestNormalOrSubmitTestAsset(int testId, int assetId, bool isSubmitTest)
+        private async Task<TempTestAsset> _GetTestNormalOrSubmitTestAsset(int testId, int assetId, int exerciseId,
+            bool isSubmitTest)
         {
-            
             //ensure that this is the right asset (check testId too)
+            //calling method ensured that the user has access to the test
             var connection = await _context.TestWithFileAsAssetReferences
                 .Include(p => p.FileReferenceTestAsset)
-                .FirstOrDefaultAsync(p => p.TestId == testId && p.FileReferenceTestAssetId == assetId);
+                .FirstOrDefaultAsync(p => p.TestId == testId &&
+                                          p.Test.ExerciseId == exerciseId &&
+                                          p.FileReferenceTestAssetId == assetId);
 
-            if (connection== null)
+            if (connection == null)
             {
                 await
                     Response.WriteAsync(
                         Jc.Serialize(new BasicResponse(ResponseCode.NotFound, "asset reference connection not found")));
                 return null;
             }
-            
+
             if (connection.FileReferenceTestAsset == null)
             {
                 await
@@ -154,12 +194,12 @@ namespace ClientServer.Controllers.Core.Exercises
                         Jc.Serialize(new BasicResponse(ResponseCode.NotFound, "asset reference not found")));
                 return null;
             }
-            
+
             var testAssetsBasePath = Files.GetUploadFilePath(UploadDirType.TestAssets);
 
-            var testFilesDict = await Files.ReadUploadedFilesAsArray(testAssetsBasePath, connection.FileReferenceTestAsset.Id);
-            
-            
+            var testFilesDict =
+                await Files.ReadUploadedFilesAsArray(testAssetsBasePath, connection.FileReferenceTestAsset.Id);
+
 
             var fileName = "asset";
             if (Files.ValidFileName(connection.FileReferenceTestAsset.OriginalName))
@@ -170,7 +210,8 @@ namespace ClientServer.Controllers.Core.Exercises
             {
                 //just try to get a file extension...
 
-                var lastIndex = connection.FileReferenceTestAsset.OriginalName.LastIndexOf(".", StringComparison.Ordinal);
+                var lastIndex =
+                    connection.FileReferenceTestAsset.OriginalName.LastIndexOf(".", StringComparison.Ordinal);
                 if (lastIndex == -1)
                 {
                     //no file extension...
@@ -224,30 +265,33 @@ namespace ClientServer.Controllers.Core.Exercises
             var connection = await _context.CustomTestWithFileAsAssetReferences
                     .Include(p => p.FileReferenceUserFileAsset)
                     .FirstOrDefaultAsync(p =>
-                        p.CustomTestId == customTestId && p.CustomTest.UserId == userId &&
+                        p.CustomTestId == customTestId &&
+                        p.CustomTest.ExerciseReleaseId == participation.ExerciseReleaseId &&
+                        p.CustomTest.UserId == userId &&
                         p.FileReferenceUserFileAssetId == assetId)
                 ;
 
-            
+
             if (connection == null)
             {
                 Response.StatusCode = 406;
                 await
-                    Response.WriteAsync(Jc.Serialize(new BasicResponse(ResponseCode.NotFound, "asset connection not found")));
+                    Response.WriteAsync(
+                        Jc.Serialize(new BasicResponse(ResponseCode.NotFound, "asset connection not found")));
                 return;
             }
-            
+
             var testAsset = connection.FileReferenceUserFileAsset;
 
             if (testAsset == null)
             {
                 Response.StatusCode = 406;
                 await
-                    Response.WriteAsync(Jc.Serialize(new BasicResponse(ResponseCode.NotFound, "asset reference not found")));
+                    Response.WriteAsync(
+                        Jc.Serialize(new BasicResponse(ResponseCode.NotFound, "asset reference not found")));
                 return;
             }
 
-            
 
             var fileName = "asset";
             if (Files.ValidFileName(testAsset.OriginalName))
@@ -271,8 +315,8 @@ namespace ClientServer.Controllers.Core.Exercises
                 }
             }
 
-            var filesIdsToRead = new int[] { connection.FileReferenceUserFileAssetId};
-            
+            var filesIdsToRead = new int[] {connection.FileReferenceUserFileAssetId};
+
             var basePath = Files.GetUploadFilePath(UploadDirType.UserAssets);
 
             var filesDict = await Files.ReadUploadedFilesAsArray(basePath, filesIdsToRead);
@@ -282,22 +326,22 @@ namespace ClientServer.Controllers.Core.Exercises
             if (content == null)
             {
                 await
-                    Response.WriteAsync(Jc.Serialize(new BasicResponse(ResponseCode.NotFound, "asset content not found")));
+                    Response.WriteAsync(
+                        Jc.Serialize(new BasicResponse(ResponseCode.NotFound, "asset content not found")));
                 return;
             }
-            
+
             //see https://stackoverflow.com/questions/20508788/do-i-need-content-type-application-octet-stream-for-file-download
             Response.ContentType = "application/octet-stream"; //overwrite global json response
             Response.Headers.Add(new KeyValuePair<string, StringValues>("Content-Disposition",
                 "attachment; filename=\"" + fileName + "\""));
 
-          
 
             await Response.Body.WriteAsync(content, 0, content.Length);
             await Response.Body.FlushAsync();
         }
 
-        
+
         /// <summary>
         /// gets (downloads) the custom project custom test asset
         /// </summary>
@@ -311,7 +355,7 @@ namespace ClientServer.Controllers.Core.Exercises
             if (!await base.IsLoggedIn(null, false, false)) return;
 
             int userId = GetUserId();
-            
+
             var customProject = await _context.CustomProjects
                     .FirstOrDefaultAsync(p => p.UserId == userId && //just ensure the project is from the current user
                                               p.Id == customProjectId)
@@ -324,9 +368,8 @@ namespace ClientServer.Controllers.Core.Exercises
                         Jc.Serialize(new BasicResponse(ResponseCode.NotFound, "custom project not found")));
                 return;
             }
-            
 
-            
+
             var oldTest = await _context.CustomProjectTests
                     .Where(p =>
                         p.Id == customTestId && p.CustomProjectId == customProjectId)
@@ -340,35 +383,37 @@ namespace ClientServer.Controllers.Core.Exercises
                         Jc.Serialize(new BasicResponse(ResponseCode.NotFound, "test not found")));
                 return;
             }
-            
-            
-             var connection = await _context.CustomProjectTestWithFileAsAssetReferences
+
+
+            var connection = await _context.CustomProjectTestWithFileAsAssetReferences
                     .Include(p => p.FileReferenceUserFileAsset)
                     .FirstOrDefaultAsync(p =>
-                        p.CustomProjectTestId == customTestId && p.CustomProjectTest.CustomProjectId == customProject.Id &&
+                        p.CustomProjectTestId == customTestId &&
+                        p.CustomProjectTest.CustomProjectId == customProject.Id &&
                         p.FileReferenceUserFileAssetId == assetId)
                 ;
 
-            
+
             if (connection == null)
             {
                 Response.StatusCode = 406;
                 await
-                    Response.WriteAsync(Jc.Serialize(new BasicResponse(ResponseCode.NotFound, "asset connection not found")));
+                    Response.WriteAsync(
+                        Jc.Serialize(new BasicResponse(ResponseCode.NotFound, "asset connection not found")));
                 return;
             }
-            
+
             var testAsset = connection.FileReferenceUserFileAsset;
 
             if (testAsset == null)
             {
                 Response.StatusCode = 406;
                 await
-                    Response.WriteAsync(Jc.Serialize(new BasicResponse(ResponseCode.NotFound, "asset reference not found")));
+                    Response.WriteAsync(
+                        Jc.Serialize(new BasicResponse(ResponseCode.NotFound, "asset reference not found")));
                 return;
             }
 
-            
 
             var fileName = "asset";
             if (Files.ValidFileName(testAsset.OriginalName))
@@ -392,8 +437,8 @@ namespace ClientServer.Controllers.Core.Exercises
                 }
             }
 
-            var filesIdsToRead = new int[] { connection.FileReferenceUserFileAssetId};
-            
+            var filesIdsToRead = new int[] {connection.FileReferenceUserFileAssetId};
+
             var basePath = Files.GetUploadFilePath(UploadDirType.UserAssets);
 
             var filesDict = await Files.ReadUploadedFilesAsArray(basePath, filesIdsToRead);
@@ -403,20 +448,19 @@ namespace ClientServer.Controllers.Core.Exercises
             if (content == null)
             {
                 await
-                    Response.WriteAsync(Jc.Serialize(new BasicResponse(ResponseCode.NotFound, "asset content not found")));
+                    Response.WriteAsync(
+                        Jc.Serialize(new BasicResponse(ResponseCode.NotFound, "asset content not found")));
                 return;
             }
-            
+
             //see https://stackoverflow.com/questions/20508788/do-i-need-content-type-application-octet-stream-for-file-download
             Response.ContentType = "application/octet-stream"; //overwrite global json response
             Response.Headers.Add(new KeyValuePair<string, StringValues>("Content-Disposition",
                 "attachment; filename=\"" + fileName + "\""));
 
-          
 
             await Response.Body.WriteAsync(content, 0, content.Length);
             await Response.Body.FlushAsync();
-            
         }
 
         /// <summary>
@@ -426,14 +470,15 @@ namespace ClientServer.Controllers.Core.Exercises
         /// <param name="testId">the test id</param>
         /// <param name="assetId">the asset reference id</param>
         [HttpGet("editor/{exerciseId}/{testId}/{assetId}")]
-        public async Task GetTestAssetWithoutReleaseCode(int exerciseId, int testId, int assetId)
+        public async Task GetExerciseEditorTestAssetWithoutReleaseCode(int exerciseId, int testId, int assetId)
         {
             if (!await base.IsLoggedIn(null, false, false)) return;
 
             int userId = GetUserId();
 
             int managingGroupId = await _context.Exercises
-                .Where(p => p.Id == exerciseId).Select(p => p.UserGroupId)
+                .Where(p => p.Id == exerciseId)
+                .Select(p => p.UserGroupId)
                 .FirstOrDefaultAsync();
 
             if (managingGroupId == default(int))
@@ -447,6 +492,7 @@ namespace ClientServer.Controllers.Core.Exercises
 
             //the user group that WILL manages the exercise (after the change)
             var targetUserGroup = await _context.UserGroups.FirstOrDefaultAsync(p => p.Id == managingGroupId);
+            
             if (targetUserGroup == null)
             {
                 Response.StatusCode = 406;
@@ -475,17 +521,19 @@ namespace ClientServer.Controllers.Core.Exercises
             //ensure that this is the right asset (check testId too)
             var connection = await _context.TestWithFileAsAssetReferences
                 .Include(p => p.FileReferenceTestAsset)
-                .FirstOrDefaultAsync(p => p.TestId == testId && p.FileReferenceTestAssetId == assetId);
+                .FirstOrDefaultAsync(p => p.TestId == testId && 
+                                          p.Test.ExerciseId == exerciseId &&
+                                          p.FileReferenceTestAssetId == assetId);
 
 
-            if (connection== null)
+            if (connection == null)
             {
                 await
                     Response.WriteAsync(
                         Jc.Serialize(new BasicResponse(ResponseCode.NotFound, "asset reference connection not found")));
                 return;
             }
-            
+
             if (connection.FileReferenceTestAsset == null)
             {
                 await
@@ -493,10 +541,11 @@ namespace ClientServer.Controllers.Core.Exercises
                         Jc.Serialize(new BasicResponse(ResponseCode.NotFound, "asset reference not found")));
                 return;
             }
-            
+
             var testAssetsBasePath = Files.GetUploadFilePath(UploadDirType.TestAssets);
 
-            var testFilesDict = await Files.ReadUploadedFilesAsArray(testAssetsBasePath, connection.FileReferenceTestAsset.Id);
+            var testFilesDict =
+                await Files.ReadUploadedFilesAsArray(testAssetsBasePath, connection.FileReferenceTestAsset.Id);
 
 
             var fileName = "asset";
@@ -508,7 +557,8 @@ namespace ClientServer.Controllers.Core.Exercises
             {
                 //just try to get a file extension...
 
-                var lastIndex = connection.FileReferenceTestAsset.OriginalName.LastIndexOf(".", StringComparison.Ordinal);
+                var lastIndex =
+                    connection.FileReferenceTestAsset.OriginalName.LastIndexOf(".", StringComparison.Ordinal);
                 if (lastIndex == -1)
                 {
                     //no file extension...
@@ -539,14 +589,17 @@ namespace ClientServer.Controllers.Core.Exercises
     internal class TempTestAsset
     {
         public int Id { get; set; }
+
         /// <summary>
         /// the name of the file/asset
         /// </summary>
         public string DisplayName { get; set; }
+
         /// <summary>
         /// the content of the asset (binary)
         /// </summary>
         public byte[] Content { get; set; }
+
         /// <summary>
         /// the mime type (maybe we need to know what content is stored)
         /// </summary>