Skip to content

Commit 3e960da

Browse files
author
burdo
committed
api nextcloud update
1 parent 30f1691 commit 3e960da

10 files changed

Lines changed: 224 additions & 1 deletion

File tree

src/main/java/org/comroid/api/model/Authentication.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,14 @@
44
import lombok.Builder.Default;
55
import lombok.Value;
66
import lombok.experimental.NonFinal;
7+
import org.comroid.api.comp.Base64;
8+
import org.comroid.api.info.Constraint;
79
import org.jetbrains.annotations.NotNull;
810
import org.jetbrains.annotations.Nullable;
911

12+
import java.util.AbstractMap;
13+
import java.util.Map;
14+
1015
@Value
1116
@Builder
1217
@NonFinal
@@ -35,6 +40,14 @@ public static Authentication ofToken(final @NotNull String username, final @NotN
3540
@Default @Nullable String username = null;
3641
@Default @Nullable String passkey = null;
3742

43+
public Map.Entry<String, String> toHttpBasicHeader() {
44+
Constraint.notNull(username, "username").run();
45+
Constraint.notNull(passkey, "passkey").run();
46+
47+
return new AbstractMap.SimpleImmutableEntry<>("Authorization",
48+
"Basic " + Base64.encode(username + ':' + passkey));
49+
}
50+
3851
public enum Type {
3952
Anonymous, UsernamePassword, UsernameToken, OnlyUsername, Token
4053
}

src/main/java/org/comroid/api/net/REST.java

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,9 @@ public static Request request(Method method, String uri) {
8282
private Function<Request, CompletableFuture<Response>> executor;
8383

8484
public enum Method implements Named {
85-
GET, POST, PUT, DELETE, HEAD, OPTIONS, TRACE, CONNECT, PATCH
85+
GET, POST, PUT, DELETE, HEAD, OPTIONS, TRACE, CONNECT, PATCH,
86+
// non standard
87+
MKCOL
8688
}
8789

8890
@Value
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
package org.comroid.api.net.nextcloud;
2+
3+
import lombok.Builder;
4+
import lombok.Value;
5+
import org.comroid.api.data.seri.DataNode;
6+
import org.comroid.api.model.Authentication;
7+
import org.comroid.api.net.REST;
8+
import org.comroid.api.net.nextcloud.component.FilesApi;
9+
import org.comroid.api.net.nextcloud.component.TablesApi;
10+
import org.comroid.api.net.nextcloud.component.UserApi;
11+
import org.comroid.api.net.nextcloud.model.OcsApiCore;
12+
import org.comroid.api.tree.Component;
13+
14+
import java.util.concurrent.CompletableFuture;
15+
16+
@Value
17+
@Builder
18+
public class OcsApiWrapper extends Component.Base implements OcsApiCore {
19+
@lombok.Builder.Default REST rest = REST.Default;
20+
String baseUrl;
21+
Authentication credentials;
22+
23+
{
24+
addChildren(new UserApi(this), new FilesApi(this), new TablesApi(this));
25+
}
26+
27+
@Override
28+
public REST.Request request(REST.Method method, String path) {
29+
return rest.new Request(method, baseUrl + path)
30+
.addHeader("Accept", "application/json")
31+
.addHeader("OCS-APIRequest", "true")
32+
.addHeader("Authorization", credentials.toHttpBasicHeader().getValue());
33+
}
34+
35+
@Override
36+
public CompletableFuture<DataNode> get(String path) {
37+
return request(REST.Method.GET, path)
38+
.execute()
39+
.thenApply(REST.Response::validate2xxOK)
40+
.thenApply(REST.Response::getBody);
41+
}
42+
}
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
package org.comroid.api.net.nextcloud.component;
2+
3+
import lombok.Value;
4+
import org.comroid.annotations.Default;
5+
import org.comroid.api.data.seri.DataNode;
6+
import org.comroid.api.net.REST;
7+
import org.comroid.api.net.nextcloud.model.OcsApiComponent;
8+
import org.comroid.api.net.nextcloud.model.OcsApiCore;
9+
10+
import java.io.IOException;
11+
import java.io.InputStream;
12+
import java.net.URLEncoder;
13+
import java.nio.charset.StandardCharsets;
14+
import java.util.Arrays;
15+
import java.util.concurrent.CompletableFuture;
16+
17+
@Value
18+
public class FilesApi extends OcsApiComponent {
19+
public FilesApi(OcsApiCore ocsApi) {
20+
super(ocsApi);
21+
}
22+
23+
public CompletableFuture<?> mkdirs(String path) {
24+
return CompletableFuture.allOf(Arrays.stream(path.split("/"))
25+
.map(this::mkdir)
26+
.toArray(CompletableFuture[]::new));
27+
}
28+
29+
public CompletableFuture<?> mkdir(String path) {
30+
return getOcsApi().request(REST.Method.MKCOL,
31+
"/remote.php/dav/files/" + getOcsApi().getCredentials().getUsername() + '/' + path)
32+
.execute()
33+
.thenApply(REST.Response::validate2xxOK);
34+
}
35+
36+
public CompletableFuture<?> upload(String path, InputStream data) throws IOException {
37+
return getOcsApi().request(REST.Method.PUT,
38+
"/remote.php/dav/files/" + getOcsApi().getCredentials().getUsername() + '/' + path)
39+
.setBody(new DataNode.Value<>(new String(data.readAllBytes(), StandardCharsets.UTF_8)))
40+
.execute()
41+
.thenApply(REST.Response::validate2xxOK);
42+
}
43+
44+
public CompletableFuture<?> share(
45+
String path, String group, @Default("31") long permissions,
46+
@Default("true") boolean download
47+
) {
48+
var queryParams = "?path=%s&shareType=1&shareWith=%s&permissions=%s".formatted(URLEncoder.encode(path,
49+
StandardCharsets.UTF_8),
50+
URLEncoder.encode(group, StandardCharsets.UTF_8),
51+
URLEncoder.encode(String.valueOf(permissions), StandardCharsets.UTF_8));
52+
if (download) queryParams += "&=attributes=%5B%7B%22scope%22%3A%22permissions%22%2C%22key%22%3A%22download%22%2C%22value%22%3Atrue%7D%5D";
53+
return getOcsApi().request(REST.Method.POST, "/ocs/v2.php/apps/files_sharing/api/v1/shares" + queryParams)
54+
.execute()
55+
.thenApply(REST.Response::validate2xxOK);
56+
}
57+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
package org.comroid.api.net.nextcloud.component;
2+
3+
import lombok.Value;
4+
import org.comroid.api.net.nextcloud.model.OcsApiComponent;
5+
import org.comroid.api.net.nextcloud.model.OcsApiCore;
6+
import org.comroid.api.net.nextcloud.model.tables.TableEntry;
7+
8+
import java.util.Collection;
9+
import java.util.concurrent.CompletableFuture;
10+
11+
@Value
12+
public class TablesApi extends OcsApiComponent {
13+
public TablesApi(OcsApiCore ocsApi) {
14+
super(ocsApi);
15+
}
16+
17+
public CompletableFuture<Collection<TableEntry>> getEntries(int tableId) {
18+
return getOcsApi().get("/index.php/apps/tables/api/1/tables/%d/rows".formatted(tableId))
19+
.thenApply(data -> data.asArray()
20+
.stream()
21+
.flatMap(entry -> entry.as(TableEntry.class).stream())
22+
.toList());
23+
}
24+
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
package org.comroid.api.net.nextcloud.component;
2+
3+
import lombok.Value;
4+
import org.comroid.api.data.seri.DataNode;
5+
import org.comroid.api.net.nextcloud.model.OcsApiComponent;
6+
import org.comroid.api.net.nextcloud.model.OcsApiCore;
7+
8+
import java.util.Collection;
9+
import java.util.concurrent.CompletableFuture;
10+
11+
@Value
12+
public class UserApi extends OcsApiComponent {
13+
public UserApi(OcsApiCore ocsApi) {
14+
super(ocsApi);
15+
}
16+
17+
public CompletableFuture<Collection<String>> getUsers() {
18+
return getOcsApi().get("/ocs/v1.php/cloud/users")
19+
.thenApply(data -> data.get("ocs")
20+
.get("data")
21+
.get("users")
22+
.asArray()
23+
.stream()
24+
.map(DataNode::toSerializedString)
25+
.toList());
26+
}
27+
}
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
package org.comroid.api.net.nextcloud.model;
2+
3+
import lombok.Value;
4+
import lombok.experimental.NonFinal;
5+
import org.comroid.api.tree.Component;
6+
7+
@Value
8+
@NonFinal
9+
public abstract class OcsApiComponent extends Component.Base {
10+
OcsApiCore ocsApi;
11+
}
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package org.comroid.api.net.nextcloud.model;
2+
3+
import org.comroid.api.data.seri.DataNode;
4+
import org.comroid.api.model.Authentication;
5+
import org.comroid.api.net.REST;
6+
import org.comroid.api.tree.Component;
7+
8+
import java.util.concurrent.CompletableFuture;
9+
10+
public interface OcsApiCore extends Component {
11+
String getBaseUrl();
12+
13+
REST getRest();
14+
15+
Authentication getCredentials();
16+
17+
REST.Request request(REST.Method method, String path);
18+
19+
CompletableFuture<DataNode> get(String path);
20+
}
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
package org.comroid.api.net.nextcloud.model.tables;
2+
3+
import lombok.Value;
4+
5+
@Value
6+
public class ColumnValue {
7+
int columnId;
8+
String value;
9+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.comroid.api.net.nextcloud.model.tables;
2+
3+
import com.fasterxml.jackson.annotation.JsonFormat;
4+
import lombok.Value;
5+
6+
import java.time.Instant;
7+
import java.util.Collection;
8+
9+
@Value
10+
public class TableEntry {
11+
long id;
12+
int tableId;
13+
String createdBy;
14+
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss") Instant createdAt;
15+
String lastEditBy;
16+
@JsonFormat(shape = JsonFormat.Shape.STRING, pattern = "yyyy-MM-dd HH:mm:ss") Instant lastEditAt;
17+
Collection<ColumnValue> data;
18+
}

0 commit comments

Comments
 (0)