nextcloud-client 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
data/README.md ADDED
@@ -0,0 +1,753 @@
1
+ [![Gem](https://img.shields.io/gem/v/nextcloud.svg?style=flat-square)](https://rubygems.org/gems/nextcloud) [![Travis](https://img.shields.io/travis/dachinat/nextcloud.svg?style=flat-square)](https://travis-ci.org/dachinat/nextcloud) [![Coveralls github](https://img.shields.io/coveralls/github/dachinat/nextcloud.svg?style=flat-square)](https://coveralls.io/github/dachinat/nextcloud) [![Yard Docs](https://img.shields.io/badge/yard-docs-blue.svg?style=flat-square)](http://rubydoc.info/github/dachinat/nextcloud/master)
2
+
3
+ # Nextcloud Ruby Client API
4
+
5
+ Wrapper gem for Ruby used for communicating with Nextcloud OCS and WebDAV API endpoints.
6
+
7
+ This gem provides features for User provisioning, Group and App management, control of Shares and Federated Cloud
8
+ Shares, WebDAV functions for File / Folder creation, removal and other operations. This gem extends the original `nextcloud` gem created by dachinat, addressing the need for maintenance and updates to ensure compatibility with the latest Nextcloud API features and best practices.
9
+
10
+ ## Installation
11
+
12
+ Add this line to your application's Gemfile:
13
+
14
+ ```ruby
15
+ gem "nextcloud-client"
16
+ ```
17
+
18
+ And then execute:
19
+
20
+ $ bundle
21
+
22
+ Or install it yourself as:
23
+
24
+ $ gem install nextcloud-client
25
+
26
+ ## Usage
27
+
28
+ #### Initialize with endpoint bundles
29
+
30
+ To initialize an OCS client you can look at following example
31
+
32
+ ```
33
+ ocs = NextcloudClient.ocs(
34
+ url: "https://cloud.yourdomain.com",
35
+ username: "your_username",
36
+ password: "your_password"
37
+ )
38
+ ```
39
+
40
+ An URL has to be a base of your Nextcloud instance. For API requests, it will be parsed to
41
+ `https://cloud.yourdomain.com/ocs/v2.php/cloud/` or similar.
42
+
43
+ Once `ocs` is available you can use following methods to initiate specific classes:
44
+
45
+ `ocs.user`, `ocs.app`, `ocs.group`, `ocs.file_sharing`
46
+
47
+ If you intent to work with WebDAV api you can initialize a client with `webdav`:
48
+
49
+ ```
50
+ webdav = NextcloudClient.webdav(
51
+ url: "https://cloud.yourdomain.com",
52
+ username: "your_username",
53
+ password: "your_password"
54
+ )
55
+ ```
56
+
57
+ You can also initialize and work with both APIs (useful if credentials are same):
58
+
59
+ ```
60
+ nextcloud = NextcloudClient.new(
61
+ url: "https://cloud.yourdomain.com",
62
+ username: "your_username",
63
+ password: "your_password"
64
+ )
65
+
66
+ ocs = nextcloud.ocs
67
+ webdav = nextcloud.webdav
68
+ ```
69
+
70
+ #### Initialize specific APIs
71
+
72
+ Previously described method is recommended, however you can initialize in a different manner.
73
+
74
+ Initialize OCS Users API:
75
+
76
+ ```
77
+ user = NextcloudClient::Ocs::User.new(url: "…", username: "…", password: "…")
78
+ ```
79
+
80
+ Initialize OCS Groups API:
81
+
82
+ ```
83
+ group = NextcloudClient::Ocs::Group.new(url: "…", username: "…", password: "…")
84
+ ```
85
+
86
+ Initialize OCS Apps API:
87
+
88
+ ```
89
+ app = NextcloudClient::Ocs::App.new(url: "…", username: "…", password: "…")
90
+ ```
91
+
92
+ Initialize OCS File Sharing API:
93
+
94
+ ```
95
+ file_sharing = NextcloudClient::Ocs::FileSharingApi.new(url: "…", username: "…", password: "…")
96
+ ```
97
+
98
+ Initialize WebDAV Directory API:
99
+
100
+ ```
101
+ directory = NextcloudClient::Webdav::Directory.new(url: "…", username: "…", password: "…")
102
+ ```
103
+
104
+ > When initializing this way, to work with certain objects some circumstances might force you use `set` method.
105
+ > For example if you wish to list members of group admin, using first way you could simply write
106
+ `ocs.group('admin').members`, in this case you will need to use `group.set('admin').members`. There is another way to
107
+ set object of intereset by putting it into initialize arguments, like so
108
+ `NextcloudClient::Ocs::Group.new({…credentials}, groupid="admin")` it can be then reset with
109
+ `set`. Corresponding parameter names for other classes are `userid` and `appid`.
110
+
111
+ ### *OCS Api usage*
112
+
113
+ These examples assume you have `NextcloudClient.ocs` instance or relevant instance of
114
+ `NextcloudClient::Ocs::{CLASS_NAME}.new` stored in `ocs` variable.
115
+
116
+ ### User actions
117
+
118
+ #### Get list of users
119
+
120
+ ```
121
+ users = ocs.user.all
122
+ # => [#<NextcloudClient::Models::User:0x00000104d253c0 @id="your_user_1">, #<NextcloudClient::Models::User:0x00000104d1f858 @id="your_user_2">]
123
+
124
+ last_user = user.last
125
+ => #<NextcloudClient::Models::User:0x000001042a2ba0 @id="your_user_2">
126
+
127
+ response_meta = users.meta
128
+ {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
129
+ ```
130
+
131
+ #### Get a single user
132
+
133
+ ```
134
+ user = ocs.user.find("your_user_1")
135
+ # => #<NextcloudClient::Models::User:0x00000103964020 @enabled="true", @id="your_user_1", …, @meta={"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}>
136
+ ```
137
+
138
+ Having `user` variable you have access to following attributes:
139
+
140
+ * enabled
141
+ * id
142
+ * quota
143
+ * email
144
+ * displayname
145
+ * phone
146
+ * address
147
+ * website
148
+ * twitter
149
+ * groups
150
+ * language
151
+ * meta
152
+
153
+
154
+ Again, here you can use `user.meta` to get service response status, code and message.
155
+
156
+ #### Create an user
157
+
158
+ ```
159
+ meta = ocs.user.create("user3", "userPassword1!").meta
160
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
161
+ ```
162
+
163
+ #### Update an user
164
+
165
+ You can update an user attributes with key-value method.
166
+
167
+ Valid keys include:
168
+
169
+ * quota
170
+ * displayname
171
+ * phone
172
+ * address
173
+ * website
174
+ * twitter
175
+ * password
176
+
177
+ ```
178
+ meta = ocs.user.update("user3", "email", "new-address@some-domain.com").meta
179
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
180
+ ```
181
+
182
+ #### Disable user
183
+
184
+ ```
185
+ meta = ocs.user.disable("user3").meta
186
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
187
+ ```
188
+
189
+ #### Enable user
190
+
191
+ ```
192
+ meta = ocs.user.enable("user3").meta
193
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
194
+ ```
195
+
196
+ #### Delete user
197
+
198
+ ```
199
+ meta = ocs.user.destroy("user3").meta
200
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
201
+ ```
202
+
203
+ #### Resend welcome email message
204
+
205
+ ```
206
+ meta = ocs.user.resend_welcome("user3").meta
207
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
208
+ ```
209
+
210
+ ### User group actions
211
+
212
+ #### Get user groups
213
+
214
+ ```
215
+ groups = ocs.user("user1").groups
216
+ # => ["admin"]
217
+ meta = groups.meta
218
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
219
+ ```
220
+
221
+ if you work with initialized User class
222
+
223
+ ```
224
+ user.set("user1").groups
225
+ ```
226
+
227
+ #### Add user to group
228
+
229
+ ```
230
+ meta = ocs.user("user4").group.create("admin").meta
231
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
232
+ ```
233
+
234
+ if you work with initialized User class
235
+
236
+ ```
237
+ user.set("user4").group.create("admin")
238
+ ```
239
+
240
+ #### Remove user from group
241
+
242
+ ```
243
+ meta = ocs.user("user4").group.destroy("admin").meta
244
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
245
+ ```
246
+
247
+ if you work with initialized User class
248
+
249
+ ```
250
+ user.set("user4").group.destroy("admin")
251
+ ```
252
+
253
+ #### Promote user to group subadmin
254
+
255
+ ```
256
+ meta = ocs.user("user4").group("group1").promote.meta
257
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
258
+ ```
259
+
260
+ if you work with initialized User class
261
+
262
+ ```
263
+ user.set("user4").group("group1").promote
264
+ ```
265
+
266
+ #### Demote user from group subadmin
267
+
268
+ ```
269
+ meta = ocs.user("user4").group("group1").demote.meta
270
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
271
+ ```
272
+
273
+ if you work with initialized User class
274
+
275
+ ```
276
+ user.set("user4").group("group1").demote
277
+ ```
278
+
279
+ #### Get user subadmin groups
280
+
281
+ ```
282
+ subadmin_groups = ocs.user("user4").subadmin_groups
283
+ # => ["group1"]
284
+ meta = subadmin_groups.meta
285
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
286
+ ```
287
+
288
+ if you work with initialized User class
289
+
290
+ ```
291
+ user.set("user4").subadmin_groups
292
+ ```
293
+
294
+ ### Group actions
295
+
296
+ #### Get all groups
297
+
298
+ ```
299
+ groups = ocs.group.all
300
+ # => ["admin", "group1", "group2"]
301
+ meta = groups.meta
302
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
303
+ ```
304
+
305
+ #### Search for a group
306
+
307
+ ```
308
+ groups = ocs.group.search("admin")
309
+ # => ["admin"]
310
+ meta = groups.meta
311
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
312
+ ```
313
+
314
+ #### Create a new group
315
+
316
+ ```
317
+ meta = ocs.group.create("group3").meta
318
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
319
+ ```
320
+
321
+ #### Get group members
322
+
323
+ ```
324
+ members = ocs.group("admin").members
325
+ # => ["user1", "user2"]
326
+ meta = members.meta
327
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
328
+ ```
329
+
330
+ if you work with initialized Group class
331
+
332
+ ```
333
+ group.set("admin").members
334
+ ```
335
+
336
+ #### Get group subadmins
337
+
338
+ ```
339
+ members = ocs.group("group1").subadmins
340
+ # => ["user1", "user2", "user3"]
341
+ meta = members.meta
342
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
343
+ ```
344
+
345
+ if you work with initialized Group class
346
+
347
+ ```
348
+ group.set("group1").subadmins
349
+ ```
350
+
351
+ #### Delete a group
352
+
353
+ ```
354
+ meta = ocs.group.destroy("group3").meta
355
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
356
+ ```
357
+
358
+ ### App actions
359
+
360
+ #### Get enabled applications
361
+
362
+ ```
363
+ enabled = ocs.app.enabled
364
+ # => […]
365
+ meta = enabled.meta
366
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
367
+ ```
368
+
369
+ #### Get disabled applications
370
+
371
+ ```
372
+ disabled = ocs.app.disabled
373
+ # => […]
374
+ meta = disabled.meta
375
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
376
+ ```
377
+
378
+ #### Get application information
379
+
380
+ ```
381
+ app = ocs.app.find("appname")
382
+ # => {…}
383
+ meta = app.meta
384
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
385
+ ```
386
+
387
+ #### Enable application
388
+
389
+ ```
390
+ meta = ocs.app("appname").enable.meta
391
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
392
+ ```
393
+
394
+ if you work with initialized App class
395
+
396
+ ```
397
+ app.set("appname").enable
398
+ ```
399
+
400
+ #### Disable application
401
+
402
+ ```
403
+ meta = ocs.app("appname").disable.meta
404
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
405
+ ```
406
+
407
+ if you work with initialized App class
408
+
409
+ ```
410
+ app.set("appname").disable
411
+ ```
412
+
413
+ ### FileSharing API
414
+
415
+ #### Initialize with authentication information
416
+
417
+ First of all you need to initiate a class with authentication information of user
418
+
419
+ ```
420
+ ocs_fs = NextcloudClient::Ocs::FileSharingApi.new(
421
+ url: "https://cloud.yourdomain.com",
422
+ username: "your_username",
423
+ password: "your_password"
424
+ )
425
+ ```
426
+
427
+ An URL has to be a base of your Nextcloud instance. For Sharing API requests, it will be parsed to
428
+ `https://cloud.yourdomain.com/ocs/v2.php/apps/files_sharing/api/v1/`
429
+
430
+ > You can also initialize with `NextcloudClient.ocs(…credentials).file_sharing`
431
+
432
+ #### Retrieve all shares of an (authenticated) user
433
+
434
+ ```
435
+ all_shares = ocs_fs.all
436
+ # => [{…}, {…}]
437
+ meta = all_shares.meta
438
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
439
+ ```
440
+
441
+ #### Retrieve a single share
442
+
443
+ ```
444
+ share = ocs_fs.find(11)
445
+ # => {"id" => "22", "shareType" => "0", …}
446
+ meta = share.meta
447
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
448
+ ```
449
+
450
+ #### Retrive shares from specific file or folder
451
+
452
+ Can be called with two optional parameters
453
+ * reshares - boolean - shows all shares for a given file
454
+ * subfiles - boolean - shows all shares for subfiles in a directory
455
+
456
+ ```
457
+ # shares from file.txt
458
+ file_shares = ocs_fs.specific("file.txt")
459
+
460
+ # shares from /dir1
461
+ dir_shares = ocs_fs.specific("/dir1")
462
+
463
+ # not only the shares from the current user but all shares from the given file
464
+ reshares = ocs_fs.specific("file1.txt", true)
465
+
466
+ # all shares within a folder, given that path defines a folder
467
+ subfiles = ocs_fs.specific("/dir1", ture, true)
468
+
469
+ # Attached variables will also have .meta method with server response information
470
+ ```
471
+
472
+ #### Create a share
473
+
474
+ First argument is a `path` (required) to a file or a folder
475
+
476
+ `shareType` (required) has to be an integer
477
+
478
+ * 0 = user
479
+ * 1 = group
480
+ * 3 = public link
481
+ * 6 = federated cloud share
482
+
483
+ `shareWith` is only reqired if `shareType` is `0` or `1`, defines user or group file will be shared with
484
+
485
+ `publicUpload` is boolean, allows public uploads in a directory (Visitors will be able to upload to public directory
486
+ shared with link)
487
+
488
+ `password` to protect shared links with
489
+
490
+ `permissions` has to be an integer (default: 31, for public shares: 1)
491
+
492
+ * 1 = read
493
+ * 2 = update
494
+ * 4 = create
495
+ * 8 = delete
496
+ * 16 = share
497
+ * 31 = all
498
+
499
+ ```
500
+ # share file.txt with user user1
501
+ ocs_fs.create("file.txt", 0, "user1").meta
502
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
503
+
504
+ # share file1.txt with public link and assign password to it
505
+ ocs_fs.create("file1.txt", 3, nil, nil, "password1P/")
506
+ ```
507
+
508
+ #### Delete a share
509
+
510
+ ```
511
+ delete = ocs_fs.destroy("21").meta
512
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
513
+ ```
514
+
515
+ #### Update a share
516
+
517
+ For details about permissions see "Create a share" section
518
+
519
+ Expiration date should be in "YYYY-MM-DD" format
520
+
521
+ ```
522
+ # makes a share read-only
523
+ ocs_fs.update_permissions(21, 1)
524
+
525
+ # updates password
526
+ ocs_fs.update_password(21, "newPassword!0")
527
+
528
+ # allows public uploads
529
+ ocs_fs.update_public_upload(21, true)
530
+
531
+ # change expiration date
532
+ ocs_fs.update_expire_date(21, "2017-11-22")
533
+
534
+ # These methods will also have .meta method with server response information
535
+ ```
536
+
537
+ ### Federated Cloud Shares
538
+
539
+ To create a federated cloud shares you can use `create` method on `FileSharingApi` (see previous section)
540
+
541
+ #### List accepted federated shares
542
+
543
+ ```
544
+ accepted = ocs_fs.federated.accepted
545
+ # => [{…}, {…}]
546
+ meta = accepted.meta
547
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
548
+ ```
549
+
550
+ #### List pending federated shares
551
+
552
+ ```
553
+ pending = ocs_fs.federated.pending
554
+ # => [{…}, {…}]
555
+ meta = pending.meta
556
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
557
+ ```
558
+
559
+ #### Info about federated share (accepted)
560
+
561
+ ```
562
+ federated_share = ocs_fs.federated.find(12)
563
+ # => {"id"=>"12", "remote"=>"https://…", …}s
564
+ meta = federated_share.meta
565
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
566
+ ```
567
+
568
+ #### Delete accepted federated share
569
+
570
+ ```
571
+ meta = ocs_fs.federated.destroy(12)
572
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
573
+ ```
574
+
575
+ #### Accept federated share
576
+
577
+ ```
578
+ meta = ocs_fs.federated.accept(13)
579
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
580
+ ```
581
+
582
+ #### Decline federated share
583
+
584
+ ```
585
+ meta = ocs_fs.federated.decline(13)
586
+ # => {"status"=>"ok", "statuscode"=>"200", "message"=>"OK"}
587
+ ```
588
+
589
+ ### *WebDAV Api usage*
590
+
591
+ In these examples `webdav` variable is assumed to be a valid instance of
592
+ `NextcloudClient.webdav` or `NextcloudClient::Webdav::{CLASS_NAME}.new`
593
+
594
+ ### File/Directory Operations
595
+
596
+ #### Find files/directories in given path
597
+
598
+ ```
599
+ directory = webdav.directory.find("dir1/")
600
+ ```
601
+
602
+ Will return instance of `Directory` model with information about current directory, it's method `contents` will contain
603
+ array of results:
604
+
605
+ ```
606
+ directory.contents
607
+ ```
608
+
609
+ #### Query information about file
610
+
611
+ ```
612
+ file = webdav.directory.find("some_file.txt")
613
+ ```
614
+
615
+ #### Create a directory
616
+
617
+ ```
618
+ webdav.directory.create("some_dir/new_dir")
619
+ ```
620
+
621
+ #### Delete a directory
622
+
623
+ ```
624
+ webdav.directory.destroy("some_dir")
625
+ ```
626
+
627
+ #### Move a directory
628
+
629
+ ```
630
+ webdav.directory.move("source_dir/", "destination_dir/")
631
+ ```
632
+
633
+ #### Copy a directory
634
+
635
+ ```
636
+ webdav.directory.copy("source_dir/", "destination_dir/)
637
+ ```
638
+
639
+ #### Download a file
640
+
641
+ ```
642
+ webdav.directory.download("some_file.txt")
643
+ ```
644
+
645
+ #### Upload a file
646
+
647
+ ```
648
+ webdav.directory.upload("some_dir/new_file.txt", "CONTENTS")
649
+ ```
650
+
651
+ #### Make a file favorite
652
+
653
+ ```
654
+ webdav.directory.favorite("some_file")
655
+ ```
656
+
657
+ #### Unfavorite a file
658
+
659
+ ```
660
+ webdav.directory.unfavorite("some_file")
661
+ ```
662
+
663
+ #### Show favorite files in path
664
+
665
+ ```
666
+ webdav.directory.favorites("/")
667
+ ```
668
+
669
+ ### Group Folder API
670
+
671
+ #### Initialize with authentication information
672
+
673
+ First of all you need to initiate a class with authentication information of user
674
+
675
+ ```
676
+ gf = NextcloudClient::Ocs::GroupFolder.new(
677
+ url: "https://cloud.yourdomain.com",
678
+ username: "your_username",
679
+ password: "your_password"
680
+ )
681
+ ```
682
+
683
+ #### List of folders
684
+
685
+ ```
686
+ gf.folders
687
+ ```
688
+
689
+ #### Find folder with id 16
690
+
691
+ ```
692
+ gf.find(16)
693
+ ```
694
+
695
+ #### Get ID of folder with name 'Intern
696
+
697
+ ```
698
+ gf.get_folder_id('Intern')
699
+ ```
700
+
701
+ #### Create folder with name 'Intern'
702
+
703
+ ```
704
+ gf.create('Intern')
705
+ ```
706
+
707
+ #### Destroy folder id 16
708
+
709
+ ```
710
+ gf.destroy(16)
711
+ ```
712
+
713
+ #### Give access to folder with id 16 for 'Intern'
714
+
715
+ ```
716
+ gf.give_access(16, 'Intern')
717
+ ```
718
+
719
+ #### Remove access to folder with id 16 for 'Intern'
720
+
721
+ ```
722
+ gf.remove_access(16, 'Intern')
723
+ ```
724
+
725
+ #### Set permissions for folder with id 16 and group 'Intern' to 31
726
+
727
+ ```
728
+ gf.set_permissions(16, 'Intern', 31)
729
+ ```
730
+
731
+ #### Set quota of folder with id 16 to 7 GB
732
+
733
+ ```
734
+ gf.set_quota(16, 1024*1024*1024*7)
735
+ ```
736
+
737
+ #### Rename folder with id 16 to 'Extern'
738
+
739
+ ```
740
+ gf.rename_folder(16, 'Extern')
741
+ ```
742
+
743
+ ## Contributing
744
+
745
+ Bug reports and pull requests are welcome on GitHub at https://github.com/dachinat/nextcloud. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [Contributor Covenant](http://contributor-covenant.org) code of conduct.
746
+
747
+ ## License
748
+
749
+ The gem is available as open source under the terms of the [MIT License](https://opensource.org/licenses/MIT).
750
+
751
+ ## Code of Conduct
752
+
753
+ Everyone interacting in the Nextcloud gem project’s codebases, issue trackers, chat rooms and mailing lists is expected to follow the [code of conduct](https://github.com/dachinat/nextcloud/blob/master/CODE_OF_CONDUCT.md).