MetadataController.cs 9.38 KB
Newer Older
1
2
3
4
5
6
7
8
9
10
11
12
13
using Coscine.Api.Project.Models;
using Coscine.ApiCommons;
using Coscine.ApiCommons.Exceptions;
using Coscine.ApiCommons.Factories;
using Microsoft.AspNetCore.Mvc;
using Newtonsoft.Json.Linq;
using System;
using System.Linq;
using VDS.RDF.Writing;
using VDS.RDF.Parsing;
using VDS.RDF;
using Metadata;
using System.Web;
14
using Microsoft.AspNetCore.Authorization;
15
16
17

namespace Coscine.Api.Project.Controllers
{
18
19

    [Authorize]
20
21
22
23
24
    public class MetadataController : Controller
    {
        private readonly Authenticator _authenticator;
        private readonly MetadataModel _metadataModel;
        private readonly ResourceModel _resourceModel;
25
        private readonly ProjectModel _projectModel;
26
27
28
29
30
31
32
        private readonly Util _util;

        public MetadataController()
        {
            _authenticator = new Authenticator(this, Program.Configuration);
            _metadataModel = new MetadataModel();
            _resourceModel = new ResourceModel();
33
            _projectModel = new ProjectModel();
34
35
36
37
38
39
            _util = new Util();
        }

        [Route("[controller]")]
        public IActionResult Index()
        {
40
            return NoContent();
41
42
        }

43
44
45
46
        // returns the basic application profile
        [HttpGet("[controller]/resource/{projectId}/ap/{applicationProfileId}")]
        public IActionResult GetApplicationProfile(Guid projectId, string applicationProfileId)
        {
47
            var user = _authenticator.GetUser();
48

49
            if (_projectModel.HasAccess(user, _projectModel.GetById(projectId), UserRoles.Owner, UserRoles.Member))
50
51
52
53
54
            {
                var graph = _util.GetGraph(HttpUtility.UrlDecode(applicationProfileId));                

                var json = JToken.Parse(VDS.RDF.Writing.StringWriter.Write(graph, new RdfJsonWriter()));
                
55
                return Json(json);
56
57
58
59
60
61
62
63
64
65
66
            }
            else
            {
                throw new NotAuthorizedException("User is no project member!");
            }

        }

        // returns the application profile with the fixed values
        [HttpGet("[controller]/resource/{resourceId}/apc/{applicationProfileId}")]
        public IActionResult GetApplicationProfileComplete(string resourceId, string applicationProfileId)
67
        {
68
            var user = _authenticator.GetUser();
69
70

            var resource = _resourceModel.GetById(Guid.Parse(resourceId));
71
            if (_resourceModel.HasAccess(user, resource, UserRoles.Owner, UserRoles.Member) && applicationProfileId != null)
72
73
74
75
76
77
78
79
80
            {
                var graph = _util.GetGraph(HttpUtility.UrlDecode(applicationProfileId));
                var fixedValuesGraph = new Graph();

                fixedValuesGraph.LoadFromString(resource.FixedValues, new RdfJsonParser());

                graph.Merge(fixedValuesGraph);

                var json = JToken.Parse(VDS.RDF.Writing.StringWriter.Write(graph, new RdfJsonWriter()));
81

82
83
84
85
86
87
88
89
90
                return Ok(json);
            }
            else
            {
                throw new NotAuthorizedException("User is no project member!");
            }

        }

91
92
        [HttpGet("[controller]/project/{projectId}/aplist/")]
        public IActionResult ListAllApplicationProfiles(Guid projectId)
93
        {
94
95
            var user = _authenticator.GetUser();
            if (_projectModel.HasAccess(user, _projectModel.GetById(projectId), UserRoles.Owner, UserRoles.Member))
96
            {
97
                var graphUris = _util.ListGraphs();
98

99
100
101
102
103
104
                return Json(new JArray(graphUris.Select(x => x.ToString()).Where(x => x.StartsWith("https://purl.org/coscine/ap/"))));
            }
            else
            {
                throw new NotAuthorizedException("User is no project member!");
            }
105
106
107
108
109
        }

        [HttpGet("[controller]/resource/{resourceId}/filename/{filename}/ver/{version}")]
        public IActionResult GetMetadataForFile(string resourceId, string filename, string version)
        {
110
111
112
            var user = _authenticator.GetUser();
            var resource = _resourceModel.GetById(Guid.Parse(resourceId));
            if (_resourceModel.HasAccess(user, resource, UserRoles.Owner, UserRoles.Member))
113
            {
114
                var id = _metadataModel.GenerateId(resourceId, filename, version);
115
116
                var uri = _metadataModel.CreateUri(id);
                var graph = _util.GetGraph(uri);
117
118
119
120
121
122
                return Json(JToken.Parse(VDS.RDF.Writing.StringWriter.Write(graph, new RdfJsonWriter())).ToString());
            }
            else
            {
                throw new NotAuthorizedException("User is no project member!");
            }
123
124
125
126
127
        }

