eyeling 1.14.13 → 1.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/examples/check/input/deep-taxonomy-100000.c +20 -0
- package/examples/check/input/gps.c +127 -0
- package/examples/check/input/high-trust-rdf-bloom-envelope.c +148 -0
- package/examples/check/input/high-trust-rdf-bloom-tamper-contrast.c +247 -0
- package/examples/check/input/odrl-dpv-risk-ranked.c +275 -0
- package/examples/check/output/deep-taxonomy-100000.n3 +300004 -0
- package/examples/check/output/gps.n3 +6 -0
- package/examples/check/output/high-trust-rdf-bloom-envelope.n3 +7 -0
- package/examples/check/output/high-trust-rdf-bloom-tamper-contrast.n3 +27 -0
- package/examples/check/output/odrl-dpv-risk-ranked.n3 +13 -0
- package/examples/decimal-ebike-motor-thermal-envelope.n3 +286 -0
- package/examples/decimal-transcendental-servo-envelope.n3 +197 -0
- package/examples/deck/high-trust-rdf-bloom-envelope.md +371 -0
- package/examples/deck/schema-foaf-mapping.md +3 -1
- package/examples/high-trust-rdf-bloom-envelope.n3 +281 -0
- package/examples/high-trust-rdf-bloom-tamper-contrast.n3 +395 -0
- package/examples/integer-first-control-tank-level.n3 +209 -0
- package/examples/integer-first-sqrt2-mediants.n3 +174 -0
- package/examples/output/decimal-ebike-motor-thermal-envelope.n3 +25 -0
- package/examples/output/decimal-transcendental-servo-envelope.n3 +29 -0
- package/examples/output/high-trust-rdf-bloom-envelope.n3 +7 -0
- package/examples/output/high-trust-rdf-bloom-tamper-contrast.n3 +27 -0
- package/examples/output/integer-first-control-tank-level.n3 +70 -0
- package/examples/output/integer-first-sqrt2-mediants.n3 +57 -0
- package/eyeling.js +90 -1
- package/lib/lexer.js +90 -1
- package/package.json +3 -2
- package/test/api.test.js +221 -0
- package/test/check.test.js +174 -0
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
#include <stdbool.h>
|
|
2
|
+
#include <stdio.h>
|
|
3
|
+
#include <stdlib.h>
|
|
4
|
+
#include <string.h>
|
|
5
|
+
|
|
6
|
+
#define ARRAY_LEN(x) (sizeof(x) / sizeof((x)[0]))
|
|
7
|
+
|
|
8
|
+
static const char *PREFIX_LINE_1 = "@prefix : <https://example.org/odrl-dpv-risk-ranked#> .\n";
|
|
9
|
+
static const char *PREFIX_LINE_2 = "@prefix log: <http://www.w3.org/2000/10/swap/log#> .\n\n";
|
|
10
|
+
|
|
11
|
+
typedef struct {
|
|
12
|
+
const char *id;
|
|
13
|
+
int importance;
|
|
14
|
+
int minNoticeDays;
|
|
15
|
+
} Need;
|
|
16
|
+
|
|
17
|
+
typedef struct {
|
|
18
|
+
const char *id;
|
|
19
|
+
const char *text;
|
|
20
|
+
const char *action;
|
|
21
|
+
bool hasNoticeConstraint;
|
|
22
|
+
bool hasInformDuty;
|
|
23
|
+
int noticeDays;
|
|
24
|
+
bool hasConsentConstraint;
|
|
25
|
+
bool isProhibition;
|
|
26
|
+
} Clause;
|
|
27
|
+
|
|
28
|
+
typedef struct {
|
|
29
|
+
const char *riskId;
|
|
30
|
+
const char *mitigationIds[2];
|
|
31
|
+
size_t mitigationCount;
|
|
32
|
+
const char *clauseId;
|
|
33
|
+
const char *description;
|
|
34
|
+
const char *level;
|
|
35
|
+
const char *severity;
|
|
36
|
+
int score;
|
|
37
|
+
int inverseScore;
|
|
38
|
+
const char *mitigationText[2];
|
|
39
|
+
} RankedRisk;
|
|
40
|
+
|
|
41
|
+
static int compare_ranked_risks(const void *lhs, const void *rhs) {
|
|
42
|
+
const RankedRisk *a = (const RankedRisk *)lhs;
|
|
43
|
+
const RankedRisk *b = (const RankedRisk *)rhs;
|
|
44
|
+
|
|
45
|
+
if (a->inverseScore != b->inverseScore) {
|
|
46
|
+
return a->inverseScore - b->inverseScore;
|
|
47
|
+
}
|
|
48
|
+
return strcmp(a->clauseId, b->clauseId);
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
static int capped_score(int raw) {
|
|
52
|
+
return raw > 100 ? 100 : raw;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
static void add_delete_account_risk(const Clause *clause, const Need *need, RankedRisk *out, size_t *count) {
|
|
56
|
+
if (strcmp(clause->action, "removeAccount") != 0) {
|
|
57
|
+
return;
|
|
58
|
+
}
|
|
59
|
+
if (clause->hasNoticeConstraint || clause->hasInformDuty) {
|
|
60
|
+
return;
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
RankedRisk risk;
|
|
64
|
+
memset(&risk, 0, sizeof(risk));
|
|
65
|
+
risk.riskId = "_:sk_1";
|
|
66
|
+
risk.mitigationIds[0] = "_:sk_2";
|
|
67
|
+
risk.mitigationIds[1] = "_:sk_4";
|
|
68
|
+
risk.mitigationCount = 2;
|
|
69
|
+
risk.clauseId = clause->id;
|
|
70
|
+
risk.score = capped_score(90 + need->importance);
|
|
71
|
+
risk.inverseScore = 1000 - risk.score;
|
|
72
|
+
risk.level = "https://w3id.org/dpv/risk#HighRisk";
|
|
73
|
+
risk.severity = "https://w3id.org/dpv/risk#HighSeverity";
|
|
74
|
+
risk.description =
|
|
75
|
+
"Risk: account/data removal is permitted without notice safeguards "
|
|
76
|
+
"(no notice constraint and no duty to inform). Clause C1: Provider may remove "
|
|
77
|
+
"the user account (and associated data) at its discretion.";
|
|
78
|
+
risk.mitigationText[0] = "Add a notice constraint (minimum noticeDays) before account removal.";
|
|
79
|
+
risk.mitigationText[1] = "Add a duty to inform the consumer prior to account removal.";
|
|
80
|
+
out[(*count)++] = risk;
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
static void add_notice_too_short_risk(const Clause *clause, const Need *need, RankedRisk *out, size_t *count) {
|
|
84
|
+
if (strcmp(clause->action, "changeTerms") != 0) {
|
|
85
|
+
return;
|
|
86
|
+
}
|
|
87
|
+
if (!clause->hasInformDuty) {
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (!(clause->noticeDays < need->minNoticeDays)) {
|
|
91
|
+
return;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
RankedRisk risk;
|
|
95
|
+
memset(&risk, 0, sizeof(risk));
|
|
96
|
+
risk.riskId = "_:sk_7";
|
|
97
|
+
risk.mitigationIds[0] = "_:sk_8";
|
|
98
|
+
risk.mitigationCount = 1;
|
|
99
|
+
risk.clauseId = clause->id;
|
|
100
|
+
risk.score = capped_score(70 + need->importance);
|
|
101
|
+
risk.inverseScore = 1000 - risk.score;
|
|
102
|
+
risk.level = "https://w3id.org/dpv/risk#HighRisk";
|
|
103
|
+
risk.severity = "https://w3id.org/dpv/risk#HighSeverity";
|
|
104
|
+
risk.description =
|
|
105
|
+
"Risk: terms may change with notice (3 days) below consumer requirement (14 days). "
|
|
106
|
+
"Clause C2: Provider may change terms by informing users at least 3 days in advance.";
|
|
107
|
+
risk.mitigationText[0] = "Increase minimum noticeDays in the inform duty to meet the consumer requirement.";
|
|
108
|
+
out[(*count)++] = risk;
|
|
109
|
+
}
|
|
110
|
+
|
|
111
|
+
static void add_share_no_consent_risk(const Clause *clause, const Need *need, RankedRisk *out, size_t *count) {
|
|
112
|
+
if (strcmp(clause->action, "shareData") != 0) {
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (clause->hasConsentConstraint) {
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
RankedRisk risk;
|
|
120
|
+
memset(&risk, 0, sizeof(risk));
|
|
121
|
+
risk.riskId = "_:sk_12";
|
|
122
|
+
risk.mitigationIds[0] = "_:sk_13";
|
|
123
|
+
risk.mitigationCount = 1;
|
|
124
|
+
risk.clauseId = clause->id;
|
|
125
|
+
risk.score = capped_score(85 + need->importance);
|
|
126
|
+
risk.inverseScore = 1000 - risk.score;
|
|
127
|
+
risk.level = "https://w3id.org/dpv/risk#HighRisk";
|
|
128
|
+
risk.severity = "https://w3id.org/dpv/risk#HighSeverity";
|
|
129
|
+
risk.description =
|
|
130
|
+
"Risk: user data sharing is permitted without an explicit consent constraint. "
|
|
131
|
+
"Clause C3: Provider may share user data with partners for business purposes.";
|
|
132
|
+
risk.mitigationText[0] = "Add an explicit consent constraint before data sharing.";
|
|
133
|
+
out[(*count)++] = risk;
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
static void add_no_portability_risk(const Clause *clause, const Need *need, RankedRisk *out, size_t *count) {
|
|
137
|
+
if (!clause->isProhibition || strcmp(clause->action, "exportData") != 0) {
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
|
|
141
|
+
RankedRisk risk;
|
|
142
|
+
memset(&risk, 0, sizeof(risk));
|
|
143
|
+
risk.riskId = "_:sk_16";
|
|
144
|
+
risk.mitigationIds[0] = "_:sk_17";
|
|
145
|
+
risk.mitigationCount = 1;
|
|
146
|
+
risk.clauseId = clause->id;
|
|
147
|
+
risk.score = capped_score(60 + need->importance);
|
|
148
|
+
risk.inverseScore = 1000 - risk.score;
|
|
149
|
+
risk.level = "https://w3id.org/dpv/risk#ModerateRisk";
|
|
150
|
+
risk.severity = "https://w3id.org/dpv/risk#ModerateSeverity";
|
|
151
|
+
risk.description =
|
|
152
|
+
"Risk: portability is restricted because exporting user data is prohibited. "
|
|
153
|
+
"Clause C4: Users are not permitted to export their data.";
|
|
154
|
+
risk.mitigationText[0] = "Add a permission allowing data export (or remove the prohibition) to support portability.";
|
|
155
|
+
out[(*count)++] = risk;
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
static void print_header(void) {
|
|
159
|
+
printf("(:Agreement1 :ConsumerExample 0) log:outputString ");
|
|
160
|
+
printf("\"\\n=== Ranked DPV Risk Report ===\\nAgreement: Example Agreement\\nProfile: Example consumer profile\\n\\n\" .\n");
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
static void print_risk_line(const RankedRisk *risk) {
|
|
164
|
+
printf("(:Agreement1 :ConsumerExample 1 %d \"%s\" 0 %s) log:outputString ",
|
|
165
|
+
risk->inverseScore,
|
|
166
|
+
risk->clauseId,
|
|
167
|
+
risk->riskId);
|
|
168
|
+
printf("\"score=%d (%s, %s) clause %s\\n %s\\n\\n\" .\n",
|
|
169
|
+
risk->score,
|
|
170
|
+
risk->level,
|
|
171
|
+
risk->severity,
|
|
172
|
+
risk->clauseId,
|
|
173
|
+
risk->description);
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
static void print_mitigation_lines(const RankedRisk *risk) {
|
|
177
|
+
for (size_t i = 0; i < risk->mitigationCount; ++i) {
|
|
178
|
+
printf("(:Agreement1 :ConsumerExample 1 %d \"%s\" 1 %s %s) log:outputString ",
|
|
179
|
+
risk->inverseScore,
|
|
180
|
+
risk->clauseId,
|
|
181
|
+
risk->riskId,
|
|
182
|
+
risk->mitigationIds[i]);
|
|
183
|
+
printf("\" - mitigation for clause %s: %s\\n\" .\n",
|
|
184
|
+
risk->clauseId,
|
|
185
|
+
risk->mitigationText[i]);
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
|
|
189
|
+
int main(void) {
|
|
190
|
+
const Need needDataCannotBeRemoved = {
|
|
191
|
+
.id = "Need_DataCannotBeRemoved",
|
|
192
|
+
.importance = 20,
|
|
193
|
+
.minNoticeDays = 0
|
|
194
|
+
};
|
|
195
|
+
const Need needChangeOnlyWithPriorNotice = {
|
|
196
|
+
.id = "Need_ChangeOnlyWithPriorNotice",
|
|
197
|
+
.importance = 15,
|
|
198
|
+
.minNoticeDays = 14
|
|
199
|
+
};
|
|
200
|
+
const Need needNoSharingWithoutConsent = {
|
|
201
|
+
.id = "Need_NoSharingWithoutConsent",
|
|
202
|
+
.importance = 12,
|
|
203
|
+
.minNoticeDays = 0
|
|
204
|
+
};
|
|
205
|
+
const Need needDataPortability = {
|
|
206
|
+
.id = "Need_DataPortability",
|
|
207
|
+
.importance = 10,
|
|
208
|
+
.minNoticeDays = 0
|
|
209
|
+
};
|
|
210
|
+
|
|
211
|
+
const Clause clauses[] = {
|
|
212
|
+
{
|
|
213
|
+
.id = "C1",
|
|
214
|
+
.text = "Provider may remove the user account (and associated data) at its discretion.",
|
|
215
|
+
.action = "removeAccount",
|
|
216
|
+
.hasNoticeConstraint = false,
|
|
217
|
+
.hasInformDuty = false,
|
|
218
|
+
.noticeDays = 0,
|
|
219
|
+
.hasConsentConstraint = false,
|
|
220
|
+
.isProhibition = false
|
|
221
|
+
},
|
|
222
|
+
{
|
|
223
|
+
.id = "C2",
|
|
224
|
+
.text = "Provider may change terms by informing users at least 3 days in advance.",
|
|
225
|
+
.action = "changeTerms",
|
|
226
|
+
.hasNoticeConstraint = true,
|
|
227
|
+
.hasInformDuty = true,
|
|
228
|
+
.noticeDays = 3,
|
|
229
|
+
.hasConsentConstraint = false,
|
|
230
|
+
.isProhibition = false
|
|
231
|
+
},
|
|
232
|
+
{
|
|
233
|
+
.id = "C3",
|
|
234
|
+
.text = "Provider may share user data with partners for business purposes.",
|
|
235
|
+
.action = "shareData",
|
|
236
|
+
.hasNoticeConstraint = false,
|
|
237
|
+
.hasInformDuty = false,
|
|
238
|
+
.noticeDays = 0,
|
|
239
|
+
.hasConsentConstraint = false,
|
|
240
|
+
.isProhibition = false
|
|
241
|
+
},
|
|
242
|
+
{
|
|
243
|
+
.id = "C4",
|
|
244
|
+
.text = "Users are not permitted to export their data.",
|
|
245
|
+
.action = "exportData",
|
|
246
|
+
.hasNoticeConstraint = false,
|
|
247
|
+
.hasInformDuty = false,
|
|
248
|
+
.noticeDays = 0,
|
|
249
|
+
.hasConsentConstraint = false,
|
|
250
|
+
.isProhibition = true
|
|
251
|
+
}
|
|
252
|
+
};
|
|
253
|
+
|
|
254
|
+
RankedRisk risks[8];
|
|
255
|
+
size_t riskCount = 0;
|
|
256
|
+
|
|
257
|
+
for (size_t i = 0; i < ARRAY_LEN(clauses); ++i) {
|
|
258
|
+
add_delete_account_risk(&clauses[i], &needDataCannotBeRemoved, risks, &riskCount);
|
|
259
|
+
add_notice_too_short_risk(&clauses[i], &needChangeOnlyWithPriorNotice, risks, &riskCount);
|
|
260
|
+
add_share_no_consent_risk(&clauses[i], &needNoSharingWithoutConsent, risks, &riskCount);
|
|
261
|
+
add_no_portability_risk(&clauses[i], &needDataPortability, risks, &riskCount);
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
qsort(risks, riskCount, sizeof(risks[0]), compare_ranked_risks);
|
|
265
|
+
|
|
266
|
+
fputs(PREFIX_LINE_1, stdout);
|
|
267
|
+
fputs(PREFIX_LINE_2, stdout);
|
|
268
|
+
print_header();
|
|
269
|
+
for (size_t i = 0; i < riskCount; ++i) {
|
|
270
|
+
print_risk_line(&risks[i]);
|
|
271
|
+
print_mitigation_lines(&risks[i]);
|
|
272
|
+
}
|
|
273
|
+
|
|
274
|
+
return 0;
|
|
275
|
+
}
|