Entitlements user interaction designs and proof of concept

entitlements.html 71KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851
  1. <?xml version="1.0" encoding="utf-8"?>
  2. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
  3. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
  4. <html xmlns="http://www.w3.org/1999/xhtml" lang="en" xml:lang="en">
  5. <head>
  6. <!-- 2018-04-20 Fri 16:44 -->
  7. <meta http-equiv="Content-Type" content="text/html;charset=utf-8" />
  8. <meta name="viewport" content="width=device-width, initial-scale=1" />
  9. <title>&lrm;</title>
  10. <meta name="generator" content="Org mode" />
  11. <meta name="author" content="Taco" />
  12. <style type="text/css">
  13. <!--/*--><![CDATA[/*><!--*/
  14. .title { text-align: center;
  15. margin-bottom: .2em; }
  16. .subtitle { text-align: center;
  17. font-size: medium;
  18. font-weight: bold;
  19. margin-top:0; }
  20. .todo { font-family: monospace; color: red; }
  21. .done { font-family: monospace; color: green; }
  22. .priority { font-family: monospace; color: orange; }
  23. .tag { background-color: #eee; font-family: monospace;
  24. padding: 2px; font-size: 80%; font-weight: normal; }
  25. .timestamp { color: #bebebe; }
  26. .timestamp-kwd { color: #5f9ea0; }
  27. .org-right { margin-left: auto; margin-right: 0px; text-align: right; }
  28. .org-left { margin-left: 0px; margin-right: auto; text-align: left; }
  29. .org-center { margin-left: auto; margin-right: auto; text-align: center; }
  30. .underline { text-decoration: underline; }
  31. #postamble p, #preamble p { font-size: 90%; margin: .2em; }
  32. p.verse { margin-left: 3%; }
  33. pre {
  34. border: 1px solid #ccc;
  35. box-shadow: 3px 3px 3px #eee;
  36. padding: 8pt;
  37. font-family: monospace;
  38. overflow: auto;
  39. margin: 1.2em;
  40. }
  41. pre.src {
  42. position: relative;
  43. overflow: visible;
  44. padding-top: 1.2em;
  45. }
  46. pre.src:before {
  47. display: none;
  48. position: absolute;
  49. background-color: white;
  50. top: -10px;
  51. right: 10px;
  52. padding: 3px;
  53. border: 1px solid black;
  54. }
  55. pre.src:hover:before { display: inline;}
  56. /* Languages per Org manual */
  57. pre.src-asymptote:before { content: 'Asymptote'; }
  58. pre.src-awk:before { content: 'Awk'; }
  59. pre.src-C:before { content: 'C'; }
  60. /* pre.src-C++ doesn't work in CSS */
  61. pre.src-clojure:before { content: 'Clojure'; }
  62. pre.src-css:before { content: 'CSS'; }
  63. pre.src-D:before { content: 'D'; }
  64. pre.src-ditaa:before { content: 'ditaa'; }
  65. pre.src-dot:before { content: 'Graphviz'; }
  66. pre.src-calc:before { content: 'Emacs Calc'; }
  67. pre.src-emacs-lisp:before { content: 'Emacs Lisp'; }
  68. pre.src-fortran:before { content: 'Fortran'; }
  69. pre.src-gnuplot:before { content: 'gnuplot'; }
  70. pre.src-haskell:before { content: 'Haskell'; }
  71. pre.src-hledger:before { content: 'hledger'; }
  72. pre.src-java:before { content: 'Java'; }
  73. pre.src-js:before { content: 'Javascript'; }
  74. pre.src-latex:before { content: 'LaTeX'; }
  75. pre.src-ledger:before { content: 'Ledger'; }
  76. pre.src-lisp:before { content: 'Lisp'; }
  77. pre.src-lilypond:before { content: 'Lilypond'; }
  78. pre.src-lua:before { content: 'Lua'; }
  79. pre.src-matlab:before { content: 'MATLAB'; }
  80. pre.src-mscgen:before { content: 'Mscgen'; }
  81. pre.src-ocaml:before { content: 'Objective Caml'; }
  82. pre.src-octave:before { content: 'Octave'; }
  83. pre.src-org:before { content: 'Org mode'; }
  84. pre.src-oz:before { content: 'OZ'; }
  85. pre.src-plantuml:before { content: 'Plantuml'; }
  86. pre.src-processing:before { content: 'Processing.js'; }
  87. pre.src-python:before { content: 'Python'; }
  88. pre.src-R:before { content: 'R'; }
  89. pre.src-ruby:before { content: 'Ruby'; }
  90. pre.src-sass:before { content: 'Sass'; }
  91. pre.src-scheme:before { content: 'Scheme'; }
  92. pre.src-screen:before { content: 'Gnu Screen'; }
  93. pre.src-sed:before { content: 'Sed'; }
  94. pre.src-sh:before { content: 'shell'; }
  95. pre.src-sql:before { content: 'SQL'; }
  96. pre.src-sqlite:before { content: 'SQLite'; }
  97. /* additional languages in org.el's org-babel-load-languages alist */
  98. pre.src-forth:before { content: 'Forth'; }
  99. pre.src-io:before { content: 'IO'; }
  100. pre.src-J:before { content: 'J'; }
  101. pre.src-makefile:before { content: 'Makefile'; }
  102. pre.src-maxima:before { content: 'Maxima'; }
  103. pre.src-perl:before { content: 'Perl'; }
  104. pre.src-picolisp:before { content: 'Pico Lisp'; }
  105. pre.src-scala:before { content: 'Scala'; }
  106. pre.src-shell:before { content: 'Shell Script'; }
  107. pre.src-ebnf2ps:before { content: 'ebfn2ps'; }
  108. /* additional language identifiers per "defun org-babel-execute"
  109. in ob-*.el */
  110. pre.src-cpp:before { content: 'C++'; }
  111. pre.src-abc:before { content: 'ABC'; }
  112. pre.src-coq:before { content: 'Coq'; }
  113. pre.src-groovy:before { content: 'Groovy'; }
  114. /* additional language identifiers from org-babel-shell-names in
  115. ob-shell.el: ob-shell is the only babel language using a lambda to put
  116. the execution function name together. */
  117. pre.src-bash:before { content: 'bash'; }
  118. pre.src-csh:before { content: 'csh'; }
  119. pre.src-ash:before { content: 'ash'; }
  120. pre.src-dash:before { content: 'dash'; }
  121. pre.src-ksh:before { content: 'ksh'; }
  122. pre.src-mksh:before { content: 'mksh'; }
  123. pre.src-posh:before { content: 'posh'; }
  124. /* Additional Emacs modes also supported by the LaTeX listings package */
  125. pre.src-ada:before { content: 'Ada'; }
  126. pre.src-asm:before { content: 'Assembler'; }
  127. pre.src-caml:before { content: 'Caml'; }
  128. pre.src-delphi:before { content: 'Delphi'; }
  129. pre.src-html:before { content: 'HTML'; }
  130. pre.src-idl:before { content: 'IDL'; }
  131. pre.src-mercury:before { content: 'Mercury'; }
  132. pre.src-metapost:before { content: 'MetaPost'; }
  133. pre.src-modula-2:before { content: 'Modula-2'; }
  134. pre.src-pascal:before { content: 'Pascal'; }
  135. pre.src-ps:before { content: 'PostScript'; }
  136. pre.src-prolog:before { content: 'Prolog'; }
  137. pre.src-simula:before { content: 'Simula'; }
  138. pre.src-tcl:before { content: 'tcl'; }
  139. pre.src-tex:before { content: 'TeX'; }
  140. pre.src-plain-tex:before { content: 'Plain TeX'; }
  141. pre.src-verilog:before { content: 'Verilog'; }
  142. pre.src-vhdl:before { content: 'VHDL'; }
  143. pre.src-xml:before { content: 'XML'; }
  144. pre.src-nxml:before { content: 'XML'; }
  145. /* add a generic configuration mode; LaTeX export needs an additional
  146. (add-to-list 'org-latex-listings-langs '(conf " ")) in .emacs */
  147. pre.src-conf:before { content: 'Configuration File'; }
  148. table { border-collapse:collapse; }
  149. caption.t-above { caption-side: top; }
  150. caption.t-bottom { caption-side: bottom; }
  151. td, th { vertical-align:top; }
  152. th.org-right { text-align: center; }
  153. th.org-left { text-align: center; }
  154. th.org-center { text-align: center; }
  155. td.org-right { text-align: right; }
  156. td.org-left { text-align: left; }
  157. td.org-center { text-align: center; }
  158. dt { font-weight: bold; }
  159. .footpara { display: inline; }
  160. .footdef { margin-bottom: 1em; }
  161. .figure { padding: 1em; }
  162. .figure p { text-align: center; }
  163. .inlinetask {
  164. padding: 10px;
  165. border: 2px solid gray;
  166. margin: 10px;
  167. background: #ffffcc;
  168. }
  169. #org-div-home-and-up
  170. { text-align: right; font-size: 70%; white-space: nowrap; }
  171. textarea { overflow-x: auto; }
  172. .linenr { font-size: smaller }
  173. .code-highlighted { background-color: #ffff00; }
  174. .org-info-js_info-navigation { border-style: none; }
  175. #org-info-js_console-label
  176. { font-size: 10px; font-weight: bold; white-space: nowrap; }
  177. .org-info-js_search-highlight
  178. { background-color: #ffff00; color: #000000; font-weight: bold; }
  179. .org-svg { width: 90%; }
  180. /*]]>*/-->
  181. </style>
  182. <link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/htmlize.css"/>
  183. <link rel="stylesheet" type="text/css" href="http://www.pirilampo.org/styles/readtheorg/css/readtheorg.css"/>
  184. <script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.3/jquery.min.js"></script>
  185. <script src="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.4/js/bootstrap.min.js"></script>
  186. <script type="text/javascript" src="http://www.pirilampo.org/styles/lib/js/jquery.stickytableheaders.js"></script>
  187. <script type="text/javascript" src="http://www.pirilampo.org/styles/readtheorg/js/readtheorg.js"></script>
  188. <script type="text/javascript">
  189. /*
  190. @licstart The following is the entire license notice for the
  191. JavaScript code in this tag.
  192. Copyright (C) 2012-2018 Free Software Foundation, Inc.
  193. The JavaScript code in this tag is free software: you can
  194. redistribute it and/or modify it under the terms of the GNU
  195. General Public License (GNU GPL) as published by the Free Software
  196. Foundation, either version 3 of the License, or (at your option)
  197. any later version. The code is distributed WITHOUT ANY WARRANTY;
  198. without even the implied warranty of MERCHANTABILITY or FITNESS
  199. FOR A PARTICULAR PURPOSE. See the GNU GPL for more details.
  200. As additional permission under GNU GPL version 3 section 7, you
  201. may distribute non-source (e.g., minimized or compacted) forms of
  202. that code without the copy of the GNU GPL normally required by
  203. section 4, provided you include this license notice and a URL
  204. through which recipients can access the Corresponding Source.
  205. @licend The above is the entire license notice
  206. for the JavaScript code in this tag.
  207. */
  208. <!--/*--><![CDATA[/*><!--*/
  209. function CodeHighlightOn(elem, id)
  210. {
  211. var target = document.getElementById(id);
  212. if(null != target) {
  213. elem.cacheClassElem = elem.className;
  214. elem.cacheClassTarget = target.className;
  215. target.className = "code-highlighted";
  216. elem.className = "code-highlighted";
  217. }
  218. }
  219. function CodeHighlightOff(elem, id)
  220. {
  221. var target = document.getElementById(id);
  222. if(elem.cacheClassElem)
  223. elem.className = elem.cacheClassElem;
  224. if(elem.cacheClassTarget)
  225. target.className = elem.cacheClassTarget;
  226. }
  227. /*]]>*///-->
  228. </script>
  229. </head>
  230. <body>
  231. <div id="content">
  232. <div id="table-of-contents">
  233. <h2>Table of Contents</h2>
  234. <div id="text-table-of-contents">
  235. <ul>
  236. <li><a href="#org800c3ea">1. Introduction</a>
  237. <ul>
  238. <li><a href="#org83f0357">1.1. Privacy levels</a></li>
  239. <li><a href="#org0298d43">1.2. Context types</a></li>
  240. <li><a href="#orgc4d3336">1.3. Properties</a></li>
  241. </ul>
  242. </li>
  243. <li><a href="#orgee237cb">2. Data Model</a>
  244. <ul>
  245. <li><a href="#orgcbd1b6a">2.1. Example wallet profile</a></li>
  246. <li><a href="#org1a632ec">2.2. profile generator</a></li>
  247. <li><a href="#org28f9f7f">2.3. Example request</a></li>
  248. <li><a href="#org452f82f">2.4. request generator</a></li>
  249. </ul>
  250. </li>
  251. <li><a href="#orgf51c7ba">3. Data Comparison</a></li>
  252. <li><a href="#org4d760b7">4. Visualization</a></li>
  253. <li><a href="#org34340c1">5. Interaction</a></li>
  254. </ul>
  255. </div>
  256. </div>
  257. <div class="figure">
  258. <p><img src="./Logo.png" alt="Logo.png" />
  259. </p>
  260. </div>
  261. <div id="outline-container-org800c3ea" class="outline-2">
  262. <h2 id="org800c3ea"><span class="section-number-2">1</span> Introduction</h2>
  263. <div class="outline-text-2" id="text-1">
  264. <p>
  265. The purpose of this document is to investigate possible User Interaction designs for Decode task 4.4.
  266. More specifically the focus is on investigating how the user of a decode wallet grants permission to decode application for a specific set of personal data.
  267. </p>
  268. </div>
  269. <div id="outline-container-org83f0357" class="outline-3">
  270. <h3 id="org83f0357"><span class="section-number-3">1.1</span> Privacy levels</h3>
  271. <div class="outline-text-3" id="text-1-1">
  272. <p>
  273. A prelimary definition of six privacy levels (ordered from most private to least private):
  274. </p>
  275. <table id="org94d16e6" border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
  276. <colgroup>
  277. <col class="org-right" />
  278. <col class="org-left" />
  279. <col class="org-left" />
  280. </colgroup>
  281. <thead>
  282. <tr>
  283. <th scope="col" class="org-right">id</th>
  284. <th scope="col" class="org-left">title</th>
  285. <th scope="col" class="org-left">description</th>
  286. </tr>
  287. </thead>
  288. <tbody>
  289. <tr>
  290. <td class="org-right">5</td>
  291. <td class="org-left">secret</td>
  292. <td class="org-left">proofs, passwords, keys etc.</td>
  293. </tr>
  294. <tr>
  295. <td class="org-right">4</td>
  296. <td class="org-left">private</td>
  297. <td class="org-left">ssn etc, strict need to know basis stuff</td>
  298. </tr>
  299. <tr>
  300. <td class="org-right">3</td>
  301. <td class="org-left">intimate</td>
  302. <td class="org-left">e.g. stuff you share with family</td>
  303. </tr>
  304. <tr>
  305. <td class="org-right">2</td>
  306. <td class="org-left">affiliate</td>
  307. <td class="org-left">e.g. stuff you share with work, project etc</td>
  308. </tr>
  309. <tr>
  310. <td class="org-right">1</td>
  311. <td class="org-left">public</td>
  312. <td class="org-left">e.g. stuff that everybody may know, your e.g. twitter handle</td>
  313. </tr>
  314. <tr>
  315. <td class="org-right">0</td>
  316. <td class="org-left">commons</td>
  317. <td class="org-left">stuff that is intended for the public good / commons, e.g. anonimized IoT stuff</td>
  318. </tr>
  319. </tbody>
  320. </table>
  321. </div>
  322. </div>
  323. <div id="outline-container-org0298d43" class="outline-3">
  324. <h3 id="org0298d43"><span class="section-number-3">1.2</span> Context types</h3>
  325. <div class="outline-text-3" id="text-1-2">
  326. <p>
  327. A preliminary definition of context types
  328. </p>
  329. <table id="orga454a98" border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
  330. <colgroup>
  331. <col class="org-right" />
  332. <col class="org-left" />
  333. <col class="org-left" />
  334. <col class="org-left" />
  335. </colgroup>
  336. <thead>
  337. <tr>
  338. <th scope="col" class="org-right">id</th>
  339. <th scope="col" class="org-left">title</th>
  340. <th scope="col" class="org-left">description</th>
  341. <th scope="col" class="org-left">generator</th>
  342. </tr>
  343. </thead>
  344. <tbody>
  345. <tr>
  346. <td class="org-right">0</td>
  347. <td class="org-left">personal</td>
  348. <td class="org-left">data that relates to your personal life, you can have different instances, for example friends, family etc.</td>
  349. <td class="org-left">Faker::Name.first<sub>name</sub></td>
  350. </tr>
  351. <tr>
  352. <td class="org-right">1</td>
  353. <td class="org-left">health</td>
  354. <td class="org-left">health data, you can define different instances (biosignals, stuff to share with dentist, gp, hospital etc)</td>
  355. <td class="org-left">['Dentist','Hospital','General Practicioner'].sample</td>
  356. </tr>
  357. <tr>
  358. <td class="org-right">2</td>
  359. <td class="org-left">education</td>
  360. <td class="org-left">school / educational data (grades, certificates etc)</td>
  361. <td class="org-left">Faker::University.name</td>
  362. </tr>
  363. <tr>
  364. <td class="org-right">3</td>
  365. <td class="org-left">work</td>
  366. <td class="org-left">stuff you share in a professional context</td>
  367. <td class="org-left">Faker::Company.name</td>
  368. </tr>
  369. <tr>
  370. <td class="org-right">4</td>
  371. <td class="org-left">hobby</td>
  372. <td class="org-left">stuff you share in the context of a pastime</td>
  373. <td class="org-left">[Faker::Music.instrument,Faker::ProgrammingLanguage.name, Faker::RockBand.name, Faker::Team.name].sample</td>
  374. </tr>
  375. <tr>
  376. <td class="org-right">5</td>
  377. <td class="org-left">financial</td>
  378. <td class="org-left">for data about mortgages, insurance, taxes etc.</td>
  379. <td class="org-left">['Mortgage', 'Insurance', 'Taxes'].sample</td>
  380. </tr>
  381. <tr>
  382. <td class="org-right">6</td>
  383. <td class="org-left">other</td>
  384. <td class="org-left">for everything that doesn't fit the above</td>
  385. <td class="org-left">Faker::StarWars.call<sub>sign</sub></td>
  386. </tr>
  387. </tbody>
  388. </table>
  389. </div>
  390. </div>
  391. <div id="outline-container-orgc4d3336" class="outline-3">
  392. <h3 id="orgc4d3336"><span class="section-number-3">1.3</span> Properties</h3>
  393. <div class="outline-text-3" id="text-1-3">
  394. <p>
  395. A list of properties with code to eval for fake instances, all properties from id 4 come from gebiedonline.
  396. We've made an inventory of the data that is related to a gebied online profile.
  397. The question arises what part of the data would theoretically go inside the wallet.
  398. This is for the application developer to decide, but we think it is sensible to develop some guidelines on this.
  399. For now we have tried to be as inclusive as possible, and put everything in the wallet.
  400. Properties that are very application specific have the 'go' (and not the 'decode') namespace.
  401. This is pretty speculative, but serves as a discussion starter.
  402. </p>
  403. <table id="org075a51c" border="2" cellspacing="0" cellpadding="6" rules="groups" frame="hsides">
  404. <colgroup>
  405. <col class="org-right" />
  406. <col class="org-left" />
  407. <col class="org-right" />
  408. <col class="org-left" />
  409. <col class="org-left" />
  410. </colgroup>
  411. <thead>
  412. <tr>
  413. <th scope="col" class="org-right">id</th>
  414. <th scope="col" class="org-left">title</th>
  415. <th scope="col" class="org-right">default<sub>privacy</sub><sub>level</sub></th>
  416. <th scope="col" class="org-left">description</th>
  417. <th scope="col" class="org-left">generator</th>
  418. </tr>
  419. </thead>
  420. <tbody>
  421. <tr>
  422. <td class="org-right">0</td>
  423. <td class="org-left">decode:name</td>
  424. <td class="org-right">2</td>
  425. <td class="org-left">full name</td>
  426. <td class="org-left">Faker::Name.name</td>
  427. </tr>
  428. <tr>
  429. <td class="org-right">1</td>
  430. <td class="org-left">decode:email</td>
  431. <td class="org-right">2</td>
  432. <td class="org-left">Email address</td>
  433. <td class="org-left">Faker::Internet.email</td>
  434. </tr>
  435. <tr>
  436. <td class="org-right">2</td>
  437. <td class="org-left">decode:address</td>
  438. <td class="org-right">2</td>
  439. <td class="org-left">Address</td>
  440. <td class="org-left">Faker::Address.street<sub>address</sub></td>
  441. </tr>
  442. <tr>
  443. <td class="org-right">3</td>
  444. <td class="org-left">decode:telephone</td>
  445. <td class="org-right">2</td>
  446. <td class="org-left">Telephone number</td>
  447. <td class="org-left">Faker::PhoneNumber.cell<sub>phone</sub></td>
  448. </tr>
  449. <tr>
  450. <td class="org-right">4</td>
  451. <td class="org-left">go:proof<sub>of</sub><sub>membership</sub></td>
  452. <td class="org-right">5</td>
  453. <td class="org-left">instead of the password that is used now</td>
  454. <td class="org-left">SecureRandom.hex</td>
  455. </tr>
  456. <tr>
  457. <td class="org-right">5</td>
  458. <td class="org-left">decode:first<sub>name</sub></td>
  459. <td class="org-right">2</td>
  460. <td class="org-left">first name</td>
  461. <td class="org-left">Faker::Name.first<sub>name</sub></td>
  462. </tr>
  463. <tr>
  464. <td class="org-right">6</td>
  465. <td class="org-left">decode:last<sub>name</sub></td>
  466. <td class="org-right">2</td>
  467. <td class="org-left">last name</td>
  468. <td class="org-left">Faker::Name.last<sub>name</sub></td>
  469. </tr>
  470. <tr>
  471. <td class="org-right">7</td>
  472. <td class="org-left">go:newsletter<sub>approval</sub></td>
  473. <td class="org-right">2</td>
  474. <td class="org-left">boolean</td>
  475. <td class="org-left">[true,false].sample</td>
  476. </tr>
  477. <tr>
  478. <td class="org-right">8</td>
  479. <td class="org-left">decode:profile<sub>picture</sub></td>
  480. <td class="org-right">2</td>
  481. <td class="org-left">profile picture</td>
  482. <td class="org-left">Faker::LoremPixel.image</td>
  483. </tr>
  484. <tr>
  485. <td class="org-right">9</td>
  486. <td class="org-left">decode:gender</td>
  487. <td class="org-right">3</td>
  488. <td class="org-left">gender</td>
  489. <td class="org-left">Faker::Demographic.marital<sub>status</sub></td>
  490. </tr>
  491. <tr>
  492. <td class="org-right">10</td>
  493. <td class="org-left">decode:birthdate</td>
  494. <td class="org-right">3</td>
  495. <td class="org-left">date of birthday</td>
  496. <td class="org-left">Faker::Date.birthday(15,99)</td>
  497. </tr>
  498. <tr>
  499. <td class="org-right">11</td>
  500. <td class="org-left">decode:homepage</td>
  501. <td class="org-right">2</td>
  502. <td class="org-left">personal homepage</td>
  503. <td class="org-left">Faker::Internet.url</td>
  504. </tr>
  505. <tr>
  506. <td class="org-right">12</td>
  507. <td class="org-left">skype:id</td>
  508. <td class="org-right">2</td>
  509. <td class="org-left">skype handle</td>
  510. <td class="org-left">Faker::Internet.user<sub>name</sub></td>
  511. </tr>
  512. <tr>
  513. <td class="org-right">13</td>
  514. <td class="org-left">twitter:id</td>
  515. <td class="org-right">1</td>
  516. <td class="org-left">twitter handle</td>
  517. <td class="org-left">Faker::Internet.user<sub>name</sub></td>
  518. </tr>
  519. <tr>
  520. <td class="org-right">14</td>
  521. <td class="org-left">facebook:id</td>
  522. <td class="org-right">3</td>
  523. <td class="org-left">facebook handle</td>
  524. <td class="org-left">Faker::Internet.email</td>
  525. </tr>
  526. <tr>
  527. <td class="org-right">15</td>
  528. <td class="org-left">linkedin:id</td>
  529. <td class="org-right">1</td>
  530. <td class="org-left">linkedin handle</td>
  531. <td class="org-left">Faker::Internet.email</td>
  532. </tr>
  533. <tr>
  534. <td class="org-right">16</td>
  535. <td class="org-left">decode:street</td>
  536. <td class="org-right">4</td>
  537. <td class="org-left">streetname + number</td>
  538. <td class="org-left">Faker::Address.street<sub>address</sub></td>
  539. </tr>
  540. <tr>
  541. <td class="org-right">17</td>
  542. <td class="org-left">decode:postcode</td>
  543. <td class="org-right">4</td>
  544. <td class="org-left">postcode</td>
  545. <td class="org-left">Faker::Address.postcode</td>
  546. </tr>
  547. <tr>
  548. <td class="org-right">18</td>
  549. <td class="org-left">decode:persons<sub>in</sub><sub>household</sub></td>
  550. <td class="org-right">4</td>
  551. <td class="org-left">taken from 'woonsituatie'</td>
  552. <td class="org-left">Faker::Number.between(1,5)</td>
  553. </tr>
  554. <tr>
  555. <td class="org-right">19</td>
  556. <td class="org-left">decode:profession</td>
  557. <td class="org-right">4</td>
  558. <td class="org-left">taken from 'werk en hobbies'</td>
  559. <td class="org-left">Faker::Job.title</td>
  560. </tr>
  561. <tr>
  562. <td class="org-right">20</td>
  563. <td class="org-left">go:my<sub>dreams</sub></td>
  564. <td class="org-right">3</td>
  565. <td class="org-left">taken from 'mijn droom'</td>
  566. <td class="org-left">Faker::RickAndMorty.quote</td>
  567. </tr>
  568. <tr>
  569. <td class="org-right">21</td>
  570. <td class="org-left">go:improve<sub>my</sub><sub>environment</sub></td>
  571. <td class="org-right">2</td>
  572. <td class="org-left">taken from 'mijn omgeving'</td>
  573. <td class="org-left">Faker::RickAndMorty.location</td>
  574. </tr>
  575. <tr>
  576. <td class="org-right">22</td>
  577. <td class="org-left">go:expertise</td>
  578. <td class="org-right">3</td>
  579. <td class="org-left">taken from 'mijn expertise' list structure?</td>
  580. <td class="org-left">Faker::Educator.course</td>
  581. </tr>
  582. <tr>
  583. <td class="org-right">23</td>
  584. <td class="org-left">decode:marital<sub>status</sub></td>
  585. <td class="org-right">4</td>
  586. <td class="org-left">taken from 'woonsituatie'</td>
  587. <td class="org-left">Faker::Demographic.marital<sub>status</sub></td>
  588. </tr>
  589. <tr>
  590. <td class="org-right">24</td>
  591. <td class="org-left">go:neighborhood<sub>role</sub></td>
  592. <td class="org-right">1</td>
  593. <td class="org-left">taken from 'rol &amp; nieuwsbrief'</td>
  594. <td class="org-left">["bewoner","toekomstige","ondernemer","professional","scholier","student","geinteresseerd"].sample</td>
  595. </tr>
  596. <tr>
  597. <td class="org-right">25</td>
  598. <td class="org-left">decode:avg<sub>yearly</sub><sub>gas</sub><sub>use</sub><sub>m3</sub></td>
  599. <td class="org-right">4</td>
  600. <td class="org-left">taken from 'jaarlijks warmte verbruik'</td>
  601. <td class="org-left">Faker::Number.between(1000,2000)</td>
  602. </tr>
  603. <tr>
  604. <td class="org-right">26</td>
  605. <td class="org-left">decode:avg<sub>yearly</sub><sub>electricy</sub><sub>use</sub><sub>kwh</sub></td>
  606. <td class="org-right">4</td>
  607. <td class="org-left">taken from 'jaarlijks electriciteits verbruik'</td>
  608. <td class="org-left">Faker::Number.between(2000,3000)</td>
  609. </tr>
  610. <tr>
  611. <td class="org-right">27</td>
  612. <td class="org-left">decode:membership<sub>organization</sub></td>
  613. <td class="org-right">2</td>
  614. <td class="org-left">taken from 'lidmaatschap van organisaties'</td>
  615. <td class="org-left">Faker::StarTrek.specie</td>
  616. </tr>
  617. <tr>
  618. <td class="org-right">28</td>
  619. <td class="org-left">go:project<sub>association</sub></td>
  620. <td class="org-right">1</td>
  621. <td class="org-left">taken from 'associatie met projecten'</td>
  622. <td class="org-left">Faker::SiliconValley.invention</td>
  623. </tr>
  624. <tr>
  625. <td class="org-right">29</td>
  626. <td class="org-left">go:offer</td>
  627. <td class="org-right">0</td>
  628. <td class="org-left">taken from 'vraag en aanbod items'</td>
  629. <td class="org-left">Faker::SiliconValley.motto</td>
  630. </tr>
  631. <tr>
  632. <td class="org-right">30</td>
  633. <td class="org-left">go:need</td>
  634. <td class="org-right">0</td>
  635. <td class="org-left">taken from 'vraag en aanbod items'</td>
  636. <td class="org-left">Faker::SiliconValley.quote</td>
  637. </tr>
  638. </tbody>
  639. </table>
  640. </div>
  641. </div>
  642. </div>
  643. <div id="outline-container-orgee237cb" class="outline-2">
  644. <h2 id="orgee237cb"><span class="section-number-2">2</span> Data Model</h2>
  645. <div class="outline-text-2" id="text-2">
  646. </div>
  647. <div id="outline-container-orgcbd1b6a" class="outline-3">
  648. <h3 id="orgcbd1b6a"><span class="section-number-3">2.1</span> Example wallet profile</h3>
  649. <div class="outline-text-3" id="text-2-1">
  650. <p>
  651. This sample wallet profile datastructure consists of multiple contexts.
  652. No assumptions are made about ontology for now so mention of existing e.g. skos/foaf,
  653. everything is in the decode namespace which is well known across applications.
  654. </p>
  655. <p>
  656. Each context has a name and groups on or more properties that consist of a well known type and a value.
  657. A type can be part of more than one context.
  658. </p>
  659. <p>
  660. Every property instance has a privacy level attached to it, so we can calculate the weight of requests and profiles.
  661. It overrides the default privacy level specified by the property type.
  662. </p>
  663. <div class="org-src-container">
  664. <pre class="src src-js" id="orgc730294"><span style="color: #4f97d7; font-weight: bold;">var</span> <span style="color: #7590db;">profile</span> = <span style="color: #4f97d7;">{</span>
  665. contexts :
  666. <span style="color: #bc6ec5;">[</span>
  667. <span style="color: #2d9574;">{</span>
  668. title : <span style="color: #2d9574;">"personal"</span>,
  669. context_type : <span style="color: #a45bad;">5</span>,<span style="color: #2aa1ae; background-color: #292e34;">//</span><span style="color: #2aa1ae; background-color: #292e34;">PERSONAL</span>
  670. properties :
  671. <span style="color: #67b11d;">[</span>
  672. <span style="color: #b1951d;">{</span>
  673. type : <span style="color: #2d9574;">"decode:name"</span>,
  674. value: <span style="color: #2d9574;">"Taco van Dijk"</span>,
  675. pl: <span style="color: #a45bad;">1</span> <span style="color: #2aa1ae; background-color: #292e34;">//</span><span style="color: #2aa1ae; background-color: #292e34;">public, everyone may know my name</span>
  676. <span style="color: #b1951d;">}</span>,
  677. <span style="color: #b1951d;">{</span>
  678. type : <span style="color: #2d9574;">"decode:email"</span>,
  679. value : <span style="color: #2d9574;">"[REDACTED]"</span>,
  680. pl: <span style="color: #a45bad;">2</span> <span style="color: #2aa1ae; background-color: #292e34;">//</span><span style="color: #2aa1ae; background-color: #292e34;">affiliate, parties i have personal business with may know</span>
  681. <span style="color: #b1951d;">}</span>,
  682. <span style="color: #b1951d;">{</span>
  683. type: <span style="color: #2d9574;">"decode:address"</span>,
  684. value: <span style="color: #2d9574;">"[REDACTED]"</span>,
  685. pl: <span style="color: #a45bad;">2</span> <span style="color: #2aa1ae; background-color: #292e34;">//</span><span style="color: #2aa1ae; background-color: #292e34;">affiliate, parties i have personal business with may know</span>
  686. <span style="color: #b1951d;">}</span>,
  687. <span style="color: #b1951d;">{</span>
  688. type: <span style="color: #2d9574;">"decode:phone"</span>,
  689. value : <span style="color: #2d9574;">"[REDACTED]"</span>,
  690. pl: <span style="color: #a45bad;">2</span> <span style="color: #2aa1ae; background-color: #292e34;">//</span><span style="color: #2aa1ae; background-color: #292e34;">affiliate, parties i have personal business with may know</span>
  691. <span style="color: #b1951d;">}</span>
  692. <span style="color: #67b11d;">]</span>,
  693. pl_sum: <span style="color: #a45bad;">7</span> <span style="color: #2aa1ae; background-color: #292e34;">//</span><span style="color: #2aa1ae; background-color: #292e34;">this is a calculated value based on the attributed pl values or default if they were not user specified</span>
  694. <span style="color: #2d9574;">}</span>,
  695. <span style="color: #2d9574;">{</span>
  696. title: <span style="color: #2d9574;">"Waag society"</span>,
  697. context_type: <span style="color: #a45bad;">2</span>,<span style="color: #2aa1ae; background-color: #292e34;">//</span><span style="color: #2aa1ae; background-color: #292e34;">WORK</span>
  698. properties :
  699. <span style="color: #67b11d;">[</span>
  700. <span style="color: #b1951d;">{</span>
  701. type : <span style="color: #2d9574;">"decode:name"</span>,
  702. value : <span style="color: #2d9574;">"Taco van Dijk"</span>,
  703. pl: <span style="color: #a45bad;">1</span>
  704. <span style="color: #b1951d;">}</span>,
  705. <span style="color: #b1951d;">{</span>
  706. type : <span style="color: #2d9574;">"decode:email"</span>,
  707. value : <span style="color: #2d9574;">"taco@waag.org"</span>,
  708. pl: <span style="color: #a45bad;">2</span>
  709. <span style="color: #b1951d;">}</span>,
  710. <span style="color: #b1951d;">{</span>
  711. type : <span style="color: #2d9574;">"decode:address"</span>,
  712. value : <span style="color: #2d9574;">"St. Antoniesbreestraat 69"</span>,
  713. pl: <span style="color: #a45bad;">1</span> <span style="color: #2aa1ae; background-color: #292e34;">//</span><span style="color: #2aa1ae; background-color: #292e34;">since this is shared with all my colleagues i find this public</span>
  714. <span style="color: #b1951d;">}</span>
  715. <span style="color: #67b11d;">]</span>,
  716. pl_sum: <span style="color: #a45bad;">4</span>
  717. <span style="color: #2d9574;">}</span>,
  718. <span style="color: #2d9574;">{</span>
  719. title: <span style="color: #2d9574;">"Dyne"</span>,
  720. context_type: <span style="color: #a45bad;">2</span>,<span style="color: #2aa1ae; background-color: #292e34;">//</span><span style="color: #2aa1ae; background-color: #292e34;">WORK</span>
  721. properties :<span style="color: #67b11d;">[</span><span style="color: #b1951d;">{</span>
  722. type : <span style="color: #2d9574;">"decode:name"</span>,
  723. value : <span style="color: #2d9574;">"Ocat"</span>,
  724. pl: <span style="color: #a45bad;">1</span>
  725. <span style="color: #b1951d;">}</span>,
  726. <span style="color: #b1951d;">{</span>
  727. type : <span style="color: #2d9574;">"decode:email"</span>,
  728. value: <span style="color: #2d9574;">"taco@gogs.dyne.org"</span>,
  729. pl: <span style="color: #a45bad;">2</span>
  730. <span style="color: #b1951d;">}</span>
  731. <span style="color: #67b11d;">]</span>,
  732. pl_sum: <span style="color: #a45bad;">3</span>
  733. <span style="color: #2d9574;">}</span>
  734. <span style="color: #bc6ec5;">]</span>
  735. <span style="color: #4f97d7;">}</span>;
  736. process.stdout.write<span style="color: #4f97d7;">(</span>JSON.stringify<span style="color: #bc6ec5;">(</span>profile<span style="color: #bc6ec5;">)</span><span style="color: #4f97d7;">)</span>;
  737. </pre>
  738. </div>
  739. </div>
  740. </div>
  741. <div id="outline-container-org1a632ec" class="outline-3">
  742. <h3 id="org1a632ec"><span class="section-number-3">2.2</span> profile generator</h3>
  743. <div class="outline-text-3" id="text-2-2">
  744. <div class="org-src-container">
  745. <pre class="src src-ruby" id="org83bf26c"> <span style="color: #4f97d7;">require</span> <span style="color: #2d9574;">'faker'</span>
  746. <span style="color: #4f97d7;">require</span> <span style="color: #2d9574;">'json'</span>
  747. <span style="color: #4f97d7;">require</span> <span style="color: #2d9574;">'securerandom'</span>
  748. <span style="color: #ce537a; font-weight: bold;">CMIN</span> = <span style="color: #a45bad;">4</span> <span style="color: #2aa1ae; background-color: #292e34;">#</span><span style="color: #2aa1ae; background-color: #292e34;">minimum amount of contexts</span>
  749. <span style="color: #ce537a; font-weight: bold;">CMAX</span> = <span style="color: #a45bad;">12</span> <span style="color: #2aa1ae; background-color: #292e34;">#</span><span style="color: #2aa1ae; background-color: #292e34;">maximum amount of extra contexts</span>
  750. <span style="color: #ce537a; font-weight: bold;">PC_MIN</span> = <span style="color: #a45bad;">4</span> <span style="color: #2aa1ae; background-color: #292e34;">#</span><span style="color: #2aa1ae; background-color: #292e34;">minimum amount of properties</span>
  751. <span style="color: #ce537a; font-weight: bold;">PC_MAX</span> = <span style="color: #a45bad;">12</span> <span style="color: #2aa1ae; background-color: #292e34;">#</span><span style="color: #2aa1ae; background-color: #292e34;">maximum amount of extra properties</span>
  752. profile = <span style="color: #4f97d7;">{}</span>
  753. contexts = <span style="color: #4f97d7;">[]</span>
  754. <span style="color: #2aa1ae; background-color: #292e34;">#</span><span style="color: #2aa1ae; background-color: #292e34;">create between CMIN and CMAX contexts in this profile</span>
  755. <span style="color: #4f97d7;">(</span><span style="color: #ce537a; font-weight: bold;">CMIN</span> + <span style="color: #4f97d7;">rand</span><span style="color: #bc6ec5;">(</span><span style="color: #ce537a; font-weight: bold;">CMAX</span><span style="color: #bc6ec5;">)</span><span style="color: #4f97d7;">)</span>.times <span style="color: #4f97d7; font-weight: bold;">do</span>
  756. context = <span style="color: #4f97d7;">{}</span>
  757. context_type_idx = <span style="color: #4f97d7;">rand</span><span style="color: #4f97d7;">(</span>context_types.count<span style="color: #4f97d7;">)</span> <span style="color: #2aa1ae; background-color: #292e34;">#</span><span style="color: #2aa1ae; background-color: #292e34;">pick a random context type</span>
  758. context<span style="color: #4f97d7;">[</span><span style="color: #a45bad;">:title</span><span style="color: #4f97d7;">]</span> = <span style="color: #4f97d7;">eval</span><span style="color: #4f97d7;">(</span>context_types<span style="color: #bc6ec5;">[</span>context_type_idx<span style="color: #bc6ec5;">][</span><span style="color: #a45bad;">3</span><span style="color: #bc6ec5;">]</span><span style="color: #4f97d7;">)</span> <span style="color: #2aa1ae; background-color: #292e34;">#</span><span style="color: #2aa1ae; background-color: #292e34;">eval a fake title based on random context type</span>
  759. context<span style="color: #4f97d7;">[</span><span style="color: #a45bad;">:context_type</span><span style="color: #4f97d7;">]</span> = context_types<span style="color: #4f97d7;">[</span>context_type_idx<span style="color: #4f97d7;">][</span><span style="color: #a45bad;">0</span><span style="color: #4f97d7;">]</span> <span style="color: #2aa1ae; background-color: #292e34;">#</span><span style="color: #2aa1ae; background-color: #292e34;">context type index</span>
  760. context<span style="color: #4f97d7;">[</span><span style="color: #a45bad;">:properties</span><span style="color: #4f97d7;">]</span> = <span style="color: #4f97d7;">[]</span>
  761. <span style="color: #2aa1ae; background-color: #292e34;">#</span><span style="color: #2aa1ae; background-color: #292e34;">sample a random amount up to 8 properties for each context</span>
  762. properties.sample<span style="color: #4f97d7;">(</span><span style="color: #ce537a; font-weight: bold;">PC_MIN</span> + <span style="color: #4f97d7;">rand</span><span style="color: #bc6ec5;">(</span><span style="color: #ce537a; font-weight: bold;">PC_MAX</span><span style="color: #bc6ec5;">)</span><span style="color: #4f97d7;">)</span>.each <span style="color: #4f97d7; font-weight: bold;">do</span> |rec|
  763. property = <span style="color: #4f97d7;">{}</span>
  764. property<span style="color: #4f97d7;">[</span><span style="color: #a45bad;">:type</span><span style="color: #4f97d7;">]</span> = rec<span style="color: #4f97d7;">[</span><span style="color: #a45bad;">1</span><span style="color: #4f97d7;">]</span>
  765. property<span style="color: #4f97d7;">[</span><span style="color: #a45bad;">:value</span><span style="color: #4f97d7;">]</span> = <span style="color: #4f97d7;">eval</span><span style="color: #4f97d7;">(</span>rec<span style="color: #bc6ec5;">[</span><span style="color: #a45bad;">4</span><span style="color: #bc6ec5;">]</span><span style="color: #4f97d7;">)</span>
  766. property<span style="color: #4f97d7;">[</span><span style="color: #a45bad;">:pl</span><span style="color: #4f97d7;">]</span> = rec<span style="color: #4f97d7;">[</span><span style="color: #a45bad;">2</span><span style="color: #4f97d7;">]</span> + <span style="color: #4f97d7;">rand</span><span style="color: #4f97d7;">(</span><span style="color: #a45bad;">2</span><span style="color: #4f97d7;">)</span> <span style="color: #2aa1ae; background-color: #292e34;">#</span><span style="color: #2aa1ae; background-color: #292e34;">default privacy level, + random markup upwards</span>
  767. context<span style="color: #4f97d7;">[</span><span style="color: #a45bad;">:properties</span><span style="color: #4f97d7;">]</span> &lt;&lt; property
  768. <span style="color: #4f97d7; font-weight: bold;">end</span>
  769. context<span style="color: #4f97d7;">[</span><span style="color: #a45bad;">:pl_sum</span><span style="color: #4f97d7;">]</span> = context<span style="color: #4f97d7;">[</span><span style="color: #a45bad;">:properties</span><span style="color: #4f97d7;">]</span>.map<span style="color: #4f97d7;">{</span>|p|<span style="color: #4f97d7;">p</span><span style="color: #bc6ec5;">[</span><span style="color: #a45bad;">:pl</span><span style="color: #bc6ec5;">]</span><span style="color: #4f97d7;">}</span>.reduce<span style="color: #4f97d7;">(</span><span style="color: #a45bad;">0</span>,<span style="color: #a45bad;">:+</span><span style="color: #4f97d7;">)</span> <span style="color: #2aa1ae; background-color: #292e34;">#</span><span style="color: #2aa1ae; background-color: #292e34;">calculate pl sum for each context</span>
  770. context<span style="color: #4f97d7;">[</span><span style="color: #a45bad;">:pl_mean</span><span style="color: #4f97d7;">]</span> = <span style="color: #4f97d7;">(</span>context<span style="color: #bc6ec5;">[</span><span style="color: #a45bad;">:pl_sum</span><span style="color: #bc6ec5;">]</span> / context<span style="color: #bc6ec5;">[</span><span style="color: #a45bad;">:properties</span><span style="color: #bc6ec5;">]</span>.count<span style="color: #4f97d7;">)</span>
  771. contexts &lt;&lt; context
  772. <span style="color: #4f97d7; font-weight: bold;">end</span>
  773. <span style="color: #2aa1ae; background-color: #292e34;"># </span><span style="color: #2aa1ae; background-color: #292e34;">sort the contexts by contextType</span>
  774. sorted = contexts.sort <span style="color: #4f97d7;">{</span> | a, b | <span style="color: #bc6ec5;">[</span>a<span style="color: #2d9574;">[</span><span style="color: #a45bad;">:context_type</span><span style="color: #2d9574;">]</span>, a<span style="color: #2d9574;">[</span><span style="color: #a45bad;">:pl_mean</span><span style="color: #2d9574;">]</span><span style="color: #bc6ec5;">]</span> &lt;=&gt; <span style="color: #bc6ec5;">[</span>b<span style="color: #2d9574;">[</span><span style="color: #a45bad;">:context_type</span><span style="color: #2d9574;">]</span>, b<span style="color: #2d9574;">[</span><span style="color: #a45bad;">:pl_mean</span><span style="color: #2d9574;">]</span><span style="color: #bc6ec5;">]</span> <span style="color: #4f97d7;">}</span>
  775. profile<span style="color: #4f97d7;">[</span><span style="color: #a45bad;">:contexts</span><span style="color: #4f97d7;">]</span> = sorted
  776. <span style="color: #4f97d7;">puts</span> profile.to_json
  777. </pre>
  778. </div>
  779. </div>
  780. </div>
  781. <div id="outline-container-org28f9f7f" class="outline-3">
  782. <h3 id="org28f9f7f"><span class="section-number-3">2.3</span> Example request</h3>
  783. <div class="outline-text-3" id="text-2-3">
  784. <p>
  785. This sample application request consists of an application name, a set of required property types and a set of optional property types.
  786. Each application has a default context type attached to it, (so we can assign it a hue).
  787. For each request we can calculate the average privacy level,
  788. and the cumulative privacy weight by adding the privacy levels of each property in the request.
  789. </p>
  790. <div class="org-src-container">
  791. <pre class="src src-js" id="orgf2c461c"><span style="color: #4f97d7; font-weight: bold;">var</span> <span style="color: #7590db;">request</span> = <span style="color: #4f97d7;">{</span>
  792. application : <span style="color: #2d9574;">"decodeapp:facebook"</span>,
  793. context_type : <span style="color: #a45bad;">5</span>,<span style="color: #2aa1ae; background-color: #292e34;">//</span><span style="color: #2aa1ae; background-color: #292e34;">personal</span>
  794. required : <span style="color: #bc6ec5;">[</span><span style="color: #2d9574;">"decode:name"</span>, <span style="color: #2d9574;">"decode:email"</span>, <span style="color: #2d9574;">"decode:address"</span><span style="color: #bc6ec5;">]</span>,
  795. optional : <span style="color: #bc6ec5;">[</span><span style="color: #2d9574;">"decode:phone"</span><span style="color: #bc6ec5;">]</span>
  796. <span style="color: #4f97d7;">}</span>
  797. <span style="color: #4f97d7; font-weight: bold;">var</span> <span style="color: #7590db;">data</span> = JSON.stringify<span style="color: #4f97d7;">(</span>request<span style="color: #4f97d7;">)</span> + <span style="color: #2d9574;">"\n"</span>;
  798. process.stdout.write<span style="color: #4f97d7;">(</span>data<span style="color: #4f97d7;">)</span>;
  799. </pre>
  800. </div>
  801. </div>
  802. </div>
  803. <div id="outline-container-org452f82f" class="outline-3">
  804. <h3 id="org452f82f"><span class="section-number-3">2.4</span> request generator</h3>
  805. <div class="outline-text-3" id="text-2-4">
  806. <div class="org-src-container">
  807. <pre class="src src-ruby" id="org0f52421"><span style="color: #4f97d7;">require</span> <span style="color: #2d9574;">'faker'</span>
  808. <span style="color: #4f97d7;">require</span> <span style="color: #2d9574;">'json'</span>
  809. <span style="color: #4f97d7;">require</span> <span style="color: #2d9574;">'securerandom'</span>
  810. request = <span style="color: #4f97d7;">{}</span>
  811. request<span style="color: #4f97d7;">[</span><span style="color: #a45bad;">:application</span><span style="color: #4f97d7;">]</span> = <span style="color: #2d9574;">"decodeapp:</span><span style="color: #7590db;">#{Faker::App.name.downcase.gsub(' ','_')}</span><span style="color: #2d9574;">"</span>
  812. request<span style="color: #4f97d7;">[</span><span style="color: #a45bad;">:context_type</span><span style="color: #4f97d7;">]</span> = <span style="color: #4f97d7;">rand</span><span style="color: #4f97d7;">(</span>context_types.count<span style="color: #4f97d7;">)</span>
  813. required_recs = properties.sample<span style="color: #4f97d7;">(</span><span style="color: #a45bad;">1</span> + <span style="color: #4f97d7;">rand</span><span style="color: #bc6ec5;">(</span><span style="color: #a45bad;">3</span><span style="color: #bc6ec5;">)</span><span style="color: #4f97d7;">)</span>
  814. optional_recs = <span style="color: #4f97d7;">(</span>properties - required_recs<span style="color: #4f97d7;">)</span>.sample<span style="color: #4f97d7;">(</span><span style="color: #a45bad;">2</span><span style="color: #4f97d7;">)</span>
  815. request<span style="color: #4f97d7;">[</span><span style="color: #a45bad;">:required</span><span style="color: #4f97d7;">]</span> = required_recs.map<span style="color: #4f97d7;">{</span>|rec| rec<span style="color: #bc6ec5;">[</span><span style="color: #a45bad;">1</span><span style="color: #bc6ec5;">]</span><span style="color: #4f97d7;">}</span> <span style="color: #2aa1ae; background-color: #292e34;">#</span><span style="color: #2aa1ae; background-color: #292e34;">map property types</span>
  816. request<span style="color: #4f97d7;">[</span><span style="color: #a45bad;">:optional</span><span style="color: #4f97d7;">]</span> = optional_recs.map<span style="color: #4f97d7;">{</span>|rec| rec<span style="color: #bc6ec5;">[</span><span style="color: #a45bad;">1</span><span style="color: #bc6ec5;">]</span><span style="color: #4f97d7;">}</span> <span style="color: #2aa1ae; background-color: #292e34;">#</span><span style="color: #2aa1ae; background-color: #292e34;">map property types</span>
  817. all_recs = required_recs + optional_recs
  818. request<span style="color: #4f97d7;">[</span><span style="color: #a45bad;">:pl_sum</span><span style="color: #4f97d7;">]</span> = all_recs.map<span style="color: #4f97d7;">{</span>|rec|<span style="color: #bc6ec5;">(</span>rec<span style="color: #2d9574;">[</span><span style="color: #a45bad;">2</span><span style="color: #2d9574;">]</span> + <span style="color: #4f97d7;">rand</span><span style="color: #2d9574;">(</span><span style="color: #a45bad;">2</span><span style="color: #2d9574;">)</span><span style="color: #bc6ec5;">)</span><span style="color: #4f97d7;">}</span>.reduce<span style="color: #4f97d7;">(</span><span style="color: #a45bad;">0</span>,<span style="color: #a45bad;">:+</span><span style="color: #4f97d7;">)</span> <span style="color: #2aa1ae; background-color: #292e34;">#</span><span style="color: #2aa1ae; background-color: #292e34;">calculate pl sum for each context</span>
  819. request<span style="color: #4f97d7;">[</span><span style="color: #a45bad;">:pl_mean</span><span style="color: #4f97d7;">]</span> = <span style="color: #4f97d7;">(</span>request<span style="color: #bc6ec5;">[</span><span style="color: #a45bad;">:pl_sum</span><span style="color: #bc6ec5;">]</span> / all_recs.count<span style="color: #4f97d7;">)</span>
  820. <span style="color: #4f97d7;">puts</span> request.to_json
  821. </pre>
  822. </div>
  823. </div>
  824. </div>
  825. </div>
  826. <div id="outline-container-orgf51c7ba" class="outline-2">
  827. <h2 id="orgf51c7ba"><span class="section-number-2">3</span> Data Comparison</h2>
  828. <div class="outline-text-2" id="text-3">
  829. <p>
  830. During the interaction we want to give the user insight into a couple of things;
  831. </p>
  832. <ul class="org-ul">
  833. <li>How does the requested set of properties relate to the different contexts? How well does a context match to the request?</li>
  834. <li>What would it mean for the context if the request was accepted? How many / which properties would have to be added to the context in order to fulfill the request?</li>
  835. <li>What would it mean for the cumulative weight of the context?</li>
  836. </ul>
  837. <p>
  838. In below ruby code a comparison is made by on creating the intersection and its inverse between the request and each context.
  839. </p>
  840. <div class="org-src-container">
  841. <pre class="src src-ruby" id="org7998c7e"><span style="color: #4f97d7;">require</span> <span style="color: #2d9574;">'json'</span>
  842. <span style="color: #4f97d7;">require</span> <span style="color: #2d9574;">'nokogiri'</span> <span style="color: #2aa1ae; background-color: #292e34;">#</span><span style="color: #2aa1ae; background-color: #292e34;">for creating xml</span>
  843. request = <span style="color: #ce537a; font-weight: bold;">JSON</span>.parse<span style="color: #4f97d7;">(</span>request_data<span style="color: #4f97d7;">)</span>
  844. profile = <span style="color: #ce537a; font-weight: bold;">JSON</span>.parse<span style="color: #4f97d7;">(</span>profile_data<span style="color: #4f97d7;">)</span>
  845. context_diffs = <span style="color: #4f97d7;">[]</span>
  846. profile<span style="color: #4f97d7;">[</span><span style="color: #2d9574;">"contexts"</span><span style="color: #4f97d7;">]</span>.each <span style="color: #4f97d7; font-weight: bold;">do</span> | context |
  847. requested = request<span style="color: #4f97d7;">[</span><span style="color: #2d9574;">"required"</span><span style="color: #4f97d7;">]</span> + request<span style="color: #4f97d7;">[</span><span style="color: #2d9574;">"optional"</span><span style="color: #4f97d7;">]</span>
  848. available = context<span style="color: #4f97d7;">[</span><span style="color: #2d9574;">"properties"</span><span style="color: #4f97d7;">]</span>.map <span style="color: #4f97d7;">{</span>|p| <span style="color: #4f97d7;">p</span><span style="color: #bc6ec5;">[</span><span style="color: #2d9574;">"type"</span><span style="color: #bc6ec5;">]</span><span style="color: #4f97d7;">}</span>
  849. intersect = available &amp; requested
  850. except = requested - available
  851. diff = <span style="color: #4f97d7;">{</span><span style="color: #a45bad;">:context</span> =&gt; context<span style="color: #bc6ec5;">[</span><span style="color: #2d9574;">"title"</span><span style="color: #bc6ec5;">]</span>, <span style="color: #a45bad;">:intersect</span> =&gt; intersect, <span style="color: #a45bad;">:except</span> =&gt; except<span style="color: #4f97d7;">}</span>
  852. context_diffs &lt;&lt; diff
  853. <span style="color: #4f97d7; font-weight: bold;">end</span>
  854. </pre>
  855. </div>
  856. <p>
  857. NOTE: We export to file diff.xml here for easy parsing in processing.js below.
  858. </p>
  859. </div>
  860. </div>
  861. <div id="outline-container-org4d760b7" class="outline-2">
  862. <h2 id="org4d760b7"><span class="section-number-2">4</span> Visualization</h2>
  863. <div class="outline-text-2" id="text-4">
  864. <p>
  865. We want to visualize the following things;
  866. </p>
  867. <ul class="org-ul">
  868. <li>The request with the application name and it's size / quality (Who's asking what)</li>
  869. <li>The different contexts with it's name and size / quality relative to the request. (What would it mean to accept?)</li>
  870. </ul>
  871. <p>
  872. Per the design of Dyne, we want to use color to indicate the relation between the request and each context.
  873. A color should indicate something about privacy level and context type.
  874. For now the mapping is as follows;
  875. Different hues can be mapped to each context type.
  876. Different tones within the hue can be mapped to each privacy level.
  877. </p>
  878. <p>
  879. This table shows all colors for each context / privacy level combination.
  880. Click on the diagram to compare colors sets.
  881. </p>
  882. <script src="processing.js"></script>
  883. <script type="text/processing" data-processing-target="ob-44f6f21ab5755a24cd02bc9679d06787f37dfeb6">
  884. //color definitions
  885. color a3 = #3A3B58;
  886. color b3 = #734246;
  887. color d3 = #B4561F;
  888. color c3 = #336F60;
  889. color f3 = #7A3E2A;
  890. color g3 = #A48137;
  891. color e2 = #97BBCB;
  892. color a4 = #3B4257;
  893. color b4 = #6A4345;
  894. color d4 = #86451F;
  895. color c4 = #345A48;
  896. color f4 = #A92F21;
  897. color g4 = #BC983B;
  898. color a5 = #3D4358;
  899. color b5 = #402623;
  900. color d5 = #85442D;
  901. color c5 = #3B403A;
  902. color f5 = #7A150B;
  903. color g5 = #252F2B;
  904. color a1 = #597099;
  905. color e4 = #0A3878;
  906. color b1 = #D16365;
  907. color d1 = #FFD43B;
  908. color c1 = #B7BF98;
  909. color e1 = #CAD2C8;
  910. color e0 = #F5EDE5;
  911. color f1 = #D17978;
  912. color g1 = #FDD23E;
  913. color a0 = #C5C3CC;
  914. color e3 = #0485B1;
  915. color b0 = #FFDCD6;
  916. color d0 = #FFE9BE;
  917. color c0 = #F0E9D5;
  918. color f0 = #E4C8BF;
  919. color g0 = #FBE6BA;
  920. color a2 = #3D4B79;
  921. color e5 = #084064;
  922. color b2 = #974244;
  923. color d2 = #F8AA08;
  924. color c2 = #4E937F;
  925. color f2 = #8F4330;
  926. color g2 = #FFDB03;
  927. color colors[][] = {
  928. {b0,b1,b2,b3,b4,b5},
  929. {c0,c1,c2,c3,c4,c5},
  930. {a0,a1,a2,a3,a4,a5},
  931. {d0,d1,d2,d3,d4,d5},
  932. {e0,e1,e2,e3,e4,e5},
  933. {f0,f1,f2,f3,f4,f5},
  934. {g0,g1,g2,g3,g4,g5}
  935. };
  936. boolean procedural = true;
  937. String[] levels = {"commons", "public", "affiliate", "intimate", "private", "secret"};
  938. String[] contextTypes = {"personal", "health", "education", "work", "hobby", "financial", "other"};
  939. static class PrivacyLevel {
  940. public static int SECRET = 5;
  941. public static int PRIVATE = 4;
  942. public static int INTIMATE = 3;
  943. public static int AFFILIATE = 2;
  944. public static int PUBLIC = 1;
  945. public static int COMMONS = 0;
  946. }
  947. static class ContextType {
  948. public static int PERSONAL = 0;
  949. public static int HEALTH = 1;
  950. public static int EDUCATION = 2;
  951. public static int WORK = 3;
  952. public static int HOBBY = 4;
  953. public static int FINANCIAL = 5;
  954. public static int OTHER = 6;
  955. }
  956. public int getColor(int privacy_level, int context_type)
  957. {
  958. if(procedural){
  959. return pcolors[context_type][privacy_level];
  960. }
  961. return colors[context_type][privacy_level];
  962. }
  963. int[][] pcolors = new int[contextTypes.length][levels.length];
  964. void setup()
  965. {
  966. generateColors();
  967. size(600,480);
  968. }
  969. void mousePressed()
  970. {
  971. //toggle colors to see the difference
  972. procedural = !procedural;
  973. }
  974. //replace colors in the table with generated ones to maximize contrast
  975. void generateColors()
  976. {
  977. //we start with b0 as a seed color
  978. color seed = d0;
  979. colorMode(HSB);
  980. float h_seed = hue(seed);
  981. float s_seed = saturation(seed);
  982. float v_seed = brightness(seed);
  983. float levelshift = 255/levels.length;
  984. float contextshift = 255/contextTypes.length + 1;
  985. //cycle hue for each level
  986. for (int i = 0; i < contextTypes.length; i++){
  987. float h = h_seed + i * contextshift;
  988. if(h > 255){h = h - 255;}
  989. //cycle brightness for each context
  990. for(int j = 0; j < levels.length; j++)
  991. {
  992. float v = v_seed - (j * levelshift);
  993. float s = s_seed + (j * levelshift);
  994. color c = color(h,s,v);
  995. pcolors[i][j] = c;
  996. }
  997. }
  998. colorMode(RGB);
  999. }
  1000. void draw()
  1001. {
  1002. background(200);
  1003. float row_height = 50;
  1004. float column_width = 80;
  1005. fill(0);
  1006. //draw privacy level headers
  1007. for (int i = 0; i < levels.length; i++ ){
  1008. text(levels[i], (i + 1) * column_width, row_height );
  1009. }
  1010. //draw context headers
  1011. for (int j = 0; j < contextTypes.length; j++)
  1012. {
  1013. text(contextTypes[j], 20, (j+2) * row_height);
  1014. }
  1015. //draw colors
  1016. for(int i = 0; i < levels.length; i++)
  1017. {
  1018. float x = 20 + (i + 1) * column_width;
  1019. for(int j = 0; j < contextTypes.length; j++)
  1020. {
  1021. float y = (j + 2) * row_height;
  1022. color c = getColor(i,j);
  1023. fill(c);
  1024. ellipse(x,y, 20, 20);
  1025. }
  1026. }
  1027. }
  1028. </script> <canvas id="ob-44f6f21ab5755a24cd02bc9679d06787f37dfeb6"></canvas>
  1029. </div>
  1030. </div>
  1031. <div id="outline-container-org34340c1" class="outline-2">
  1032. <h2 id="org34340c1"><span class="section-number-2">5</span> Interaction</h2>
  1033. <div class="outline-text-2" id="text-5">
  1034. <p>
  1035. We have come up with an interaction for entitlements that is based around a 'context switcher'.
  1036. The color of the section in the center always represents the current context.
  1037. The outer ring is divided into separate 'sectors' for each context that you have defined.
  1038. </p>
  1039. <p>
  1040. Each context has a different color, based on the context type and the data that it holds.
  1041. For example if you are at work you would (or the application will automatically)
  1042. set the current context to blue by clicking on the blue sector.
  1043. </p>
  1044. <p>
  1045. When a request comes in through decode, it will be positioned in orbit around the context switcher,
  1046. close by the sector of the calculated best fitted context. Based on the category and the data diff.
  1047. </p>
  1048. <div class="org-src-container">
  1049. <pre class="src src-java" id="orgbd920af"><span style="color: #2aa1ae; background-color: #292e34;">//</span><span style="color: #2aa1ae; background-color: #292e34;">calculate the fitness score for the given context and diff for the current request </span>
  1050. <span style="color: #ce537a; font-weight: bold;">int</span> <span style="color: #bc6ec5; font-weight: bold;">fitnessScore</span><span style="color: #4f97d7;">(</span><span style="color: #ce537a; font-weight: bold;">c</span>,<span style="color: #ce537a; font-weight: bold;">d</span><span style="color: #4f97d7;">)</span>
  1051. <span style="color: #4f97d7;">{</span>
  1052. <span style="color: #ce537a; font-weight: bold;">int</span> <span style="color: #7590db;">score</span> = <span style="color: #a45bad;">0</span>;
  1053. <span style="color: #4f97d7; font-weight: bold;">if</span><span style="color: #bc6ec5;">(</span>c.contextType == request.contextType<span style="color: #bc6ec5;">)</span>
  1054. <span style="color: #bc6ec5;">{</span>
  1055. score += <span style="color: #a45bad;">5</span>;
  1056. <span style="color: #bc6ec5;">}</span>
  1057. <span style="color: #2aa1ae; background-color: #292e34;">//</span><span style="color: #2aa1ae; background-color: #292e34;">add one point for each property that is present</span>
  1058. score += d.intersect.length;
  1059. <span style="color: #2aa1ae; background-color: #292e34;">//</span><span style="color: #2aa1ae; background-color: #292e34;">subtract one point for each property that is missing</span>
  1060. score -= d.except.length;
  1061. <span style="color: #4f97d7; font-weight: bold;">return</span> score;
  1062. <span style="color: #4f97d7;">}</span>
  1063. </pre>
  1064. </div>
  1065. <p>
  1066. The user can drag the request around the outer ring to compare the impact it would have,
  1067. accepting the request for each sector in the context switcher.
  1068. </p>
  1069. <p>
  1070. After a suitable context is found, the user can let go of the request, and a dialog appears in the center,
  1071. asking the user to either accept or decline the request.
  1072. </p>
  1073. <p>
  1074. The example below demonstrates the concept with a randomly generated profile and request.
  1075. </p>
  1076. <script src="processing.js"></script>
  1077. <script type="text/processing" data-processing-target="ob-012f45a13f3c9558ffb5644a19192df95c5288cd">
  1078. String[] levels = {"commons", "public", "affiliate", "intimate", "private", "secret"};
  1079. String[] contextTypes = {"personal", "health", "education", "work", "hobby", "financial", "other"};
  1080. static class PrivacyLevel {
  1081. public static int SECRET = 5;
  1082. public static int PRIVATE = 4;
  1083. public static int INTIMATE = 3;
  1084. public static int AFFILIATE = 2;
  1085. public static int PUBLIC = 1;
  1086. public static int COMMONS = 0;
  1087. }
  1088. static class ContextType {
  1089. public static int PERSONAL = 0;
  1090. public static int HEALTH = 1;
  1091. public static int EDUCATION = 2;
  1092. public static int WORK = 3;
  1093. public static int HOBBY = 4;
  1094. public static int FINANCIAL = 5;
  1095. public static int OTHER = 6;
  1096. }
  1097. int[][] colors = generateColors();
  1098. //generate colors to maximize contrast
  1099. int[][] generateColors()
  1100. {
  1101. int[][] pcolors = new int[contextTypes.length][levels.length];
  1102. //we start with d0 as a seed color
  1103. color seed = #FFE9BE;//seed color
  1104. colorMode(HSB);
  1105. float h_seed = hue(seed);
  1106. float s_seed = saturation(seed);
  1107. float v_seed = brightness(seed);
  1108. float levelshift = 255/levels.length;
  1109. float contextshift = 255/contextTypes.length + 1;
  1110. //cycle hue for each level
  1111. for (int i = 0; i < contextTypes.length; i++){
  1112. float h = h_seed + i * contextshift;
  1113. if(h > 255){h = h - 255;}
  1114. //cycle brightness for each context
  1115. for(int j = 0; j < levels.length; j++)
  1116. {
  1117. float v = v_seed - (j * levelshift);
  1118. float s = s_seed + (j * levelshift);
  1119. color c = color(h,s,v);
  1120. pcolors[i][j] = c;
  1121. }
  1122. }
  1123. colorMode(RGB);
  1124. return pcolors;
  1125. }
  1126. public int getColor(int privacy_level, int context_type)
  1127. {
  1128. return colors[context_type][privacy_level];
  1129. }
  1130. class Request
  1131. {
  1132. public String application;
  1133. public int contextType;
  1134. public String[] required_properties;
  1135. public String[] optional_properties;
  1136. public int plSum;
  1137. public int plMean;
  1138. public Request(String app, int contextType, String[] req, String[] opt, int sum, int mean)
  1139. {
  1140. this.application = app;
  1141. this.contextType = contextType;
  1142. this.required_properties = req;
  1143. this.optional_properties = opt;
  1144. this.plSum = sum;
  1145. this.plMean = mean;
  1146. }
  1147. }
  1148. class Diff
  1149. {
  1150. public String context;
  1151. public String[] intersect;
  1152. public String[] except;
  1153. public Diff(String ctx, String[] intersect, String[] except)
  1154. {
  1155. this.context = ctx;
  1156. this.intersect = intersect;
  1157. this.except = except;
  1158. }
  1159. }
  1160. class Property
  1161. {
  1162. public String type;
  1163. public String value;
  1164. public int pl;//privacy level
  1165. public Property(String type, String value, int pl)
  1166. {
  1167. this.type = type;
  1168. this.value = value;
  1169. this.pl = pl;
  1170. }
  1171. }
  1172. class Context
  1173. {
  1174. public String title;
  1175. public int plSum;
  1176. public int plMean;
  1177. public int contextType;
  1178. public Property[] properties;
  1179. public Context(String title, int plSum, int plMean, int contextType, Property[] properties)
  1180. {
  1181. this.title = title;
  1182. this.plSum = plSum;
  1183. this.plMean = plMean;
  1184. this.properties = properties;
  1185. this.contextType = contextType;
  1186. }
  1187. }
  1188. XMLElement doc = new XMLElement(this, 'diff.xml');
  1189. //create typed versions because this is java :-(
  1190. Request parseRequest(XMLElement xml)
  1191. {
  1192. XMLElement req = xml.getChild(0);
  1193. String name = req.getChild(0).getContent();
  1194. int contextType = req.getChild(1).getContent();
  1195. String[] required = new String[req.getChild(2).getChildCount()];
  1196. String[] optional = new String[req.getChild(3).getChildCount()];
  1197. int plSum = parseInt(req.getChild(4).getContent());
  1198. int plMean = parseInt(req.getChild(5).getContent());
  1199. for (int i = 0; i < required.length; i++) {
  1200. required[i] = req.getChild(2).getChild(i).getContent();
  1201. }
  1202. for (int i = 0; i < optional.length; i++) {
  1203. optional[i] = req.getChild(3).getChild(i).getContent();
  1204. }
  1205. Request r = new Request(name,contextType,required,optional, plSum, plMean);
  1206. return r;
  1207. }
  1208. Context[] parseProfile(XMLElement xml)
  1209. {
  1210. XMLElement profile = xml.getChild(2);
  1211. Context[] contexts = new Context[profile.getChildCount()];
  1212. for(int i = 0; i < contexts.length; i++)
  1213. {
  1214. String contextName = profile.getChild(i).getChild(0).getContent();
  1215. int contextType = parseInt(profile.getChild(i).getChild(1).getContent());
  1216. int plSum = parseInt(profile.getChild(i).getChild(2).getContent());
  1217. int plMean = parseInt(profile.getChild(i).getChild(3).getContent());
  1218. XMLElement propertiesEl = profile.getChild(i).getChild(4);
  1219. Property[] properties = new Property[propertiesEl.getChildCount()];
  1220. for(int j = 0; j < properties.length; j++)
  1221. {
  1222. Property prop = parseProperty(propertiesEl.getChild(j));
  1223. properties[j] = prop;
  1224. }
  1225. Context context = new Context(contextName, plSum, plMean, contextType, properties);
  1226. contexts[i] = context;
  1227. }
  1228. return contexts;
  1229. }
  1230. Property parseProperty(XMLElement propertyEl)
  1231. {
  1232. String propertyType = propertyEl.getChild(0).getContent();
  1233. String value = propertyEl.getChild(1).getContent();
  1234. int pl = parseInt(propertyEl.getChild(2).getContent());
  1235. return new Property(propertyType, value, pl);
  1236. }
  1237. //create typed versions because this is java :-(
  1238. Diff[] parseDiffs(xml)
  1239. {
  1240. XMLElement diffsEl = xml.getChild(1);
  1241. Diff[] diffs = new Diff[diffsEl.getChildCount()];
  1242. for(int i = 0; i < diffs.length; i++)
  1243. {
  1244. String contextName = diffsEl.getChild(i).getChild(0).getContent();
  1245. String[] intersects = new String[diffsEl.getChild(i).getChild(1).getChildCount()];
  1246. String[] except = new String[diffsEl.getChild(i).getChild(2).getChildCount()];
  1247. for(int j = 0; j < intersects.length; j++)
  1248. {
  1249. intersects[j] = diffsEl.getChild(i).getChild(1).getChild(j).getContent();
  1250. }
  1251. for(int j = 0; j < except.length; j++)
  1252. {
  1253. except[j] = diffsEl.getChild(i).getChild(2).getChild(j).getContent();
  1254. }
  1255. Diff diff = new Diff(contextName,intersects,except);
  1256. diffs[i] = diff;
  1257. }
  1258. return diffs;
  1259. }
  1260. Request request = parseRequest(doc);
  1261. Diff[] diffs = parseDiffs(doc);
  1262. Context[] contexts = parseProfile(doc);
  1263. //calculate the fitness score for the given context and diff for the current request
  1264. int fitnessScore(c,d)
  1265. {
  1266. int score = 0;
  1267. if(c.contextType == request.contextType)
  1268. {
  1269. score += 5;
  1270. }
  1271. //add one point for each property that is present
  1272. score += d.intersect.length;
  1273. //subtract one point for each property that is missing
  1274. score -= d.except.length;
  1275. return score;
  1276. }
  1277. //magic numbers
  1278. float contextSize = 500;//random(50,100); //random between 50 and 100
  1279. float requestSize = 50;
  1280. float eqd_angle = TWO_PI / contexts.length;
  1281. float PROPORTION_CENTER = 0.6;
  1282. float DISTANCE_FACTOR = 1.4;
  1283. //globals
  1284. float centerX, centerY;
  1285. float xOffset, yOffset;
  1286. float requestX, requestY;//request coordinates, they can move
  1287. boolean hitRequest = false;
  1288. boolean dragging = false;
  1289. int hitContext = -1;
  1290. int currentContext = 1;//first context is the default context
  1291. PFont font;
  1292. PFont titleFont;
  1293. void setup()
  1294. {
  1295. size(800,800);
  1296. rectMode(RADIUS);
  1297. smooth();
  1298. titleFont = createFont("HelveticaNeue", 20);
  1299. font = createFont("HelveticaNeue", 14);
  1300. centerX = width/2;
  1301. centerY = height/2;
  1302. int bestContext = bestFit();
  1303. PVector position = positionForSectorIndex(bestContext);
  1304. requestX = position.x;
  1305. requestY = position.y;
  1306. }
  1307. //calculate best fitting sector
  1308. int bestFit()
  1309. {
  1310. int count = 0;
  1311. int bestContext = -1;
  1312. int bestScore = -99;
  1313. for(Context context : contexts)
  1314. {
  1315. Diff diff = diffs[count];
  1316. int score = fitnessScore(context,diff);
  1317. if(score > bestScore)
  1318. {
  1319. bestScore = score;
  1320. bestContext = count;
  1321. }
  1322. count++;
  1323. }
  1324. return bestContext;
  1325. }
  1326. //the position should be outside the center of the middle of the sector
  1327. PVector positionForSectorIndex(int index)
  1328. {
  1329. float angle = (PI/2) + (index * eqd_angle) + (eqd_angle/2);
  1330. float x = centerX + (contextSize/2 * DISTANCE_FACTOR) * cos(angle); //calculate xPos
  1331. float y = centerY + (contextSize/2 * DISTANCE_FACTOR) * sin(angle); //calculate yPos
  1332. return new PVector(x,y);
  1333. }
  1334. //draw each frame
  1335. void draw()
  1336. {
  1337. background(255);
  1338. drawTitle();
  1339. //drawBorder();
  1340. drawSectors();
  1341. drawCurrentContext();
  1342. drawRequest();
  1343. }
  1344. //draw the request and label
  1345. void drawRequest()
  1346. {
  1347. color strokeColor = hitRequest? 255 : 153;
  1348. stroke(strokeColor);
  1349. color reqColor = getColor(request.plMean, request.contextType);
  1350. fill(reqColor,127);
  1351. ellipse(requestX,requestY, requestSize,requestSize);
  1352. colorMode(HSB);
  1353. fill(darken(reqColor));
  1354. textAlign(CENTER,CENTER);
  1355. text(request.application + "\n(" + contextTypes[request.contextType]+ ")", requestX, requestY + 50/1.5);
  1356. text("" + request.plSum, requestX, requestY);
  1357. colorMode(RGB);
  1358. }
  1359. //draw current context as center circle over the pie
  1360. void drawCurrentContext()
  1361. {
  1362. Context current = contexts[currentContext];
  1363. //set up colors for current context
  1364. color contextColor = getColor(current.plMean, current.contextType);
  1365. colorMode(HSB);
  1366. color darkContextColor = darken(contextColor);
  1367. colorMode(RGB);
  1368. fill(contextColor);
  1369. noStroke();
  1370. ellipse(centerX, centerY, contextSize * PROPORTION_CENTER, contextSize * PROPORTION_CENTER);
  1371. //if we have hit a context draw detailed information in the center
  1372. if(hitContext > -1)
  1373. {
  1374. fill(255);
  1375. noStroke();
  1376. ellipse(centerX, centerY, contextSize * PROPORTION_CENTER * 0.95, contextSize * PROPORTION_CENTER * 0.95);
  1377. if(dragging == false)
  1378. {
  1379. drawButtons(darkContextColor);
  1380. }
  1381. else
  1382. {
  1383. textFont(font);
  1384. drawDiff(current, contextColor);
  1385. }
  1386. }
  1387. else //just draw the current context title
  1388. {
  1389. textFont(font);
  1390. fill(255);
  1391. noStroke();
  1392. ellipse(centerX, centerY, contextSize * 0.4, contextSize * 0.4);
  1393. fill(darkContextColor);
  1394. textAlign(CENTER,CENTER);
  1395. text("My \n" + current.title + "\n data", centerX, centerY);
  1396. }
  1397. }
  1398. //darken the given color, expects hsb color mode
  1399. int darken(int c)
  1400. {
  1401. float h = hue(c);
  1402. float s = saturation(c);
  1403. float v = brightness(c);
  1404. return color(h,s,v * 0.6);
  1405. }
  1406. //draw the accept / decline buttons
  1407. void drawButtons(color darkContextColor)
  1408. {
  1409. //draw accept and decline button
  1410. fill(darkContextColor);
  1411. textFont(font);
  1412. textAlign(CENTER,CENTER);
  1413. text("ACCEPT | DECLINE", centerX, centerY);
  1414. }
  1415. //show diff information
  1416. void drawDiff(Context c, color contextColor)
  1417. {
  1418. ellipse(centerX, centerY, contextSize * PROPORTION_CENTER * 0.95, contextSize * PROPORTION_CENTER * 0.95);
  1419. colorMode(HSB);
  1420. fill(darken(contextColor));
  1421. colorMode(RGB);
  1422. Diff d = diffs[hitContext];
  1423. String available = getIntersection(c,d);
  1424. String missing = getMissing(d);
  1425. String diffMessage = c.title + " (" + c.plSum + ")\n";
  1426. if(d.intersect.length > 0) { diffMessage += "\nAvailable: \n" + available; }
  1427. if(d.except.length > 0){ diffMessage += "\nMissing: \n" + missing;}
  1428. textAlign(CENTER,CENTER);
  1429. text(diffMessage, centerX, centerY);
  1430. }
  1431. //draw Sectors for each context as pie pieces
  1432. void drawSectors()
  1433. {
  1434. noStroke();
  1435. int count = 0;
  1436. float begin = (PI/2);
  1437. float end = begin + eqd_angle;
  1438. int previousContextType = contexts[0].contextType;
  1439. for(Context context : contexts)
  1440. {
  1441. color contextColor = getColor(context.plMean, context.contextType);
  1442. colorMode(HSB);
  1443. color darkContextColor = darken(contextColor);
  1444. colorMode(RGB);
  1445. fill(contextColor);
  1446. arc(centerX, centerY, contextSize, contextSize, begin, end);
  1447. int ext = 20;
  1448. if(count == currentContext)
  1449. {
  1450. noStroke();
  1451. arc(centerX, centerY, contextSize + ext , contextSize + ext, begin, end);
  1452. }
  1453. if(context.contextType != previousContextType)
  1454. {
  1455. stroke(255);
  1456. strokeWeight(3);
  1457. }
  1458. else
  1459. {
  1460. ext = 0;
  1461. stroke(darkContextColor);
  1462. strokeWeight(1);
  1463. }
  1464. //draw white line as divider
  1465. float angle = (PI/2) + (count * eqd_angle);
  1466. float x = centerX + (contextSize/2 + ext) * cos(angle);
  1467. float y = centerY + (contextSize/2 + ext) * sin(angle);
  1468. line(centerX,centerY,x,y);
  1469. noStroke();
  1470. strokeWeight(1);
  1471. begin = end;
  1472. end = begin + eqd_angle;
  1473. previousContextType = context.contextType;
  1474. count++;
  1475. }
  1476. //draw first white divider from center down.
  1477. stroke(255);
  1478. strokeWeight(3);
  1479. line(centerX,centerY,centerX,centerY + contextSize/2);
  1480. strokeWeight(1);
  1481. }
  1482. //draw outer rim
  1483. void drawBorder()
  1484. {
  1485. Context current = contexts[currentContext];
  1486. //set up colors for current context
  1487. color contextColor = getColor(current.plMean, current.contextType);
  1488. colorMode(HSB);
  1489. color darkContextColor = darken(contextColor);
  1490. colorMode(RGB);
  1491. stroke(darkContextColor);
  1492. fill(255);
  1493. ellipse(centerX, centerY, contextSize + 10, contextSize + 10);
  1494. }
  1495. //draw title
  1496. void drawTitle()
  1497. {
  1498. textFont(titleFont);
  1499. fill(150);
  1500. textAlign(CENTER);
  1501. text("Do you want to entitle " + request.application + " ?\nPlease drag the request on to your preferred context." , centerX, 80);
  1502. }
  1503. /* interaction functions */
  1504. void mousePressed()
  1505. {
  1506. //test if request hit
  1507. boolean hitRequest = (mouseX > requestX - requestSize/2 && mouseX < requestX + requestSize/2 &&
  1508. mouseY > requestY - requestSize/2 && mouseY < requestY + requestSize/2);
  1509. //update global
  1510. dragging = hitRequest;
  1511. //test if context hit
  1512. float deltaX = mouseX - centerX;
  1513. float deltaY = mouseY - centerY;
  1514. int index = hitContextIndex(deltaX,deltaY);
  1515. if(index > -1)
  1516. {
  1517. currentContext = index;
  1518. }
  1519. }
  1520. void mouseDragged()
  1521. {
  1522. float deltaX = mouseX - centerX;
  1523. float deltaY = mouseY - centerY;
  1524. float distance = sqrt(deltaX*deltaX + deltaY*deltaY);
  1525. float fraction = distance / (contextSize / 2);
  1526. float minDistanceFactor = (PROPORTION_CENTER + (1-PROPORTION_CENTER)/2);
  1527. //outside the circle is allowed anywhere
  1528. if(fraction > minDistanceFactor && dragging)
  1529. {
  1530. requestX = mouseX - xOffset;
  1531. requestY = mouseY - yOffset;
  1532. hitContext = hitContextIndex(deltaX,deltaY);
  1533. if(hitContext > -1){currentContext = hitContext;}
  1534. }
  1535. else if(dragging) //else calculate closest point that is allowed
  1536. {
  1537. float mouseAngle = (PI/2) - atan2(deltaX, deltaY);
  1538. float x = centerX + (contextSize/2 * minDistanceFactor) * cos(mouseAngle); //calculate xPos
  1539. float y = centerY + (contextSize/2 * minDistanceFactor) * sin(mouseAngle); //calculate yPos
  1540. requestX = x;
  1541. requestY = y;
  1542. hitContext = hitContextIndex(x - centerX, y - centerY);
  1543. currentContext = hitContext;
  1544. }
  1545. }
  1546. void mouseReleased()
  1547. {
  1548. dragging = false;
  1549. //hitContext = -1;
  1550. //PVector position = positionForSectorIndex(1);
  1551. //requestX = position.x;
  1552. //requestY = position.y;
  1553. }
  1554. //calculate which pie part was clicked,
  1555. //by means of the angle between the mouse point an the center of the circle
  1556. //returns -1 if no pie part was clicked
  1557. //(because the distance is not between 0.8 and 1 times the distanceSize)
  1558. int hitContextIndex(float deltaX, float deltaY)
  1559. {
  1560. float distance = sqrt(deltaX*deltaX + deltaY*deltaY);
  1561. float fraction = distance / (contextSize / 2);
  1562. if(fraction < PROPORTION_CENTER || fraction > 1)
  1563. {
  1564. return -1;
  1565. }
  1566. //overstaande, aanliggende => tan dus atan2
  1567. float mouseAngle = atan2(deltaX, deltaY);
  1568. float degrees = mouseAngle * 180 / PI;
  1569. if(degrees < 0){degrees = 360 + degrees;} //so everyting is on one continuum
  1570. float part = eqd_angle * 180 /PI;
  1571. int index = (contexts.length - ((int) (degrees / part))) - 1;//because we start at the bottom.
  1572. return index;
  1573. }
  1574. /* data functions */
  1575. //create a string that lists the values of the intersection in d, with the values in c
  1576. String getIntersection(Context c, Diff d)
  1577. {
  1578. String result = "";
  1579. for(String key : d.intersect)
  1580. {
  1581. String value = getPropertyValue(c, key);
  1582. if(value != null) result += key.substring(key.indexOf(":")+1) + " (" + value + ")\n";
  1583. }
  1584. return result;
  1585. }
  1586. //create a string that lists the missing keys in the intersection d
  1587. String getMissing(Diff d)
  1588. {
  1589. String result = "";
  1590. for(String key : d.except)
  1591. {
  1592. result += key.substring(key.indexOf(":")+1) + "\n";
  1593. }
  1594. return result;
  1595. }
  1596. //get the value of a property value in c designated by key
  1597. String getPropertyValue(Context c, String key)
  1598. {
  1599. int MAX_LENGTH = 10;
  1600. for(Property p : c.properties)
  1601. {
  1602. if(p.type == key)
  1603. {
  1604. String value = p.value;
  1605. if(value.length > MAX_LENGTH)
  1606. {
  1607. value = value.substring(0, Math.min(value.length(), MAX_LENGTH)) + "...";
  1608. }
  1609. return value;
  1610. }
  1611. }
  1612. return null;
  1613. }
  1614. </script> <canvas id="ob-012f45a13f3c9558ffb5644a19192df95c5288cd"></canvas>
  1615. </div>
  1616. </div>
  1617. </div>
  1618. <div id="postamble" class="status">
  1619. <p class="author">Author: Taco</p>
  1620. <p class="date">Created: 2018-04-20 Fri 16:44</p>
  1621. <p class="validation"><a href="http://validator.w3.org/check?uri=referer">Validate</a></p>
  1622. </div>
  1623. </body>
  1624. </html>