        [HttpPut("[controller]/resource/{resourceId}/filename/{filename}/ver/{version}")]
        public IActionResult StoreMetadataForFile(string resourceId, string filename, string version)
        {
128
129
            var innerBlock = ObjectFactory<JToken>.DeserializeFromStream(Request.Body);
            var graphName = _metadataModel.GenerateId(resourceId, filename, version);
130
            var graphNameUri = _metadataModel.CreateUri(graphName);
131
            var json = new JObject
132
            {
133
134
135
136
137
138
139
140
141
                [graphName] = innerBlock
            };

            var user = _authenticator.GetUser();
            var resource = _resourceModel.GetById(Guid.Parse(resourceId));
                
            if (_resourceModel.HasAccess(user, resource, UserRoles.Owner, UserRoles.Member))
            {
                json[graphName]["http://www.w3.org/1999/02/22-rdf-syntax-ns#type"] = new JArray
142
                {
143
144
145
146
147
                    new JObject
                    {
                        ["value"] = resource.ApplicationProfile.Substring(0, resource.ApplicationProfile.Length-1),
                        ["type"] = "uri"
                    }
148
                };
149
150
151
                // throw bad request if empty node value is detected
                JToken root = json.First.First;
                foreach (var node in root)
152
                {
153
154
155
156
157
158
                    string nodeValue = node.First.First["value"].ToString().ToLower();
                    if (String.IsNullOrEmpty(nodeValue))
                    {
                        throw new ArgumentException("Empty values in application profile are not accepted.");
                    }
                }
159

160
161
                var graph = new Graph();
                graph.LoadFromString(json.ToString(), new RdfJsonParser());
162

163
164
165
166
167
168
169
                var fixedValuesGraph = new Graph();
                fixedValuesGraph.LoadFromString(resource.FixedValues, new RdfJsonParser());

                foreach(var triple in fixedValuesGraph.Triples.Where(x => x.Predicate.ToString() == "https://purl.org/coscine/fixedValue"))
                {
                    // Remove any existing triples
                    foreach (var triple2 in graph.GetTriplesWithSubjectPredicate(graph.CreateUriNode(graphNameUri), triple.Subject).ToList())
170
                    {
171
                        graph.Retract(triple2);
172
                    }
173
174
                    graph.Assert(graph.CreateUriNode(graphNameUri), triple.Subject, triple.Object);
                }
175

176
                // Default values is not checked or added
177

178
179
180
181
182
                // validate the data
                if (_util.ValidateShacl(graph, graphNameUri))
                {
                    // store the data
                    if (_util.HasGraph(graphNameUri))
183
                    {
184
                        _util.ClearGraph(graphNameUri);
185
186
187
                    }
                    else
                    {
188
                        _util.CreateNamedGraph(graphNameUri);
189
190
                    }

191
192
193
194
195
                    // BaseUri must be set for the sparql query
                    graph.BaseUri = graphNameUri;
                    _util.AddGraph(graph);

                    return NoContent();
196
197
198
                }
                else
                {
199
                    throw new NotAuthorizedException("Data has the wrong format!");
200
                }
201
202
203
204
205
206

            }
            else
            {
                throw new NotAuthorizedException("User is no project member!");
            }
207
208
        }

209
210
        [HttpGet("[controller]/vocabulary/{projectId}/{path}")]
        public IActionResult GetVocabulary(Guid projectId, string path)
211
        {
212
213
            var user = _authenticator.GetUser();
            if (_projectModel.HasAccess(user, _projectModel.GetById(projectId), UserRoles.Owner, UserRoles.Member))
214
            {
215
                var graph = _util.GetGraph(HttpUtility.UrlDecode(path));
216

217
218
219
220
                var de = new JArray();
                foreach (var kv in _util.GetVocabularyLabels(graph, "de"))
                {
                    JObject obj = new JObject
221
                    {
222
223
224
225
226
                        ["value"] = kv.Key,
                        ["name"] = kv.Value
                    };
                    de.Add(obj);
                }
227

228
229
230
231
                var en = new JArray();
                foreach(var kv in _util.GetVocabularyLabels(graph, "en"))
                {
                    JObject obj = new JObject
232
                    {
233
234
                        ["value"] = kv.Key,
                        ["name"] = kv.Value
235
                    };
236
                    en.Add(obj);
237
                }
238
239

                JObject json = new JObject
240
                {
241
242
243
244
245
246
247
248
249
250
                    ["de"] = de,
                    ["en"] = en
                };

                return Json(json);
            }
            else
            {
                throw new NotAuthorizedException("User is no project member!");
            }
251
252
253
254
        }

    }
}