Skip to content

Commit 4d45af8

Browse files
authored
Fixed Issue #426 Restart Changed to Operate action (#1121)
1 parent 63b3d44 commit 4d45af8

File tree

9 files changed

+71
-35
lines changed

9 files changed

+71
-35
lines changed

api/src/main/java/io/kafbat/ui/controller/KafkaConnectController.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -191,11 +191,7 @@ public Mono<ResponseEntity<Void>> updateConnectorState(String clusterName, Strin
191191
ConnectorActionDTO action,
192192
ServerWebExchange exchange) {
193193
ConnectAction[] connectActions;
194-
if (RESTART_ACTIONS.contains(action)) {
195-
connectActions = new ConnectAction[] {ConnectAction.VIEW, ConnectAction.RESTART};
196-
} else {
197-
connectActions = new ConnectAction[] {ConnectAction.VIEW, ConnectAction.EDIT};
198-
}
194+
connectActions = new ConnectAction[] {ConnectAction.VIEW, ConnectAction.OPERATE};
199195

200196
var context = AccessContext.builder()
201197
.cluster(clusterName)
@@ -237,7 +233,7 @@ public Mono<ResponseEntity<Void>> restartConnectorTask(String clusterName, Strin
237233

238234
var context = AccessContext.builder()
239235
.cluster(clusterName)
240-
.connectActions(connectName, ConnectAction.VIEW, ConnectAction.RESTART)
236+
.connectActions(connectName, ConnectAction.VIEW, ConnectAction.OPERATE)
241237
.operationName("restartConnectorTask")
242238
.operationParams(Map.of(CONNECTOR_NAME, connectorName))
243239
.build();

api/src/main/java/io/kafbat/ui/model/rbac/Resource.java

Lines changed: 29 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,13 @@
1212
import io.kafbat.ui.model.rbac.permission.SchemaAction;
1313
import io.kafbat.ui.model.rbac.permission.TopicAction;
1414
import jakarta.annotation.Nullable;
15+
import java.util.ArrayList;
16+
import java.util.Arrays;
17+
import java.util.Collection;
1518
import java.util.List;
19+
import java.util.Map;
20+
import java.util.Optional;
21+
import java.util.stream.Collectors;
1622
import java.util.stream.Stream;
1723
import org.apache.commons.lang3.EnumUtils;
1824

@@ -28,7 +34,7 @@ public enum Resource {
2834

2935
SCHEMA(SchemaAction.values()),
3036

31-
CONNECT(ConnectAction.values()),
37+
CONNECT(ConnectAction.values(), ConnectAction.ALIASES),
3238

3339
KSQL(KsqlAction.values()),
3440

@@ -38,14 +44,27 @@ public enum Resource {
3844

3945
CLIENT_QUOTAS(ClientQuotaAction.values());
4046

41-
private final List<PermissibleAction> actions;
47+
48+
private final Map<String, PermissibleAction> actions;
49+
private final Map<String, PermissibleAction> aliases;
50+
51+
Resource(PermissibleAction[] actions, Map<String, PermissibleAction> aliases) {
52+
this.actions = Arrays.stream(actions)
53+
.collect(
54+
Collectors.toMap(
55+
a -> a.name().toLowerCase(),
56+
a -> a
57+
)
58+
);
59+
this.aliases = aliases;
60+
}
4261

4362
Resource(PermissibleAction[] actions) {
44-
this.actions = List.of(actions);
63+
this(actions, Map.of());
4564
}
4665

4766
public List<PermissibleAction> allActions() {
48-
return actions;
67+
return new ArrayList<>(actions.values());
4968
}
5069

5170
@Nullable
@@ -54,17 +73,14 @@ public static Resource fromString(String name) {
5473
}
5574

5675
public List<PermissibleAction> parseActionsWithDependantsUnnest(List<String> actionsToParse) {
57-
return actionsToParse.stream()
58-
.map(toParse -> actions.stream()
59-
.filter(a -> toParse.equalsIgnoreCase(a.name()))
60-
.findFirst()
76+
return actionsToParse.stream().map(toParse ->
77+
Optional.ofNullable(actions.get(toParse.toLowerCase()))
78+
.or(() -> Optional.ofNullable(aliases.get(toParse.toLowerCase())))
6179
.orElseThrow(() -> new IllegalArgumentException(
6280
"'%s' actions not applicable for resource %s".formatted(toParse, name())))
63-
)
64-
// unnesting all dependant actions
65-
.flatMap(a -> Stream.concat(Stream.of(a), a.unnestAllDependants()))
66-
.distinct()
67-
.toList();
81+
).flatMap(a ->
82+
Stream.concat(Stream.of(a), a.unnestAllDependants())
83+
).distinct().toList();
6884
}
6985

7086
}

api/src/main/java/io/kafbat/ui/model/rbac/permission/ConnectAction.java

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package io.kafbat.ui.model.rbac.permission;
22

3+
import java.util.Map;
34
import java.util.Set;
45
import org.apache.commons.lang3.EnumUtils;
56
import org.jetbrains.annotations.Nullable;
@@ -9,10 +10,9 @@ public enum ConnectAction implements PermissibleAction {
910
VIEW,
1011
EDIT(VIEW),
1112
CREATE(VIEW),
12-
RESTART(VIEW),
13+
OPERATE(VIEW),
1314
DELETE(VIEW),
14-
RESET_OFFSETS(VIEW)
15-
15+
RESET_OFFSETS(VIEW),
1616
;
1717

1818
private final ConnectAction[] dependantActions;
@@ -21,7 +21,9 @@ public enum ConnectAction implements PermissibleAction {
2121
this.dependantActions = dependantActions;
2222
}
2323

24-
public static final Set<ConnectAction> ALTER_ACTIONS = Set.of(CREATE, EDIT, DELETE, RESTART, RESET_OFFSETS);
24+
public static final Set<ConnectAction> ALTER_ACTIONS = Set.of(CREATE, EDIT, DELETE, OPERATE, RESET_OFFSETS);
25+
26+
public static final Map<String, PermissibleAction> ALIASES = Map.of("restart", OPERATE);
2527

2628
@Nullable
2729
public static ConnectAction fromString(String name) {

api/src/test/java/io/kafbat/ui/model/rbac/AccessContextTest.java

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@
99
import io.kafbat.ui.model.rbac.AccessContext.ResourceAccess;
1010
import io.kafbat.ui.model.rbac.AccessContext.SingleResourceAccess;
1111
import io.kafbat.ui.model.rbac.permission.ClusterConfigAction;
12+
import io.kafbat.ui.model.rbac.permission.ConnectAction;
1213
import io.kafbat.ui.model.rbac.permission.PermissibleAction;
1314
import io.kafbat.ui.model.rbac.permission.TopicAction;
1415
import jakarta.annotation.Nullable;
@@ -98,10 +99,30 @@ void deniesAccessForResourceWithoutNameIfUserHasAllNeededPermissions() {
9899
assertThat(allowed).isFalse();
99100
}
100101

102+
@Test
103+
void shouldMapActionAliases() {
104+
SingleResourceAccess sra =
105+
new SingleResourceAccess(Resource.CONNECT, List.of(ConnectAction.OPERATE));
106+
107+
var allowed = sra.isAccessible(
108+
List.of(
109+
permission(Resource.CONNECT, null, List.of("restart"))
110+
)
111+
);
112+
113+
assertThat(allowed).isTrue();
114+
}
115+
101116
private Permission permission(Resource res, @Nullable String namePattern, PermissibleAction... actions) {
117+
return permission(
118+
res, namePattern, Stream.of(actions).map(PermissibleAction::name).toList()
119+
);
120+
}
121+
122+
private Permission permission(Resource res, @Nullable String namePattern, List<String> actions) {
102123
Permission p = new Permission();
103124
p.setResource(res.name());
104-
p.setActions(Stream.of(actions).map(PermissibleAction::name).toList());
125+
p.setActions(actions);
105126
p.setValue(namePattern);
106127
p.validate();
107128
p.transform();

api/src/test/java/io/kafbat/ui/model/rbac/PermissionTest.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ void transformSetsFullActionsListIfAllActionPassed() {
3434
p.transform();
3535

3636
assertThat(p.getParsedActions())
37-
.isEqualTo(List.of(TopicAction.values()));
37+
.containsExactlyInAnyOrder(TopicAction.values());
3838
}
3939

4040
@Test

contract/src/main/resources/swagger/kafbat-ui-api.yaml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3947,6 +3947,7 @@ components:
39473947
- MESSAGES_READ
39483948
- MESSAGES_PRODUCE
39493949
- MESSAGES_DELETE
3950+
- OPERATE
39503951
- RESTART
39513952

39523953
ResourceType:

frontend/src/components/Connect/Details/Actions/Actions.tsx

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -91,7 +91,7 @@ const Actions: React.FC = () => {
9191
onClick={pauseConnectorHandler}
9292
permission={{
9393
resource: ResourceType.CONNECT,
94-
action: Action.EDIT,
94+
action: Action.OPERATE,
9595
value: routerProps.connectName,
9696
}}
9797
>
@@ -103,7 +103,7 @@ const Actions: React.FC = () => {
103103
onClick={stopConnectorHandler}
104104
permission={{
105105
resource: ResourceType.CONNECT,
106-
action: Action.EDIT,
106+
action: Action.OPERATE,
107107
value: routerProps.connectName,
108108
}}
109109
>
@@ -116,7 +116,7 @@ const Actions: React.FC = () => {
116116
onClick={resumeConnectorHandler}
117117
permission={{
118118
resource: ResourceType.CONNECT,
119-
action: Action.EDIT,
119+
action: Action.OPERATE,
120120
value: routerProps.connectName,
121121
}}
122122
>
@@ -127,7 +127,7 @@ const Actions: React.FC = () => {
127127
onClick={restartConnectorHandler}
128128
permission={{
129129
resource: ResourceType.CONNECT,
130-
action: Action.RESTART,
130+
action: Action.OPERATE,
131131
value: routerProps.connectName,
132132
}}
133133
>
@@ -137,7 +137,7 @@ const Actions: React.FC = () => {
137137
onClick={restartAllTasksHandler}
138138
permission={{
139139
resource: ResourceType.CONNECT,
140-
action: Action.RESTART,
140+
action: Action.OPERATE,
141141
value: routerProps.connectName,
142142
}}
143143
>
@@ -147,7 +147,7 @@ const Actions: React.FC = () => {
147147
onClick={restartFailedTasksHandler}
148148
permission={{
149149
resource: ResourceType.CONNECT,
150-
action: Action.RESTART,
150+
action: Action.OPERATE,
151151
value: routerProps.connectName,
152152
}}
153153
>

frontend/src/components/Connect/Details/Tasks/ActionsCellTasks.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ const ActionsCellTasks: React.FC<CellContext<Task, unknown>> = ({ row }) => {
2525
confirm="Are you sure you want to restart the task?"
2626
permission={{
2727
resource: ResourceType.CONNECT,
28-
action: Action.RESTART,
28+
action: Action.OPERATE,
2929
value: routerProps.connectName,
3030
}}
3131
>

frontend/src/components/Connect/List/ActionsCell.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -126,7 +126,7 @@ const ActionsCell: React.FC<CellContext<FullConnectorInfo, unknown>> = ({
126126
disabled={isMutating}
127127
permission={{
128128
resource: ResourceType.CONNECT,
129-
action: Action.RESTART,
129+
action: Action.OPERATE,
130130
value: connect,
131131
}}
132132
>
@@ -137,7 +137,7 @@ const ActionsCell: React.FC<CellContext<FullConnectorInfo, unknown>> = ({
137137
disabled={isMutating}
138138
permission={{
139139
resource: ResourceType.CONNECT,
140-
action: Action.RESTART,
140+
action: Action.OPERATE,
141141
value: connect,
142142
}}
143143
>
@@ -148,7 +148,7 @@ const ActionsCell: React.FC<CellContext<FullConnectorInfo, unknown>> = ({
148148
disabled={isMutating}
149149
permission={{
150150
resource: ResourceType.CONNECT,
151-
action: Action.RESTART,
151+
action: Action.OPERATE,
152152
value: connect,
153153
}}
154154
>

0 commit comments

Comments
 (0)