edc_web_ui/components/
create_policy.rs

1use crate::components::list_of_rules::ListOfRules;
2use crate::components::simple_or_id_field::SimpleOrIdField;
3use crate::contexts::use_edc_connector_context;
4use edc_connector_client::types::policy::{
5  Action, Constraint, NewPolicyDefinition, Obligation, Permission, Policy, PolicyKind, Prohibition,
6  Target,
7};
8use patternfly_yew::prelude::*;
9use yew::platform::spawn_local;
10use yew::prelude::*;
11
12#[derive(Copy, Clone, PartialEq, Eq, strum::Display)]
13enum Options {
14  Agreement,
15  Offer,
16  Set,
17}
18
19#[function_component]
20pub fn CreatePolicy() -> Html {
21  let edc_connector_context = use_edc_connector_context();
22
23  let identifier = use_state(String::new);
24  let kind = use_state(|| Options::Set);
25  let assignee = use_state(String::default);
26  let assigner = use_state(String::default);
27  let target = use_state(|| (true, String::default()));
28  let permissions = use_state(Vec::new);
29  let prohibitions = use_state(Vec::new);
30  let obligations = use_state(Vec::new);
31
32  let onsubmit = use_callback(
33    (
34      edc_connector_context,
35      identifier.clone(),
36      kind.clone(),
37      assignee.clone(),
38      assigner.clone(),
39      target.clone(),
40      permissions.clone(),
41      prohibitions.clone(),
42      obligations.clone(),
43    ),
44    |event: SubmitEvent,
45     (
46      edc_connector_context,
47      identifier,
48      kind,
49      assignee,
50      assigner,
51      target,
52      permissions,
53      prohibitions,
54      obligations,
55    )| {
56      event.prevent_default();
57
58      let edc_connector_context = edc_connector_context.clone();
59      let identifier = (**identifier).clone();
60      let kind = **kind;
61      let assignee = (**assignee).clone();
62      let assigner = (**assigner).clone();
63      let (is_simple_target, target) = (**target).clone();
64
65      let permissions = (**permissions)
66        .iter()
67        .map(|(action, constraints): &(Action, Vec<Constraint>)| {
68          Permission::builder()
69            .action(action.clone())
70            .constraints(constraints.clone())
71            .build()
72        })
73        .collect();
74
75      let prohibitions = (**prohibitions)
76        .iter()
77        .map(|(action, constraints): &(Action, Vec<Constraint>)| {
78          Prohibition::builder()
79            .action(action.clone())
80            .constraints(constraints.clone())
81            .build()
82        })
83        .collect();
84
85      let obligations = (**obligations)
86        .iter()
87        .map(|(action, constraints): &(Action, Vec<Constraint>)| {
88          Obligation::builder()
89            .action(action.clone())
90            .constraints(constraints.clone())
91            .build()
92        })
93        .collect();
94
95      spawn_local(async move {
96        let kind = match kind {
97          Options::Agreement => PolicyKind::Agreement,
98          Options::Offer => PolicyKind::Offer,
99          Options::Set => PolicyKind::Set,
100        };
101
102        let policy_builder = Policy::builder()
103          .kind(kind)
104          .permissions(permissions)
105          .prohibitions(prohibitions)
106          .obligations(obligations);
107
108        let policy_builder = if !assignee.is_empty() {
109          policy_builder.maybe_assignee(Some(assignee))
110        } else {
111          policy_builder.maybe_assignee(None::<String>)
112        };
113
114        let policy_builder = if !assigner.is_empty() {
115          policy_builder.maybe_assigner(Some(assigner))
116        } else {
117          policy_builder.maybe_assigner(None::<String>)
118        };
119
120        let policy_builder = if !target.is_empty() {
121          if is_simple_target {
122            policy_builder.target(Target::Simple(target))
123          } else {
124            policy_builder.target(Target::Id { id: target })
125          }
126        } else {
127          policy_builder.maybe_target(None::<Target>)
128        };
129
130        let policy = policy_builder.build();
131
132        let new_policy = NewPolicyDefinition::builder()
133          .id(&identifier)
134          .policy(policy)
135          .build();
136
137        if let Some(client) = edc_connector_context.get_client() {
138          let _ = client.policies().create(&new_policy).await;
139        }
140      })
141    },
142  );
143
144  let onchange_identifier = {
145    let identifier = identifier.clone();
146
147    use_callback((), move |value, _| {
148      identifier.set(value);
149    })
150  };
151
152  let onselect_kind = {
153    let kind = kind.clone();
154
155    use_callback((), move |value, _| {
156      kind.set(value);
157    })
158  };
159
160  let onchange_assignee = {
161    let assignee = assignee.clone();
162
163    use_callback((), move |value: String, _| {
164      assignee.set(value);
165    })
166  };
167
168  let onchange_assigner = {
169    let assigner = assigner.clone();
170
171    use_callback((), move |value: String, _| {
172      assigner.set(value);
173    })
174  };
175
176  let onchange_target = {
177    let target = target.clone();
178
179    use_callback((), move |value: (bool, String), _| {
180      target.set(value);
181    })
182  };
183
184  let onchange_permissions = {
185    let permissions = permissions.clone();
186    use_callback((), move |list, _| {
187      permissions.set(list);
188    })
189  };
190
191  let onchange_prohibitions = {
192    let prohibitions = prohibitions.clone();
193    use_callback((), move |list, _| {
194      prohibitions.set(list);
195    })
196  };
197
198  let onchange_obligations = {
199    let obligations = obligations.clone();
200    use_callback((), move |list, _| {
201      obligations.set(list);
202    })
203  };
204
205  let (target_is_simple, target_value) = (*target).clone();
206
207  let disabled = false;
208
209  html!(
210    <Form {onsubmit}>
211      <FormGroup
212        label={"Identifier"}
213        required={true}
214        >
215        <TextInput
216          required={true}
217          value={(*identifier).to_string()}
218          onchange={onchange_identifier}
219          />
220      </FormGroup>
221
222      <FormGroup
223        label={"Kind"}
224        required={true}
225        >
226        <SimpleSelect<Options>
227          selected={*kind}
228          onselect={onselect_kind}
229          entries={vec![Options::Agreement, Options::Offer, Options::Set]}
230          />
231      </FormGroup>
232
233      <FormGroup
234        label={"Permissions"}
235        >
236        <ListOfRules
237          list={(*permissions).clone()}
238          onchange={onchange_permissions}
239          />
240      </FormGroup>
241
242      <FormGroup
243        label={"Prohibitions"}
244        >
245        <ListOfRules
246          list={(*prohibitions).clone()}
247          onchange={onchange_prohibitions}
248          />
249      </FormGroup>
250
251      <FormGroup
252        label={"Obligations"}
253        >
254        <ListOfRules
255          list={(*obligations).clone()}
256          onchange={onchange_obligations}
257          />
258      </FormGroup>
259
260      <FormGroup
261        label={"Assignee"}
262        >
263        <TextInput
264          value={(*assignee).clone()}
265          onchange={onchange_assignee}
266          />
267      </FormGroup>
268
269      <FormGroup
270        label={"Assigner"}
271        >
272        <TextInput
273          value={(*assigner).clone()}
274          onchange={onchange_assigner}
275          />
276      </FormGroup>
277
278      <FormGroup
279        label={"Target"}
280        >
281        <SimpleOrIdField onchange={onchange_target} is_simple={target_is_simple} value={target_value} />
282      </FormGroup>
283
284      <ActionGroup>
285        <Button
286          variant={ButtonVariant::Primary}
287          label="Submit"
288          r#type={ButtonType::Submit}
289          {disabled}
290          />
291        <Button variant={ButtonVariant::Secondary} label="Reset" r#type={ButtonType::Reset}/>
292      </ActionGroup>
293    </Form>
294  )
295}