aboutsummaryrefslogtreecommitdiff
path: root/stdlib/source/test/lux/control/security/policy.lux
blob: d193cc159bf44439f840a865b84f31adba34b4a1 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
(.module:
  [lux #*
   ["_" test (#+ Test)]
   [abstract
    [equivalence (#+)]
    [hash (#+ Hash)]
    [monad (#+ do)]
    {[0 #spec]
     [/
      ["$." functor (#+ Injection Comparison)]
      ["$." apply]
      ["$." monad]]}]
   [control
    [security
     ["!" capability]]]
   [data
    ["." name]
    ["." text ("#@." equivalence)]
    [number
     ["n" nat]]]
   [math
    ["r" random]]]
  {1
   ["." / (#+ Context Privacy Can-Conceal Can-Reveal Privilege Private with-policy)]})

(def: (injection can-conceal)
  (All [label]
    (-> (Can-Conceal label) (Injection (All [value] (Private value label)))))
  (!.use can-conceal))

(def: (comparison can-reveal)
  (All [label]
    (-> (Can-Reveal label) (Comparison (All [value] (Private value label)))))
  (function (_ == left right)
    (== (!.use can-reveal left)
        (!.use can-reveal right))))

(type: Password (Private Text))

(signature: (Policy %)
  (: (Hash (Password %))
     &hash)

  (: (-> Text (Password %))
     password)

  (: (Privilege Privacy %)
     privilege))

(def: (policy _)
  (Ex [%] (-> Any (Policy %)))
  (with-policy
    (: (Context Privacy Policy)
       (function (_ (^@ privilege (^open "%@.")))
         (structure
          (def: &hash
            (structure
             (def: &equivalence
               (structure (def: (= reference sample)
                            (text@= (!.use %@can-downgrade reference)
                                    (!.use %@can-downgrade sample)))))
             (def: hash
               (|>> (!.use %@can-downgrade)
                    (:: text.hash hash)))))
          
          (def: password
            (!.use %@can-upgrade))

          (def: privilege
            privilege))))))

(def: #export test
  Test
  (<| (_.context (name.module (name-of /._)))
      (do r.monad
        [#let [policy-0 (policy [])]
         raw-password (r.ascii 10)
         #let [password (:: policy-0 password raw-password)]]
        ($_ _.and
            ($functor.spec (..injection (:: policy-0 can-upgrade)) (..comparison (:: policy-0 can-downgrade)) /.functor)
            ($apply.spec (..injection (:: policy-0 can-upgrade)) (..comparison (:: policy-0 can-downgrade)) /.apply)
            ($monad.spec (..injection (:: policy-0 can-upgrade)) (..comparison (:: policy-0 can-downgrade)) /.monad)

            (_.test "Can work with private values under the same label."
                    (and (:: policy-0 = password password)
                         (n.= (:: text.hash hash raw-password)
                              (:: policy-0 hash password))))
            (let [policy-1 (policy [])
                  delegate (/.delegation (:: policy-0 can-downgrade) (:: policy-1 can-upgrade))]
              (_.test "Can use delegation to share private values between policies."
                      (:: policy-1 = (delegate password) (delegate password))))
            ))))