Skip to content

Commit 54e56c1

Browse files
committed
WIP: mutation
1 parent 704b8c8 commit 54e56c1

File tree

11 files changed

+804
-10
lines changed

11 files changed

+804
-10
lines changed
Lines changed: 176 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
/*
2+
* Licensed to The Apereo Foundation under one or more contributor license
3+
* agreements. See the NOTICE file distributed with this work for additional
4+
* information regarding copyright ownership.
5+
*
6+
*
7+
* The Apereo Foundation licenses this file to you under the Educational
8+
* Community License, Version 2.0 (the "License"); you may not use this file
9+
* except in compliance with the License. You may obtain a copy of the License
10+
* at:
11+
*
12+
* http://opensource.org/licenses/ecl2.txt
13+
*
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
17+
* License for the specific language governing permissions and limitations under
18+
* the License.
19+
*
20+
*/
21+
22+
package org.opencastproject.graphql.command;
23+
24+
import org.opencastproject.authorization.xacml.manager.api.AclService;
25+
import org.opencastproject.authorization.xacml.manager.api.AclServiceFactory;
26+
import org.opencastproject.graphql.exception.GraphQLRuntimeException;
27+
import org.opencastproject.graphql.exception.GraphQLUnauthorizedException;
28+
import org.opencastproject.graphql.execution.context.OpencastContext;
29+
import org.opencastproject.graphql.execution.context.OpencastContextManager;
30+
import org.opencastproject.graphql.playlist.GqlPlaylist;
31+
import org.opencastproject.graphql.playlist.PlaylistEntriesInput;
32+
import org.opencastproject.graphql.playlist.PlaylistMetadataInput;
33+
import org.opencastproject.graphql.type.input.AccessControlListInput;
34+
import org.opencastproject.graphql.util.GraphQLObjectMapper;
35+
import org.opencastproject.playlists.Playlist;
36+
import org.opencastproject.playlists.PlaylistAccessControlEntry;
37+
import org.opencastproject.playlists.PlaylistEntry;
38+
import org.opencastproject.playlists.PlaylistEntryType;
39+
import org.opencastproject.playlists.PlaylistService;
40+
import org.opencastproject.security.api.AccessControlEntry;
41+
import org.opencastproject.security.api.AccessControlList;
42+
import org.opencastproject.security.api.SecurityService;
43+
import org.opencastproject.security.api.UnauthorizedException;
44+
45+
import java.util.ArrayList;
46+
import java.util.List;
47+
48+
/**
49+
* Command to create a playlist from GraphQL inputs (metadata, entries, acl).
50+
*/
51+
public class CreatePlaylistCommand extends AbstractCommand<GqlPlaylist> {
52+
53+
private final PlaylistMetadataInput metadataInput;
54+
private final PlaylistEntriesInput entriesInput;
55+
private final AccessControlListInput aclInput;
56+
57+
public CreatePlaylistCommand(final Builder builder) {
58+
super(builder);
59+
this.metadataInput = builder.metadataInput;
60+
this.entriesInput = builder.entriesInput;
61+
this.aclInput = builder.aclInput;
62+
}
63+
64+
@Override
65+
public GqlPlaylist execute() {
66+
OpencastContext context = OpencastContextManager.getCurrentContext();
67+
final PlaylistService playlistService = context.getService(PlaylistService.class);
68+
final SecurityService securityService = context.getService(SecurityService.class);
69+
try {
70+
// read arguments from environment when present, otherwise fall back to builder values
71+
final Object metadataArg = environment.getArgument("metadata");
72+
final PlaylistMetadataInput metadata = metadataArg == null
73+
? metadataInput
74+
: GraphQLObjectMapper.newInstance().convertValue(metadataArg, PlaylistMetadataInput.class);
75+
76+
final Object entriesArg = environment.getArgument("entries");
77+
final PlaylistEntriesInput entries = entriesArg == null
78+
? entriesInput
79+
: GraphQLObjectMapper.newInstance().convertValue(entriesArg, PlaylistEntriesInput.class);
80+
81+
Playlist playlist = new Playlist();
82+
if (metadata != null) {
83+
playlist.setTitle(metadata.getTitle());
84+
playlist.setDescription(metadata.getDescription());
85+
playlist.setCreator(securityService.getUser().getName());
86+
}
87+
88+
List<PlaylistEntry> playlistEntries = new ArrayList<>();
89+
if (entries != null && entries.getEntries() != null) {
90+
for (var entryInput : entries.getEntries()) {
91+
PlaylistEntryType type = PlaylistEntryType.EVENT;
92+
if (entryInput != null && entryInput.getType() != null) {
93+
type = entryInput.getType().getType();
94+
}
95+
PlaylistEntry pe = new PlaylistEntry(entryInput == null ? null : entryInput.getContentId(), type);
96+
playlistEntries.add(pe);
97+
}
98+
}
99+
playlist.setEntries(playlistEntries);
100+
101+
AccessControlList acl = new AccessControlList();
102+
final AccessControlListInput aclToUse = this.aclInput == null ? environment.getArgument("acl") == null ? null
103+
: GraphQLObjectMapper.newInstance().convertValue(environment.getArgument("acl"), AccessControlListInput.class)
104+
: this.aclInput;
105+
106+
if (aclToUse != null) {
107+
if (aclToUse.getEntries() != null) {
108+
for (var item : aclToUse.getEntries()) {
109+
for (var action : item.getAction()) {
110+
acl.getEntries().add(new AccessControlEntry(item.getRole(), action, true));
111+
}
112+
}
113+
}
114+
if (aclToUse.getManagedAclId() != null) {
115+
AclService aclService = context.getService(AclServiceFactory.class)
116+
.serviceFor(context.getService(SecurityService.class).getOrganization());
117+
aclService.getAcl(aclToUse.getManagedAclId()).ifPresent(value -> acl.merge(value.getAcl()));
118+
}
119+
}
120+
121+
List<PlaylistAccessControlEntry> aceList = new ArrayList<>();
122+
for (AccessControlEntry entry : acl.getEntries()) {
123+
aceList.add(new PlaylistAccessControlEntry(entry.isAllow(), entry.getRole(), entry.getAction()));
124+
}
125+
playlist.setAccessControlEntries(aceList);
126+
127+
// Persist
128+
playlist = playlistService.update(playlist);
129+
130+
return new GqlPlaylist(playlist);
131+
} catch (UnauthorizedException e) {
132+
throw new GraphQLUnauthorizedException(e.getMessage());
133+
} catch (RuntimeException e) {
134+
throw new GraphQLRuntimeException(e);
135+
}
136+
}
137+
138+
public static Builder create(
139+
PlaylistMetadataInput metadataInput,
140+
PlaylistEntriesInput entriesInput,
141+
AccessControlListInput accessControlListInput) {
142+
return new Builder(metadataInput, entriesInput, accessControlListInput);
143+
}
144+
145+
public static class Builder extends AbstractCommand.Builder<GqlPlaylist> {
146+
147+
private final PlaylistMetadataInput metadataInput;
148+
private final PlaylistEntriesInput entriesInput;
149+
private final AccessControlListInput aclInput;
150+
151+
public Builder(PlaylistMetadataInput metadataInput, PlaylistEntriesInput entriesInput,
152+
AccessControlListInput aclInput) {
153+
this.metadataInput = metadataInput;
154+
this.entriesInput = entriesInput;
155+
this.aclInput = aclInput;
156+
}
157+
158+
@Override
159+
public void validate() {
160+
super.validate();
161+
if (metadataInput == null) {
162+
throw new IllegalStateException("Playlist metadata cannot be null");
163+
}
164+
if (aclInput == null) {
165+
throw new IllegalStateException("Access control list cannot be null");
166+
}
167+
}
168+
169+
@Override
170+
public CreatePlaylistCommand build() {
171+
validate();
172+
return new CreatePlaylistCommand(this);
173+
}
174+
}
175+
176+
}
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
/*
2+
* Licensed to The Apereo Foundation under one or more contributor license
3+
* agreements. See the NOTICE file distributed with this work for additional
4+
* information regarding copyright ownership.
5+
*
6+
*
7+
* The Apereo Foundation licenses this file to you under the Educational
8+
* Community License, Version 2.0 (the "License"); you may not use this file
9+
* except in compliance with the License. You may obtain a copy of the License
10+
* at:
11+
*
12+
* http://opensource.org/licenses/ecl2.txt
13+
*
14+
* Unless required by applicable law or agreed to in writing, software
15+
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
16+
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
17+
* License for the specific language governing permissions and limitations under
18+
* the License.
19+
*
20+
*/
21+
package org.opencastproject.graphql.command;
22+
import org.opencastproject.graphql.exception.GraphQLNotFoundException;
23+
import org.opencastproject.graphql.exception.GraphQLRuntimeException;
24+
import org.opencastproject.graphql.exception.GraphQLUnauthorizedException;
25+
import org.opencastproject.graphql.execution.context.OpencastContext;
26+
import org.opencastproject.graphql.execution.context.OpencastContextManager;
27+
import org.opencastproject.graphql.playlist.GqlDeletePlaylistPayload;
28+
import org.opencastproject.playlists.PlaylistService;
29+
import org.opencastproject.security.api.UnauthorizedException;
30+
import org.opencastproject.util.NotFoundException;
31+
public class DeletePlaylistCommand extends AbstractCommand<GqlDeletePlaylistPayload> {
32+
private final String id;
33+
public DeletePlaylistCommand(final Builder builder) {
34+
super(builder);
35+
this.id = builder.id;
36+
}
37+
@Override
38+
public GqlDeletePlaylistPayload execute() {
39+
OpencastContext context = OpencastContextManager.getCurrentContext();
40+
final PlaylistService playlistService = context.getService(PlaylistService.class);
41+
try {
42+
playlistService.remove(this.id);
43+
} catch (UnauthorizedException e) {
44+
throw new GraphQLUnauthorizedException(e.getMessage());
45+
} catch (NotFoundException e) {
46+
throw new GraphQLNotFoundException(e.getMessage());
47+
} catch (IllegalStateException e) {
48+
throw new GraphQLRuntimeException(e);
49+
}
50+
return new GqlDeletePlaylistPayload(id);
51+
}
52+
public static Builder create(String id) {
53+
return new Builder(id);
54+
}
55+
public static class Builder extends AbstractCommand.Builder<GqlDeletePlaylistPayload> {
56+
private final String id;
57+
public Builder(String id) {
58+
this.id = id;
59+
}
60+
@Override
61+
public void validate() {
62+
super.validate();
63+
if (id == null) {
64+
throw new IllegalArgumentException("Id can not be null.");
65+
}
66+
}
67+
@Override
68+
public DeletePlaylistCommand build() {
69+
validate();
70+
return new DeletePlaylistCommand(this);
71+
}
72+
}
73+
}

0 commit comments

Comments
 (0)