Skip to content

Commit 4a87db3

Browse files
khietaandrewmwells-amazonBhakti Shah
authored
Add JSON interface for Lean code (#160)
Co-authored-by: Andrew Wells <[email protected]> Co-authored-by: Bhakti Shah <[email protected]>
1 parent e1d10d7 commit 4a87db3

29 files changed

+15203
-28
lines changed

cedar-lean/Cedar/Data/Map.lean

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,12 @@ def findOrErr {α β ε} [BEq α] (m : Map α β) (k : α) (err: ε) : Except ε
7474
| some v => ok v
7575
| _ => error err
7676

77+
/-- Returns the binding for `k` in `m`, or panics if none is found. -/
78+
def find! {α β} [Repr α] [BEq α] [Inhabited β] (m : Map α β) (k : α) : β :=
79+
match m.find? k with
80+
| some v => v
81+
| _ => panic! s!"find!: key {repr k} not found"
82+
7783
/-- Filters `m` using `f`. -/
7884
def filter {α β} (f : α → β → Bool) (m : Map α β) : Map α β :=
7985
Map.mk (m.kvs.filter (fun ⟨k, v⟩ => f k v))

cedar-lean/Cedar/Spec/Expr.lean

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -66,12 +66,11 @@ inductive Expr where
6666

6767
----- Derivations -----
6868

69-
deriving instance Repr, DecidableEq for Var
70-
deriving instance Repr, DecidableEq for UnaryOp
71-
deriving instance Repr, DecidableEq for BinaryOp
69+
deriving instance Repr, DecidableEq, Inhabited for Var
70+
deriving instance Repr, DecidableEq, Inhabited for UnaryOp
71+
deriving instance Repr, DecidableEq, Inhabited for BinaryOp
7272
deriving instance Repr, Inhabited for Expr
7373

74-
7574
mutual
7675

7776
-- We should be able to get rid of this manual deriviation eventually.

cedar-lean/Cedar/Spec/Ext.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ def Ext.lt : Ext → Ext → Bool
3939

4040
----- Derivations -----
4141

42-
deriving instance Repr, DecidableEq for Ext
42+
deriving instance Repr, DecidableEq, Inhabited for Ext
4343

4444
instance : LT Ext where
4545
lt := fun x y => Ext.lt x y

cedar-lean/Cedar/Spec/Ext/Decimal.lean

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,9 @@ if h : Decimal.lt d₁ d₂ then isTrue h else isFalse h
7777
instance decLe (d₁ d₂ : Decimal) : Decidable (d₁ ≤ d₂) :=
7878
if h : Decimal.le d₁ d₂ then isTrue h else isFalse h
7979

80+
instance : Inhabited Decimal where
81+
default := Subtype.mk 0 (by simp)
82+
8083
end Decimal
8184

82-
end Cedar.Spec.Ext
85+
end Cedar.Spec.Ext

cedar-lean/Cedar/Spec/ExtFun.lean

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,6 @@ def call : ExtFun → List Value → Result Value
6464

6565
----- Derivations -----
6666

67-
deriving instance Repr, DecidableEq for ExtFun
67+
deriving instance Repr, DecidableEq, Inhabited for ExtFun
6868

6969
end Cedar.Spec

cedar-lean/Cedar/Spec/Value.lean

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -131,12 +131,11 @@ instance : Coe Value (Result (Data.Set Value)) where
131131

132132
deriving instance Repr, DecidableEq, BEq for Except
133133
deriving instance Repr, DecidableEq for Error
134-
deriving instance Repr, DecidableEq, Inhabited for Name
134+
deriving instance Repr, DecidableEq, Inhabited, Lean.ToJson for Name
135135
deriving instance Repr, DecidableEq, Inhabited for EntityType
136136
deriving instance Repr, DecidableEq, Inhabited for EntityUID
137137
deriving instance Repr, DecidableEq, Inhabited for Prim
138-
deriving instance Repr for Value
139-
138+
deriving instance Repr, Inhabited for Value
140139

141140
mutual
142141

@@ -302,6 +301,4 @@ instance : LT Value where
302301
instance Value.decLt (n m : Value) : Decidable (n < m) :=
303302
if h : Value.lt n m then isTrue h else isFalse h
304303

305-
deriving instance Inhabited for Value
306-
307304
end Cedar.Spec

cedar-lean/Cedar/Validation/Typechecker.lean

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -287,4 +287,9 @@ def typeOf (x : Expr) (c : Capabilities) (env : Environment) : ResultType :=
287287
let tys ← xs.mapM₁ (λ ⟨x₁, _⟩ => justType (typeOf x₁ c env))
288288
typeOfCall xfn tys xs
289289

290+
---- Derivations -----
291+
292+
deriving instance Repr for RequestType
293+
deriving instance Repr for Environment
294+
290295
end Cedar.Validation

cedar-lean/Cedar/Validation/Types.lean

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,13 @@ def ActionStore.descendentOf (as : ActionStore) (uid₁ uid₂ : EntityUID) : B
110110

111111
----- Derivations -----
112112

113-
deriving instance DecidableEq for BoolType
114-
deriving instance DecidableEq for ExtType
113+
deriving instance Repr, DecidableEq for BoolType
114+
deriving instance Repr, DecidableEq, Inhabited for ExtType
115+
deriving instance Repr, DecidableEq, Inhabited for Qualified
116+
deriving instance Repr, Inhabited for CedarType
117+
deriving instance Repr for TypeError
118+
deriving instance Repr for EntityTypeStoreEntry
119+
deriving instance Repr for ActionStoreEntry
115120

116121
mutual
117122

@@ -184,9 +189,6 @@ end
184189

185190
instance : DecidableEq CedarType := decCedarType
186191

187-
deriving instance DecidableEq for Qualified
188192
deriving instance DecidableEq for TypeError
189193

190-
deriving instance Inhabited for CedarType
191-
192194
end Cedar.Validation

cedar-lean/Cedar/Validation/Validator.lean

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -143,4 +143,32 @@ def validate (policies : Policies) (schema : Schema) : ValidationResult :=
143143
let envs := schema.toEnvironments
144144
policies.forM (typecheckPolicyWithEnvironments · envs)
145145

146+
----- Derivations -----
147+
148+
deriving instance Repr for SchemaActionEntry
149+
deriving instance Repr for Schema
150+
deriving instance Repr for ValidationError
151+
152+
/-
153+
Lossy serialization of errors to Json. This serialization provides some extra
154+
information to DRT without having to derive `Lean.ToJson` for `Expr` and `CedarType`.
155+
-/
156+
def validationErrorToJson : ValidationError → Lean.Json
157+
| .typeError _ (.lubErr _ _) => "lubErr"
158+
| .typeError _ (.unexpectedType _) => "unexpectedType"
159+
| .typeError _ (.attrNotFound _ _) => "attrNotFound"
160+
| .typeError _ (.unknownEntity _) => "unknownEntity"
161+
| .typeError _ (.extensionErr _) => "extensionErr"
162+
| .typeError _ .emptySetErr => "emptySetErr"
163+
| .typeError _ (.incompatibleSetTypes _) => "incompatibleSetTypes"
164+
| .impossiblePolicy _ => "impossiblePolicy"
165+
166+
instance : Lean.ToJson ValidationError where
167+
toJson := validationErrorToJson
168+
169+
-- Used to serialize `ValidationResult`
170+
deriving instance Lean.ToJson for Except
171+
instance : Lean.ToJson Unit where
172+
toJson := λ _ => Lean.Json.null
173+
146174
end Cedar.Validation

cedar-lean/Cli/Main.lean

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/-
2+
Copyright 2022-2023 Amazon.com, Inc. or its affiliates. All Rights Reserved.
3+
4+
Licensed under the Apache License, Version 2.0 (the "License");
5+
you may not use this file except in compliance with the License.
6+
You may obtain a copy of the License at
7+
8+
https://www.apache.org/licenses/LICENSE-2.0
9+
10+
Unless required by applicable law or agreed to in writing, software
11+
distributed under the License is distributed on an "AS IS" BASIS,
12+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
See the License for the specific language governing permissions and
14+
limitations under the License.
15+
-/
16+
17+
import Lean.Data.Json.FromToJson
18+
19+
import DiffTest.Main
20+
import DiffTest.Parser
21+
22+
/-! This file provides a basic command line interface for authorization
23+
and validation. It uses the interface functions defined in `Difftest`. -/
24+
25+
open DiffTest
26+
27+
def readFile (filename : String) : IO String :=
28+
IO.FS.readFile filename
29+
30+
def printUsage (err : String) : IO Unit :=
31+
IO.println s!"{err}\nUsage: Cli <command> <file>"
32+
33+
def main (args : List String) : IO Unit :=
34+
match args.length with
35+
| 2 => do
36+
let command := args.get! 0
37+
let filename := args.get! 1
38+
let request ← readFile filename
39+
match command with
40+
| "authorize" =>
41+
let response := isAuthorizedDRT request
42+
IO.println response
43+
| "validate" =>
44+
let response := validateDRT request
45+
IO.println response
46+
| _ => printUsage s!"Invalid command `{command}` (expected `authorize` or `validate`)"
47+
| n => printUsage s!"Incorrect number of arguments (expected 2, but got {n})"

0 commit comments

Comments
 (0)