Entitlements user interaction designs and proof of concept

entitlements.org 33KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130
  1. #+HTML_HEAD: <link rel="stylesheet" type="text/css" href="http://thomasf.github.io/solarized-css/solarized-light.min.css" />
  2. * Introduction
  3. The purpose of this document is to investigate possible User Interaction designs for Decode task 4.4.
  4. 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.
  5. A prelimary definition of six privacy levels (ordered from most private to least private):
  6. - SECRET: passwords, keys etc.
  7. - PRIVATE: ssn etc, strict need to know basis stuff
  8. - INTIMATE: e.g. stuff you share with family
  9. - AFFILIATE: e.g. stuff you share with work, project etc
  10. - PUBLIC: e.g. stuff that everybody may know, your e.g. twitter handle
  11. - COMMONS: stuff that is intended for the public good / commons, e.g. anonimized IoT stuff
  12. A preliminary definition of context types
  13. - PERSONAL: data that relates to your personal life, you can have different instances, for example friends, family etc.
  14. - HEALTH: health data, you can define different instances (biosignals, stuff to share with dentist, gp, hospital etc)
  15. - EDUCATION: school / educational data (grades, certificates etc)
  16. - WORK: stuff you share in a professional context
  17. - HOBBY: stuff you share in the context of a pastime
  18. - FINANCIAL: for data about mortgages, insurance, taxes etc.
  19. - OTHER: for everything that doesn't fit the above
  20. * Data Model
  21. ** Example wallet profile
  22. This sample wallet profile datastructure consists of multiple contexts.
  23. No assumptions are made about ontology for now so mention of existing e.g. skos/foaf,
  24. everything is in the decode namespace which is well known across applications.
  25. Each context has a name and groups on or more properties that consist of a well known type and a value.
  26. A type can be part of more than one context.
  27. Every property instance has a privacy level attached to it, so we can calculate the weight of requests and profiles.
  28. It overrides the default privacy level specified by the property type.
  29. #+name: profile
  30. #+begin_src js :results output
  31. var profile = {
  32. contexts :
  33. [
  34. {
  35. title : "personal",
  36. properties :
  37. [
  38. {
  39. type : "decode:name",
  40. value: "Taco van Dijk",
  41. pl: 1 //public, everyone may know my name
  42. },
  43. {
  44. type : "decode:email",
  45. value : "[REDACTED]",
  46. pl: 2 //affiliate, parties i have personal business with may know
  47. },
  48. {
  49. type: "decode:address",
  50. value: "[REDACTED]",
  51. pl: 2 //affiliate, parties i have personal business with may know
  52. },
  53. {
  54. type: "decode:phone",
  55. value : "[REDACTED]",
  56. pl: 2 //affiliate, parties i have personal business with may know
  57. }
  58. ],
  59. pl_sum: 7 //this is a calculated value based on the attributed pl values or default if they were not user specified
  60. },
  61. {
  62. title: "professional",
  63. properties :
  64. [
  65. {
  66. type : "decode:name",
  67. value : "Taco van Dijk",
  68. pl: 1
  69. },
  70. {
  71. type : "decode:email",
  72. value : "taco@waag.org",
  73. pl: 2
  74. },
  75. {
  76. type : "decode:address",
  77. value : "St. Antoniesbreestraat 69",
  78. pl: 1 //since this is shared with all my colleagues i find this public
  79. }
  80. ],
  81. pl_sum: 4
  82. }
  83. ]
  84. };
  85. process.stdout.write(JSON.stringify(profile));
  86. #+end_src
  87. #+RESULTS: profile
  88. : {"contexts":[{"title":"personal","properties":[{"type":"decode:name","value":"Taco van Dijk","pl":1},{"type":"decode:email","value":"[REDACTED]","pl":2},{"type":"decode:address","value":"[REDACTED]","pl":2},{"type":"decode:phone","value":"[REDACTED]","pl":2}],"pl_sum":7},{"title":"professional","properties":[{"type":"decode:name","value":"Taco van Dijk","pl":1},{"type":"decode:email","value":"taco@waag.org","pl":2},{"type":"decode:address","value":"St. Antoniesbreestraat 69","pl":1}],"pl_sum":4}]}
  89. *** Things to further investigate
  90. - Apply default weights to each property type, these can be overridden by attributing a privacy level to the property
  91. - Make a big list of possible property types (at least properties that are used in Gebied Online)
  92. - Make a big list of possible context names
  93. - Create a generator that seeds profiles with random contexts from the aforementioned lists.
  94. ** Example request
  95. This sample application request consists of an application name, a set of required property types and a set of optional property types.
  96. Each application has a default context type attached to it, (so we can assign it a hue).
  97. For each request we can calculate the average privacy level,
  98. and the cumulative privacy weight by adding the privacy levels of each property in the request.
  99. #+name: request
  100. #+BEGIN_SRC js :results output
  101. var request = {
  102. application : "decodeapp:facebook",
  103. context_type : 0,//personal
  104. required : ["decode:name", "decode:email", "decode:address"],
  105. optional : ["decode:phone"]
  106. }
  107. var data = JSON.stringify(request) + "\n";
  108. process.stdout.write(data);
  109. #+END_SRC
  110. #+RESULTS: request
  111. : {"application":"decodeapp:facebook","context_type":0,"required":["decode:name","decode:email","decode:address"],"optional":["decode:phone"]}
  112. *** Things to further investigate
  113. - Create a generator that seeds a request with random required and optional property types
  114. - Attribute a default context type to the application
  115. * Data Comparison
  116. During the interaction we want to give the user insight into a couple of things;
  117. - How does the requested set of properties relate to the different contexts? How well does a context match to the request?
  118. - 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?
  119. - What would it mean for the cumulative weight of the context?
  120. In below ruby code a comparison is made by on creating the intersection and its inverse between the request and each context.
  121. #+name: diff_src
  122. #+BEGIN_SRC ruby
  123. require 'json'
  124. require 'nokogiri' #for creating xml
  125. request = JSON.parse(request_data)
  126. profile = JSON.parse(profile_data)
  127. context_diffs = []
  128. profile["contexts"].each do | context |
  129. requested = request["required"] + request["optional"]
  130. available = context["properties"].map {|p| p["type"]}
  131. intersect = available & requested
  132. except = requested - available
  133. diff = {:context => context["title"], :intersect => intersect, :except => except}
  134. context_diffs << diff
  135. end
  136. #+END_SRC
  137. #+name: xml
  138. #+BEGIN_SRC ruby :exports none
  139. # unfortunately processing.js doesn't support json yet, so we have to use xml
  140. doc = Nokogiri::XML::Builder.new do |xml|
  141. xml.result {
  142. xml.request {
  143. xml.application request["application"]
  144. xml.contextType request["context_type"]
  145. xml.required {
  146. request["required"].each do |p| xml.property p end
  147. }
  148. xml.optional {
  149. request["optional"].each do |p| xml.property p end
  150. }
  151. }
  152. xml.diffs {
  153. context_diffs.each do |diff|
  154. xml.diff {
  155. xml.contextName diff[:context]
  156. xml.intersect {
  157. diff[:intersect].each do |p| xml.property p end
  158. }
  159. xml.except {
  160. diff[:except].each do |p| xml.property p end
  161. }
  162. }
  163. end
  164. }
  165. xml.profile {
  166. profile["contexts"].each do | context |
  167. xml.contextObj {
  168. xml.contextName context["title"]
  169. xml.plSum context["pl_sum"]
  170. xml.properties {
  171. context["properties"].each do |property|
  172. xml.property {
  173. xml.type property["type"]
  174. xml.value property["value"]
  175. xml.pl property["pl"]
  176. }
  177. end
  178. }
  179. }
  180. end
  181. }
  182. }
  183. end
  184. path = "diff.xml"
  185. File.write(path, doc.to_xml)
  186. path
  187. #+END_SRC
  188. #+name: diff
  189. #+BEGIN_SRC ruby :exports none :noweb yes :var profile_data=profile :var request_data=request :results value file
  190. <<diff_src>>
  191. <<xml>>
  192. #+END_SRC
  193. #+RESULTS: diff
  194. [[file:diff.xml]]
  195. *** Things to further investigate
  196. - Calculate the weight (sum of privacy levels of the properties it contains) of each context before and after giving permission
  197. NOTE: We export to file diff.xml here for easy parsing in processing.js below.
  198. /de relatieve grootte van de cirkel kan zijn op basis van hoeveel data je erin hebt.
  199. personal is size 4, professional size 3
  200. request is size 3
  201. * Visualization
  202. We want to visualize the following things;
  203. - The request with the application name and it's size / quality (Who's asking what)
  204. - The different contexts with it's name and size / quality relative to the request. (What would it mean to accept?)
  205. Per the design of Dyne, we want to use color to indicate the relation between the request and each context.
  206. A color should indicate something about privacy level and context type.
  207. For now the mapping is as follows;
  208. Different hues can be mapped to each context type.
  209. Different tones within the hue can be mapped to each privacy level.
  210. #+name: colors
  211. #+BEGIN_SRC java
  212. //color definitions
  213. color a3 = #3A3B58;
  214. color b3 = #734246;
  215. color d3 = #B4561F;
  216. color c3 = #336F60;
  217. color f3 = #7A3E2A;
  218. color g3 = #A48137;
  219. color e2 = #97BBCB;
  220. color a4 = #3B4257;
  221. color b4 = #6A4345;
  222. color d4 = #86451F;
  223. color c4 = #345A48;
  224. color f4 = #A92F21;
  225. color g4 = #BC983B;
  226. color a5 = #3D4358;
  227. color b5 = #402623;
  228. color d5 = #85442D;
  229. color c5 = #3B403A;
  230. color f5 = #7A150B;
  231. color g5 = #252F2B;
  232. color a1 = #597099;
  233. color e4 = #0A3878;
  234. color b1 = #D16365;
  235. color d1 = #FFD43B;
  236. color c1 = #B7BF98;
  237. color e1 = #CAD2C8;
  238. color e0 = #F5EDE5;
  239. color f1 = #D17978;
  240. color g1 = #FDD23E;
  241. color a0 = #C5C3CC;
  242. color e3 = #0485B1;
  243. color b0 = #FFDCD6;
  244. color d0 = #FFE9BE;
  245. color c0 = #F0E9D5;
  246. color f0 = #E4C8BF;
  247. color g0 = #FBE6BA;
  248. color a2 = #3D4B79;
  249. color e5 = #084064;
  250. color b2 = #974244;
  251. color d2 = #F8AA08;
  252. color c2 = #4E937F;
  253. color f2 = #8F4330;
  254. color g2 = #FFDB03;
  255. color colors[][] = {
  256. {b0,b1,b2,b3,b4,b5},
  257. {c0,c1,c2,c3,c4,c5},
  258. {a0,a1,a2,a3,a4,a5},
  259. {d0,d1,d2,d3,d4,d5},
  260. {e0,e1,e2,e3,e4,e5},
  261. {f0,f1,f2,f3,f4,f5},
  262. {g0,g1,g2,g3,g4,g5}
  263. };
  264. class PrivacyLevel {
  265. public static int SECRET = 5; //passwords, keys etc.
  266. public static int PRIVATE = 4;//ssn etc, strict need to know basis stuff
  267. public static int INTIMATE = 3;//e.g. stuff you share with family
  268. public static int AFFILIATE = 2;//e.g. stuff you share with work, project etc
  269. public static int PUBLIC = 1;//e.g. stuff that everybody may know, your e.g. twitter handle
  270. public static int COMMONS = 0;//stuff that is intended for the public good / commons, anonimized IoT stuff
  271. }
  272. class ContextType {
  273. public static int SELF = 5; //stuff that applies strictly to yourself
  274. public static int FAMILY = 4;//stuff that applies to you and your family (hopefully not facebook pics)
  275. public static int FRIENDS = 3;//stuff you share with friends
  276. public static int WORK = 2;//stuff you share in a professional context
  277. public static int HOBBY = 1;//stuff you share in the context of a pastime
  278. public static int OTHER = 0;//stuff that doesn't fit in any of the other types
  279. }
  280. public int getColor(int privacy_level, int context_type)
  281. {
  282. return colors[context_type][privacy_level];
  283. }
  284. #+END_SRC
  285. Below snippet exemplifies a color for the SELF context with a privacy level SECRET, and should be a dark red color.
  286. #+name: color_example_src_1
  287. #+BEGIN_SRC java
  288. void draw(){
  289. size(100,100);
  290. background(0);
  291. noStroke();
  292. int level = PrivacyLevel.SECRET;
  293. int contextType = ContextType.SELF;
  294. color secret_self = getColor(level, contextType);//expect dark red
  295. fill(secret_self);
  296. ellipse(50,50,50,50);
  297. }
  298. #+END_SRC
  299. #+name: color_example_1
  300. #+BEGIN_SRC processing :noweb yes
  301. <<colors>>
  302. <<color_example_src_1>>
  303. #+END_SRC
  304. #+RESULTS: color_example_1
  305. #+BEGIN_EXPORT html
  306. <script src="processing.js"></script>
  307. <script type="text/processing" data-processing-target="ob-e4084f25c6566c618f6cc091e4920fd86e9b1c21">
  308. //color definitions
  309. color a3 = #3A3B58;
  310. color b3 = #734246;
  311. color d3 = #B4561F;
  312. color c3 = #336F60;
  313. color f3 = #7A3E2A;
  314. color g3 = #A48137;
  315. color e2 = #97BBCB;
  316. color a4 = #3B4257;
  317. color b4 = #6A4345;
  318. color d4 = #86451F;
  319. color c4 = #345A48;
  320. color f4 = #A92F21;
  321. color g4 = #BC983B;
  322. color a5 = #3D4358;
  323. color b5 = #402623;
  324. color d5 = #85442D;
  325. color c5 = #3B403A;
  326. color f5 = #7A150B;
  327. color g5 = #252F2B;
  328. color a1 = #597099;
  329. color e4 = #0A3878;
  330. color b1 = #D16365;
  331. color d1 = #FFD43B;
  332. color c1 = #B7BF98;
  333. color e1 = #CAD2C8;
  334. color e0 = #F5EDE5;
  335. color f1 = #D17978;
  336. color g1 = #FDD23E;
  337. color a0 = #C5C3CC;
  338. color e3 = #0485B1;
  339. color b0 = #FFDCD6;
  340. color d0 = #FFE9BE;
  341. color c0 = #F0E9D5;
  342. color f0 = #E4C8BF;
  343. color g0 = #FBE6BA;
  344. color a2 = #3D4B79;
  345. color e5 = #084064;
  346. color b2 = #974244;
  347. color d2 = #F8AA08;
  348. color c2 = #4E937F;
  349. color f2 = #8F4330;
  350. color g2 = #FFDB03;
  351. color colors[][] = {
  352. {a0,a1,a2,a3,a4,a5},
  353. {b0,b1,b2,b3,b4,b5},
  354. {c0,c1,c2,c3,c4,c5},
  355. {d0,d1,d2,d3,d4,d5},
  356. {e0,e1,e2,e3,e4,e5},
  357. {f0,f1,f2,f3,f4,f5},
  358. {g0,g1,g2,g3,g4,g5}
  359. };
  360. class PrivacyLevel {
  361. public static int SECRET = 5; //passwords, keys etc.
  362. public static int PRIVATE = 4;//ssn etc, strict need to know basis stuff
  363. public static int INTIMATE = 3;//e.g. stuff you share with family
  364. public static int AFFILIATE = 2;//e.g. stuff you share with work, project etc
  365. public static int PUBLIC = 1;//e.g. stuff that everybody may know, your e.g. twitter handle
  366. public static int COMMONS = 0;//stuff that is intended for the public good / commons, anonimized IoT stuff
  367. }
  368. class ContextType {
  369. public static int SELF = 5; //stuff that applies strictly to yourself
  370. public static int FAMILY = 4;//stuff that applies to you and your family (hopefully not facebook pics)
  371. public static int FRIENDS = 3;//stuff you share with friends
  372. public static int WORK = 2;//stuff you share in a professional context
  373. public static int HOBBY = 1;//stuff you share in the context of a pastime
  374. public static int OTHER = 0;//stuff that doesn't fit in any of the other types
  375. }
  376. public int getColor(int privacy_level, int context_type)
  377. {
  378. return colors[context_type][privacy_level];
  379. }
  380. void draw(){
  381. size(100,100);
  382. background(0);
  383. noStroke();
  384. int level = PrivacyLevel.SECRET;
  385. int contextType = ContextType.SELF;
  386. color secret_self = getColor(level, contextType);//should be dark red
  387. fill(secret_self);
  388. ellipse(50,50,50,50);
  389. }
  390. </script> <canvas id="ob-e4084f25c6566c618f6cc091e4920fd86e9b1c21"></canvas>
  391. #+END_EXPORT
  392. #+name: color_example_src_2
  393. #+BEGIN_SRC java
  394. void draw(){
  395. size(100,100);
  396. background(0);
  397. noStroke();
  398. int level = PrivacyLevel.PUBLIC;
  399. int contextType = ContextType.WORK;
  400. color work_public = getColor(level, contextType);//expect light blueish
  401. fill(work_public);
  402. ellipse(50,50,50,50);
  403. }
  404. #+END_SRC
  405. #+name: color_example_2
  406. #+BEGIN_SRC processing :noweb yes
  407. <<colors>>
  408. <<color_example_src_2>>
  409. #+END_SRC
  410. #+RESULTS: color_example_2
  411. #+BEGIN_EXPORT html
  412. <script src="processing.js"></script>
  413. <script type="text/processing" data-processing-target="ob-760b680df1e803a95f5ec520fa92b091eca605c2">
  414. //color definitions
  415. color a3 = #3A3B58;
  416. color b3 = #734246;
  417. color d3 = #B4561F;
  418. color c3 = #336F60;
  419. color f3 = #7A3E2A;
  420. color g3 = #A48137;
  421. color e2 = #97BBCB;
  422. color a4 = #3B4257;
  423. color b4 = #6A4345;
  424. color d4 = #86451F;
  425. color c4 = #345A48;
  426. color f4 = #A92F21;
  427. color g4 = #BC983B;
  428. color a5 = #3D4358;
  429. color b5 = #402623;
  430. color d5 = #85442D;
  431. color c5 = #3B403A;
  432. color f5 = #7A150B;
  433. color g5 = #252F2B;
  434. color a1 = #597099;
  435. color e4 = #0A3878;
  436. color b1 = #D16365;
  437. color d1 = #FFD43B;
  438. color c1 = #B7BF98;
  439. color e1 = #CAD2C8;
  440. color e0 = #F5EDE5;
  441. color f1 = #D17978;
  442. color g1 = #FDD23E;
  443. color a0 = #C5C3CC;
  444. color e3 = #0485B1;
  445. color b0 = #FFDCD6;
  446. color d0 = #FFE9BE;
  447. color c0 = #F0E9D5;
  448. color f0 = #E4C8BF;
  449. color g0 = #FBE6BA;
  450. color a2 = #3D4B79;
  451. color e5 = #084064;
  452. color b2 = #974244;
  453. color d2 = #F8AA08;
  454. color c2 = #4E937F;
  455. color f2 = #8F4330;
  456. color g2 = #FFDB03;
  457. color colors[][] = {
  458. {a0,a1,a2,a3,a4,a5},
  459. {b0,b1,b2,b3,b4,b5},
  460. {c0,c1,c2,c3,c4,c5},
  461. {d0,d1,d2,d3,d4,d5},
  462. {e0,e1,e2,e3,e4,e5},
  463. {f0,f1,f2,f3,f4,f5},
  464. {g0,g1,g2,g3,g4,g5}
  465. };
  466. class PrivacyLevel {
  467. public static int SECRET = 5; //passwords, keys etc.
  468. public static int PRIVATE = 4;//ssn etc, strict need to know basis stuff
  469. public static int INTIMATE = 3;//e.g. stuff you share with family
  470. public static int AFFILIATE = 2;//e.g. stuff you share with work, project etc
  471. public static int PUBLIC = 1;//e.g. stuff that everybody may know, your e.g. twitter handle
  472. public static int COMMONS = 0;//stuff that is intended for the public good / commons, anonimized IoT stuff
  473. }
  474. class ContextType {
  475. public static int SELF = 5; //stuff that applies strictly to yourself
  476. public static int FAMILY = 4;//stuff that applies to you and your family (hopefully not facebook pics)
  477. public static int FRIENDS = 3;//stuff you share with friends
  478. public static int WORK = 2;//stuff you share in a professional context
  479. public static int HOBBY = 1;//stuff you share in the context of a pastime
  480. public static int OTHER = 0;//stuff that doesn't fit in any of the other types
  481. }
  482. public int getColor(int privacy_level, int context_type)
  483. {
  484. return colors[context_type][privacy_level];
  485. }
  486. void draw(){
  487. size(100,100);
  488. background(0);
  489. noStroke();
  490. int level = PrivacyLevel.PUBLIC;
  491. int contextType = ContextType.WORK;
  492. color secret_self = getColor(level, contextType);//should be light blueish
  493. fill(secret_self);
  494. ellipse(50,50,50,50);
  495. }
  496. </script> <canvas id="ob-760b680df1e803a95f5ec520fa92b091eca605c2"></canvas>
  497. #+END_EXPORT
  498. #+name: glue
  499. #+BEGIN_SRC java :exports none
  500. class Request
  501. {
  502. public String application;
  503. public int contextType;
  504. public String[] required_properties;
  505. public String[] optional_properties;
  506. public Request(String app, int contextType, String[] req, String[] opt)
  507. {
  508. this.application = app;
  509. this.contextType = contextType;
  510. this.required_properties = req;
  511. this.optional_properties = opt;
  512. }
  513. }
  514. class Diff
  515. {
  516. public String context;
  517. public String[] intersect;
  518. public String[] except;
  519. public Diff(String ctx, String[] intersect, String[] except)
  520. {
  521. this.context = ctx;
  522. this.intersect = intersect;
  523. this.except = except;
  524. }
  525. }
  526. class Property
  527. {
  528. public String type;
  529. public String value;
  530. public int pl;//privacy level
  531. public Property(String type, String value, int pl)
  532. {
  533. this.type = type;
  534. this.value = value;
  535. this.pl = pl;
  536. }
  537. }
  538. class Context
  539. {
  540. public String title;
  541. public int plSum;
  542. public Property[] properties;
  543. public Context(String title, int plSum, Property[] properties)
  544. {
  545. this.title = title;
  546. this.plSum = plSum;
  547. this.properties = properties;
  548. }
  549. }
  550. XMLElement doc = new XMLElement(this, 'diff.xml');
  551. //create typed versions because this is java :-(
  552. Request parseRequest(XMLElement xml)
  553. {
  554. XMLElement req = xml.getChild(0);
  555. String name = req.getChild(0).getContent();
  556. int contextType = req.getChild(1).getContent();
  557. String[] required = new String[req.getChild(2).getChildCount()];
  558. String[] optional = new String[req.getChild(3).getChildCount()];
  559. for (int i = 0; i < required.length; i++) {
  560. required[i] = req.getChild(2).getChild(i).getContent();
  561. }
  562. for (int i = 0; i < optional.length; i++) {
  563. optional[i] = req.getChild(3).getChild(i).getContent();
  564. }
  565. Request r = new Request(name,contextType,required,optional);
  566. return r;
  567. }
  568. Context[] parseProfile(XMLElement xml)
  569. {
  570. XMLElement profile = xml.getChild(2);
  571. Context[] contexts = new Context[profile.getChildCount()];
  572. for(int i = 0; i < contexts.length; i++)
  573. {
  574. String contextName = profile.getChild(i).getChild(0).getContent();
  575. int plSum = parseInt(profile.getChild(i).getChild(1).getContent());
  576. XMLElement propertiesEl = profile.getChild(i).getChild(2);
  577. Property[] properties = new Property[propertiesEl.getChildCount()];
  578. for(int j = 0; j < properties.length; j++)
  579. {
  580. Property prop = parseProperty(propertiesEl.getChild(j));
  581. properties[j] = prop;
  582. }
  583. Context context = new Context(contextName, plSum, properties);
  584. contexts[i] = context;
  585. }
  586. return contexts;
  587. }
  588. Property parseProperty(XMLElement propertyEl)
  589. {
  590. String propertyType = propertyEl.getChild(0).getContent();
  591. String value = propertyEl.getChild(1).getContent();
  592. int pl = parseInt(propertyEl.getChild(2).getContent());
  593. return new Property(propertyType, value, pl);
  594. }
  595. //create typed versions because this is java :-(
  596. Diff[] parseDiffs(xml)
  597. {
  598. XMLElement diffsEl = xml.getChild(1);
  599. Diff[] diffs = new Diff[diffsEl.getChildCount()];
  600. for(int i = 0; i < diffs.length; i++)
  601. {
  602. String contextName = diffsEl.getChild(i).getChild(0).getContent();
  603. String[] intersects = new String[diffsEl.getChild(i).getChild(1).getChildCount()];
  604. String[] except = new String[diffsEl.getChild(i).getChild(2).getChildCount()];
  605. for(int j = 0; j < intersects.length; j++)
  606. {
  607. intersects[j] = diffsEl.getChild(i).getChild(1).getChild(j).getContent();
  608. }
  609. for(int j = 0; j < except.length; j++)
  610. {
  611. except[j] = diffsEl.getChild(i).getChild(2).getChild(j).getContent();
  612. }
  613. Diff diff = new Diff(contextName,intersects,except);
  614. diffs[i] = diff;
  615. }
  616. return diffs;
  617. }
  618. Request request = parseRequest(doc);
  619. Diff[] diffs = parseDiffs(doc);
  620. Context[] contexts = parseProfile(doc);
  621. #+END_SRC
  622. ** Request
  623. #+name: draw_request_src
  624. #+BEGIN_SRC java
  625. size(200,200);
  626. //background(0);
  627. noFill();
  628. //the size of request is fixed for now
  629. ffloat centerX = width/2;
  630. float centerY = height/2;
  631. float rsize = 55;
  632. //color of request is mapped to the privacy type of the request, each request has one.
  633. //INTIMATE because it's in the middle of the privacy level continuum
  634. color reqColor = getColor(PrivacyLevel.INTIMATE, request.contextType);
  635. fill(reqColor);
  636. ellipse(centerX, centerY, rsize, rsize);
  637. //show the name of the application that makes the request, centered below the circle
  638. fill(0);
  639. textAlign(CENTER,CENTER);
  640. text(request.application, centerX, centerY + rsize/1.5);
  641. #+END_SRC
  642. #+name: draw_request
  643. #+BEGIN_SRC processing :noweb yes
  644. <<colors>>
  645. <<glue>>
  646. <<draw_request_src>>
  647. #+END_SRC
  648. #+RESULTS: draw_request
  649. #+BEGIN_EXPORT html
  650. <script src="processing.js"></script>
  651. <script type="text/processing" data-processing-target="ob-7bacb312f1e57618d3a25d1d7df81deb408229ff">
  652. //color definitions
  653. color a3 = #3A3B58;
  654. color b3 = #734246;
  655. color d3 = #B4561F;
  656. color c3 = #336F60;
  657. color f3 = #7A3E2A;
  658. color g3 = #A48137;
  659. color e2 = #97BBCB;
  660. color a4 = #3B4257;
  661. color b4 = #6A4345;
  662. color d4 = #86451F;
  663. color c4 = #345A48;
  664. color f4 = #A92F21;
  665. color g4 = #BC983B;
  666. color a5 = #3D4358;
  667. color b5 = #402623;
  668. color d5 = #85442D;
  669. color c5 = #3B403A;
  670. color f5 = #7A150B;
  671. color g5 = #252F2B;
  672. color a1 = #597099;
  673. color e4 = #0A3878;
  674. color b1 = #D16365;
  675. color d1 = #FFD43B;
  676. color c1 = #B7BF98;
  677. color e1 = #CAD2C8;
  678. color e0 = #F5EDE5;
  679. color f1 = #D17978;
  680. color g1 = #FDD23E;
  681. color a0 = #C5C3CC;
  682. color e3 = #0485B1;
  683. color b0 = #FFDCD6;
  684. color d0 = #FFE9BE;
  685. color c0 = #F0E9D5;
  686. color f0 = #E4C8BF;
  687. color g0 = #FBE6BA;
  688. color a2 = #3D4B79;
  689. color e5 = #084064;
  690. color b2 = #974244;
  691. color d2 = #F8AA08;
  692. color c2 = #4E937F;
  693. color f2 = #8F4330;
  694. color g2 = #FFDB03;
  695. color colors[][] = {
  696. {b0,b1,b2,b3,b4,b5},
  697. {c0,c1,c2,c3,c4,c5},
  698. {a0,a1,a2,a3,a4,a5},
  699. {d0,d1,d2,d3,d4,d5},
  700. {e0,e1,e2,e3,e4,e5},
  701. {f0,f1,f2,f3,f4,f5},
  702. {g0,g1,g2,g3,g4,g5}
  703. };
  704. class PrivacyLevel {
  705. public static int SECRET = 5; //passwords, keys etc.
  706. public static int PRIVATE = 4;//ssn etc, strict need to know basis stuff
  707. public static int INTIMATE = 3;//e.g. stuff you share with family
  708. public static int AFFILIATE = 2;//e.g. stuff you share with work, project etc
  709. public static int PUBLIC = 1;//e.g. stuff that everybody may know, your e.g. twitter handle
  710. public static int COMMONS = 0;//stuff that is intended for the public good / commons, anonimized IoT stuff
  711. }
  712. class ContextType {
  713. public static int SELF = 5; //stuff that applies strictly to yourself
  714. public static int FAMILY = 4;//stuff that applies to you and your family (hopefully not facebook pics)
  715. public static int FRIENDS = 3;//stuff you share with friends
  716. public static int WORK = 2;//stuff you share in a professional context
  717. public static int HOBBY = 1;//stuff you share in the context of a pastime
  718. public static int OTHER = 0;//stuff that doesn't fit in any of the other types
  719. }
  720. public int getColor(int privacy_level, int context_type)
  721. {
  722. return colors[context_type][privacy_level];
  723. }
  724. class Request
  725. {
  726. public String application;
  727. public int contextType;
  728. public String[] required_properties;
  729. public String[] optional_properties;
  730. public Request(String app, int contextType, String[] req, String[] opt)
  731. {
  732. this.application = app;
  733. this.contextType = contextType;
  734. this.required_properties = req;
  735. this.optional_properties = opt;
  736. }
  737. }
  738. class Diff
  739. {
  740. public String context;
  741. public String[] intersect;
  742. public String[] except;
  743. public Diff(String ctx, String[] intersect, String[] except)
  744. {
  745. this.context = ctx;
  746. this.intersect = intersect;
  747. this.except = except;
  748. }
  749. }
  750. class Property
  751. {
  752. public String type;
  753. public String value;
  754. public int pl;//privacy level
  755. public Property(String type, String value, int pl)
  756. {
  757. this.type = type;
  758. this.value = value;
  759. this.pl = pl;
  760. }
  761. }
  762. class Context
  763. {
  764. public String title;
  765. public int plSum;
  766. public Property[] properties;
  767. public Context(String title, int plSum, Property[] properties)
  768. {
  769. this.title = title;
  770. this.plSum = plSum;
  771. this.properties = properties;
  772. }
  773. }
  774. XMLElement doc = new XMLElement(this, 'diff.xml');
  775. //create typed versions because this is java :-(
  776. Request parseRequest(XMLElement xml)
  777. {
  778. XMLElement req = xml.getChild(0);
  779. String name = req.getChild(0).getContent();
  780. int contextType = req.getChild(1).getContent();
  781. String[] required = new String[req.getChild(2).getChildCount()];
  782. String[] optional = new String[req.getChild(3).getChildCount()];
  783. for (int i = 0; i < required.length; i++) {
  784. required[i] = req.getChild(2).getChild(i).getContent();
  785. }
  786. for (int i = 0; i < optional.length; i++) {
  787. optional[i] = req.getChild(3).getChild(i).getContent();
  788. }
  789. Request r = new Request(name,contextType,required,optional);
  790. return r;
  791. }
  792. Context[] parseProfile(XMLElement xml)
  793. {
  794. XMLElement profile = xml.getChild(2);
  795. Context[] contexts = new Context[profile.getChildCount()];
  796. for(int i = 0; i < contexts.length; i++)
  797. {
  798. String contextName = profile.getChild(i).getChild(0).getContent();
  799. int plSum = parseInt(profile.getChild(i).getChild(1).getContent());
  800. XMLElement propertiesEl = profile.getChild(i).getChild(2);
  801. Property[] properties = new Property[propertiesEl.getChildCount()];
  802. for(int j = 0; j < properties.length; j++)
  803. {
  804. Property prop = parseProperty(propertiesEl.getChild(j));
  805. properties[j] = prop;
  806. }
  807. Context context = new Context(contextName, plSum, properties);
  808. contexts[i] = context;
  809. }
  810. return contexts;
  811. }
  812. Property parseProperty(XMLElement propertyEl)
  813. {
  814. String propertyType = propertyEl.getChild(0).getContent();
  815. String value = propertyEl.getChild(1).getContent();
  816. int pl = parseInt(propertyEl.getChild(2).getContent());
  817. return new Property(propertyType, value, pl);
  818. }
  819. //create typed versions because this is java :-(
  820. Diff[] parseDiffs(xml)
  821. {
  822. XMLElement diffsEl = xml.getChild(1);
  823. Diff[] diffs = new Diff[diffsEl.getChildCount()];
  824. for(int i = 0; i < diffs.length; i++)
  825. {
  826. String contextName = diffsEl.getChild(i).getChild(0).getContent();
  827. String[] intersects = new String[diffsEl.getChild(i).getChild(1).getChildCount()];
  828. String[] except = new String[diffsEl.getChild(i).getChild(2).getChildCount()];
  829. for(int j = 0; j < intersects.length; j++)
  830. {
  831. intersects[j] = diffsEl.getChild(i).getChild(1).getChild(j).getContent();
  832. }
  833. for(int j = 0; j < except.length; j++)
  834. {
  835. except[j] = diffsEl.getChild(i).getChild(2).getChild(j).getContent();
  836. }
  837. Diff diff = new Diff(contextName,intersects,except);
  838. diffs[i] = diff;
  839. }
  840. return diffs;
  841. }
  842. Request request = parseRequest(doc);
  843. Diff[] diffs = parseDiffs(doc);
  844. Context[] contexts = parseProfile(doc);
  845. size(200,200);
  846. //background(0);
  847. noFill();
  848. stroke(255);
  849. //the size of request is fixed for now
  850. ffloat centerX = width/2;
  851. float centerY = height/2;
  852. float rsize = 55;
  853. //color of request is mapped to the privacy type of the request, each request has one.
  854. //INTIMATE because it's in the middle of the privacy level continuum
  855. color reqColor = getColor(PrivacyLevel.INTIMATE, request.contextType);
  856. fill(reqColor);
  857. ellipse(centerX, centerY, rsize, rsize);
  858. //show the name of the application that makes the request, centered below the circle
  859. fill(0);
  860. textAlign(CENTER,CENTER);
  861. text("hoezo", centerX, centerY + rsize/1.5);
  862. </script> <canvas id="ob-7bacb312f1e57618d3a25d1d7df81deb408229ff"></canvas>
  863. #+END_EXPORT
  864. ** Contexts
  865. How do we visulize each context? Intend to do this in processing too.
  866. #+name: draw_context_src
  867. #+BEGIN_SRC java
  868. //draw the difference for each context with the request
  869. size(200,200);
  870. background(0);
  871. noFill();
  872. stroke(255);
  873. ellipse(56, 46, 55, 55);
  874. text(diffs[0].context, 10, 10);
  875. text(contexts[0].properties[0].value, 10, 50);
  876. #+END_SRC
  877. #+name: draw_context
  878. #+BEGIN_SRC processing :noweb yes
  879. <<glue>>
  880. <<draw_context_src>>
  881. #+END_SRC
  882. #+RESULTS: draw_context
  883. #+BEGIN_EXPORT html
  884. <script src="processing.js"></script>
  885. <script type="text/processing" data-processing-target="ob-c5ac3c4c54147ecffc2f4eea88af7cca0a1a2f6d">
  886. class Request
  887. {
  888. public String application;
  889. public String[] required_properties;
  890. public String[] optional_properties;
  891. public Request(String app, String[] req, String[] opt)
  892. {
  893. this.application = app;
  894. this.required_properties = req;
  895. this.optional_properties = opt;
  896. }
  897. }
  898. class Diff
  899. {
  900. public String context;
  901. public String[] intersect;
  902. public String[] except;
  903. public Diff(String ctx, String[] intersect, String[] except)
  904. {
  905. this.context = ctx;
  906. this.intersect = intersect;
  907. this.except = except;
  908. }
  909. }
  910. //TODO: add Profile / Context / Property classes here
  911. class Context
  912. {
  913. public String title;
  914. public int plSum;
  915. public Context(String title, int plSum)
  916. {
  917. this.title = title;
  918. this.plSum = plSum;
  919. }
  920. }
  921. XMLElement doc = new XMLElement(this, 'diff.xml');
  922. //create typed versions because this is java :-(
  923. Request parseRequest(xml)
  924. {
  925. XMLElement req = xml.getChild(0);
  926. String name = req.getChild(0).getContent();
  927. String[] required = new String[req.getChild(1).getChildCount()];
  928. String[] optional = new String[req.getChild(2).getChildCount()];
  929. for (int i = 0; i < required.length; i++) {
  930. required[i] = req.getChild(1).getChild(i).getContent();
  931. }
  932. for (int i = 0; i < optional.length; i++) {
  933. optional[i] = req.getChild(2).getChild(i).getContent();
  934. }
  935. Request r = new Request(name,required,optional);
  936. return r;
  937. }
  938. Context[] parseProfile(xml)
  939. {
  940. //TODO: implement this! so that we can finally start on the real visualization
  941. XMLElement profile = xml.getChild(2);
  942. Context[] contexts = new Context[profile.getChildCount()];
  943. for(int i = 0; i < contexts.length; i++)
  944. {
  945. String contextName = profile.getChild(i).getChild(0).getContent();
  946. int plSum = profile.getChild(i).getChild(0).getContent();
  947. Context context = new Context(contextName, plSum);
  948. contexts[i] = context;
  949. }
  950. return contexts;
  951. }
  952. //create typed versions because this is java :-(
  953. Diff[] parseDiffs(xml)
  954. {
  955. XMLElement diffsEl = xml.getChild(1);
  956. Diff[] diffs = new Diff[diffsEl.getChildCount()];
  957. for(int i = 0; i < diffs.length; i++)
  958. {
  959. String contextName = diffsEl.getChild(i).getChild(0).getContent();
  960. String[] intersects = new String[diffsEl.getChild(i).getChild(1).getChildCount()];
  961. String[] except = new String[diffsEl.getChild(i).getChild(2).getChildCount()];
  962. for(int j = 0; j < intersects.length; j++)
  963. {
  964. intersects[j] = diffsEl.getChild(i).getChild(1).getChild(j).getContent();
  965. }
  966. for(int j = 0; j < except.length; j++)
  967. {
  968. except[j] = diffsEl.getChild(i).getChild(2).getChild(j).getContent();
  969. }
  970. Diff diff = new Diff(contextName,intersects,except);
  971. diffs[i] = diff;
  972. }
  973. return diffs;
  974. }
  975. Request request = parseRequest(doc);
  976. Diff[] diffs = parseDiffs(doc);
  977. Context[] contexts = parseProfile(doc);
  978. //draw the difference for each context with the request
  979. size(200,200);
  980. background(0);
  981. noFill();
  982. stroke(255);
  983. ellipse(56, 46, 55, 55);
  984. text(diffs[0].context, 10, 10);
  985. </script> <canvas id="ob-c5ac3c4c54147ecffc2f4eea88af7cca0a1a2f6d"></canvas>
  986. #+END_EXPORT
  987. *** Things to further investigate
  988. - How do we show relation between request and each context with color?
  989. - Can we use distance as well as color to indicate the relation?
  990. - Can we use size of the circle to indicate the weight, or use badges?
  991. * Interaction
  992. We intend to investigate this in Processing as well.
  993. *** Things to further investigate
  994. - How does the end user actually accept the request? Is it by dragging the request onto the context?
  995. - How does the end user decline the request?