icfs 0.1.3 → 0.2.0
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.
- checksums.yaml +4 -4
- data/bin/icfs_demo_fcgi.rb +2 -0
- data/{bin/icfs_demo_ssl_gen.rb → devel/demo/ssl_gen.rb} +25 -13
- data/devel/demo/ssl_gen.yml +14 -0
- data/devel/icfs-wrk/Dockerfile +1 -1
- data/devel/run/base.rb +92 -0
- data/devel/run/copy-s3.rb +2 -0
- data/devel/run/email.rb +36 -0
- data/devel/run/email_imap.rb +43 -0
- data/devel/run/email_smime.rb +47 -0
- data/devel/run/init-icfs.rb +2 -0
- data/devel/run/webrick.rb +5 -57
- data/lib/icfs/api.rb +101 -90
- data/lib/icfs/cache.rb +2 -0
- data/lib/icfs/cache_elastic.rb +127 -125
- data/lib/icfs/{web/config.rb → config.rb} +3 -3
- data/lib/icfs/{web/config_redis.rb → config_redis.rb} +8 -8
- data/lib/icfs/{web/config_s3.rb → config_s3.rb} +8 -8
- data/lib/icfs/demo/auth.rb +5 -7
- data/lib/icfs/demo/static.rb +2 -0
- data/lib/icfs/elastic.rb +10 -8
- data/lib/icfs/email/basic.rb +242 -0
- data/lib/icfs/email/core.rb +293 -0
- data/lib/icfs/email/from.rb +52 -0
- data/lib/icfs/email/imap.rb +148 -0
- data/lib/icfs/email/smime.rb +139 -0
- data/lib/icfs/items.rb +5 -3
- data/lib/icfs/store.rb +20 -18
- data/lib/icfs/store_fs.rb +7 -5
- data/lib/icfs/store_s3.rb +4 -2
- data/lib/icfs/users.rb +5 -3
- data/lib/icfs/users_fs.rb +8 -6
- data/lib/icfs/users_redis.rb +12 -10
- data/lib/icfs/users_s3.rb +6 -4
- data/lib/icfs/utils/backup.rb +30 -29
- data/lib/icfs/utils/check.rb +36 -34
- data/lib/icfs/validate.rb +24 -15
- data/lib/icfs/web/auth_ssl.rb +7 -9
- data/lib/icfs/web/client.rb +671 -679
- data/lib/icfs.rb +174 -10
- metadata +16 -7
- data/devel/devel-webrick.yml +0 -49
data/lib/icfs/api.rb
CHANGED
@@ -9,6 +9,8 @@
|
|
9
9
|
# This program is distributed WITHOUT ANY WARRANTY; without even the
|
10
10
|
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
11
11
|
|
12
|
+
# frozen_string_literal: true
|
13
|
+
|
12
14
|
#
|
13
15
|
module ICFS
|
14
16
|
|
@@ -49,12 +51,14 @@ class Api
|
|
49
51
|
# @param users [Users] the User/role/group interface
|
50
52
|
# @param cache [Cache] the cache
|
51
53
|
# @param store [Store] the store
|
54
|
+
# @param config [Config] the config settings, optional
|
52
55
|
#
|
53
|
-
def initialize(stats, users, cache, store)
|
56
|
+
def initialize(stats, users, cache, store, config=nil)
|
54
57
|
@users = users
|
55
58
|
@cache = cache
|
56
59
|
@store = store
|
57
60
|
@gstats = stats.map{|st| st.dup.freeze }.freeze
|
61
|
+
@config = config
|
58
62
|
reset
|
59
63
|
end # def initialize
|
60
64
|
|
@@ -67,8 +71,8 @@ class Api
|
|
67
71
|
def user=(uname)
|
68
72
|
@user = uname.dup.freeze
|
69
73
|
urgp = @users.read(uname)
|
70
|
-
raise(Error::NotFound, 'User name not found'
|
71
|
-
raise(Error::Value, 'Not a user'
|
74
|
+
raise(Error::NotFound, 'User name not found') if !urgp
|
75
|
+
raise(Error::Value, 'Not a user') if urgp['type'] != 'user'
|
72
76
|
if urgp['roles']
|
73
77
|
@roles = urgp['roles'].map{|rn| rn.freeze }.freeze
|
74
78
|
else
|
@@ -96,6 +100,8 @@ class Api
|
|
96
100
|
@ur.merge @roles
|
97
101
|
@ur.freeze
|
98
102
|
|
103
|
+
@config.load(@user) if @config
|
104
|
+
|
99
105
|
reset
|
100
106
|
end # def user=()
|
101
107
|
|
@@ -143,6 +149,11 @@ class Api
|
|
143
149
|
attr_reader :urg
|
144
150
|
|
145
151
|
|
152
|
+
###############################################
|
153
|
+
# Config settings
|
154
|
+
attr_reader :config
|
155
|
+
|
156
|
+
|
146
157
|
###############################################
|
147
158
|
# Reset the cached cases and access
|
148
159
|
#
|
@@ -213,7 +224,7 @@ class Api
|
|
213
224
|
###############################################
|
214
225
|
# See if we are tasked
|
215
226
|
def tasked?(cid, anum)
|
216
|
-
id = '%s.%d'
|
227
|
+
id = '%s.%d' % [cid, anum]
|
217
228
|
unless @tasked.key?(id)
|
218
229
|
act = _action_read(cid, anum)
|
219
230
|
|
@@ -283,12 +294,12 @@ class Api
|
|
283
294
|
def case_read(cid, lnum=0)
|
284
295
|
if lnum != 0
|
285
296
|
json = @store.case_read(cid, lnum)
|
286
|
-
return Items.parse(json, 'case'
|
297
|
+
return Items.parse(json, 'case', Items::ItemCase)
|
287
298
|
end
|
288
299
|
|
289
300
|
if !@cases.key?(cid)
|
290
301
|
json = @cache.case_read(cid)
|
291
|
-
cur = Items.parse(json, 'case'
|
302
|
+
cur = Items.parse(json, 'case', Items::ItemCase)
|
292
303
|
@cases[cid] = cur
|
293
304
|
end
|
294
305
|
return @cases[cid]
|
@@ -308,12 +319,12 @@ class Api
|
|
308
319
|
# get access list
|
309
320
|
al = access_list(cid)
|
310
321
|
if !al.include?(ICFS::PermRead)
|
311
|
-
raise(Error::Perms, 'missing perms: %s'
|
322
|
+
raise(Error::Perms, 'missing perms: %s' % ICFS::PermRead)
|
312
323
|
end
|
313
324
|
|
314
325
|
# read
|
315
326
|
json = @cache.log_read(cid, lnum)
|
316
|
-
return Items.parse(json, 'log'
|
327
|
+
return Items.parse(json, 'log', Items::ItemLog)
|
317
328
|
end # def log_read()
|
318
329
|
|
319
330
|
|
@@ -331,7 +342,7 @@ class Api
|
|
331
342
|
# get access list and current entry
|
332
343
|
al = access_list(cid)
|
333
344
|
json = @cache.entry_read(cid, enum)
|
334
|
-
ec = Items.parse(json, 'entry'
|
345
|
+
ec = Items.parse(json, 'entry', Items::ItemEntry)
|
335
346
|
|
336
347
|
# see if we can read the entry
|
337
348
|
need = Set.new
|
@@ -339,7 +350,7 @@ class Api
|
|
339
350
|
need.merge(ec['perms']) if ec['perms']
|
340
351
|
need.subtract(al)
|
341
352
|
unless need.empty?
|
342
|
-
raise(Error::Perms, 'missing perms: %s'
|
353
|
+
raise(Error::Perms, 'missing perms: %s' %
|
343
354
|
need.to_a.sort.join(', ') )
|
344
355
|
end
|
345
356
|
|
@@ -348,7 +359,7 @@ class Api
|
|
348
359
|
return ec
|
349
360
|
else
|
350
361
|
json = @store.entry_read(cid, enum, lnum)
|
351
|
-
return Items.parse(json, 'entry'
|
362
|
+
return Items.parse(json, 'entry', Items::ItemEntry)
|
352
363
|
end
|
353
364
|
end # def entry_read()
|
354
365
|
|
@@ -366,7 +377,7 @@ class Api
|
|
366
377
|
def file_read(cid, enum, lnum, fnum)
|
367
378
|
entry_read(cid, enum)
|
368
379
|
fi = @store.file_read(cid, enum, lnum, fnum)
|
369
|
-
raise(Error::NotFound, 'file not found'
|
380
|
+
raise(Error::NotFound, 'file not found') if !fi
|
370
381
|
return fi
|
371
382
|
end # def file_read()
|
372
383
|
|
@@ -377,10 +388,10 @@ class Api
|
|
377
388
|
# Internal version.
|
378
389
|
#
|
379
390
|
def _action_read(cid, anum)
|
380
|
-
id = '%s.%d'
|
391
|
+
id = '%s.%d' % [cid, anum]
|
381
392
|
unless @actions.key?(id)
|
382
393
|
json = @cache.action_read(cid, anum)
|
383
|
-
act = Items.parse(json, 'action'
|
394
|
+
act = Items.parse(json, 'action', Items::ItemAction)
|
384
395
|
@actions[id] = act
|
385
396
|
end
|
386
397
|
return @actions[id]
|
@@ -405,7 +416,7 @@ class Api
|
|
405
416
|
|
406
417
|
# see if we can read the action
|
407
418
|
unless _can_read?(cid, anum)
|
408
|
-
raise(Error::Perms, 'missing perms: %s'
|
419
|
+
raise(Error::Perms, 'missing perms: %s' % ICFS::PermRead )
|
409
420
|
end
|
410
421
|
|
411
422
|
# return the requested version
|
@@ -413,7 +424,7 @@ class Api
|
|
413
424
|
return ac
|
414
425
|
else
|
415
426
|
json = @store.action_read( cid, anum, lnum)
|
416
|
-
return Items.parse(json, 'action'
|
427
|
+
return Items.parse(json, 'action', Items::ItemAction)
|
417
428
|
end
|
418
429
|
end # def action_read()
|
419
430
|
|
@@ -432,19 +443,19 @@ class Api
|
|
432
443
|
# get access list
|
433
444
|
al = access_list(cid)
|
434
445
|
if !al.include?(ICFS::PermRead)
|
435
|
-
raise(Error::Perms, 'missing perms: %s'
|
446
|
+
raise(Error::Perms, 'missing perms: %s' % ICFS::PermRead )
|
436
447
|
end
|
437
448
|
|
438
449
|
# read curent index
|
439
450
|
json = @cache.index_read(cid, xnum)
|
440
|
-
xc = Items.parse(json, 'index'
|
451
|
+
xc = Items.parse(json, 'index', Items::ItemIndex)
|
441
452
|
|
442
453
|
# return the requested version
|
443
454
|
if( lnum == 0 || xc['log'] == lnum )
|
444
455
|
return xc
|
445
456
|
else
|
446
457
|
json = @store.index_read(cid, xnum, lnum)
|
447
|
-
return Items.parse(json, 'index'
|
458
|
+
return Items.parse(json, 'index', Items::ItemIndex)
|
448
459
|
end
|
449
460
|
end # def index_read()
|
450
461
|
|
@@ -458,11 +469,11 @@ class Api
|
|
458
469
|
|
459
470
|
al = access_list(cid)
|
460
471
|
if !al.include?(ICFS::PermRead)
|
461
|
-
raise(Error::Perms, 'missing perms: %s'
|
472
|
+
raise(Error::Perms, 'missing perms: %s' % ICFS::PermRead)
|
462
473
|
end
|
463
474
|
|
464
475
|
json = @cache.current_read(cid)
|
465
|
-
return Items.parse(json, 'current'
|
476
|
+
return Items.parse(json, 'current', Items::ItemCurrent)
|
466
477
|
end # end def current_read()
|
467
478
|
|
468
479
|
|
@@ -494,7 +505,7 @@ class Api
|
|
494
505
|
# @param query [Hash] a query
|
495
506
|
#
|
496
507
|
def case_search(query)
|
497
|
-
Items.validate(query, 'Case Search'
|
508
|
+
Items.validate(query, 'Case Search', ValCaseSearch)
|
498
509
|
@cache.case_search(query)
|
499
510
|
end
|
500
511
|
|
@@ -516,8 +527,8 @@ class Api
|
|
516
527
|
sort: {
|
517
528
|
method: :string,
|
518
529
|
allowed: Set[
|
519
|
-
'time_desc'
|
520
|
-
'time_asc'
|
530
|
+
'time_desc',
|
531
|
+
'time_asc',
|
521
532
|
].freeze,
|
522
533
|
whitelist: true,
|
523
534
|
}.freeze
|
@@ -531,7 +542,7 @@ class Api
|
|
531
542
|
# @param query [Hash] a query
|
532
543
|
#
|
533
544
|
def log_search(query)
|
534
|
-
Items.validate(query, 'Log Search'
|
545
|
+
Items.validate(query, 'Log Search', ValLogSearch)
|
535
546
|
@cache.log_search(query)
|
536
547
|
end
|
537
548
|
|
@@ -556,8 +567,8 @@ class Api
|
|
556
567
|
sort: {
|
557
568
|
method: :string,
|
558
569
|
allowed: Set[
|
559
|
-
'time_desc'
|
560
|
-
'time_asc'
|
570
|
+
'time_desc',
|
571
|
+
'time_asc',
|
561
572
|
].freeze,
|
562
573
|
whitelist: true,
|
563
574
|
}.freeze
|
@@ -570,14 +581,14 @@ class Api
|
|
570
581
|
# Search for entries
|
571
582
|
#
|
572
583
|
def entry_search(query)
|
573
|
-
Items.validate(query, 'Entry Search'
|
584
|
+
Items.validate(query, 'Entry Search', ValEntrySearch)
|
574
585
|
|
575
586
|
# check permissions
|
576
587
|
# - have global search permissions / read access to the case
|
577
588
|
# - are searching for an action they can read
|
578
589
|
unless( _search?(query) || (query[:caseid] &&
|
579
590
|
query[:action] && tasked?(query[:caseid], query[:action])))
|
580
|
-
raise(Error::Perms, 'Does not have permission to search'
|
591
|
+
raise(Error::Perms, 'Does not have permission to search')
|
581
592
|
end
|
582
593
|
|
583
594
|
# run the query
|
@@ -645,8 +656,8 @@ class Api
|
|
645
656
|
sort: {
|
646
657
|
method: :string,
|
647
658
|
allowed: Set[
|
648
|
-
'time_desc'
|
649
|
-
'time_asc'
|
659
|
+
'time_desc',
|
660
|
+
'time_asc',
|
650
661
|
].freeze,
|
651
662
|
whitelist: true,
|
652
663
|
}.freeze
|
@@ -658,7 +669,7 @@ class Api
|
|
658
669
|
# Search for actions
|
659
670
|
#
|
660
671
|
def action_search(query)
|
661
|
-
Items.validate(query, 'Action Search'
|
672
|
+
Items.validate(query, 'Action Search', ValActionSearch)
|
662
673
|
|
663
674
|
# permissions check
|
664
675
|
# - have global search permissions / read access to the case
|
@@ -666,7 +677,7 @@ class Api
|
|
666
677
|
unless( _search?(query) || @ur.include?(query[:assigned]) ||
|
667
678
|
(query[:assigned] == ICFS::UserCase && query[:caseid] &&
|
668
679
|
access_list(query[:caseid]).include?(ICFS::PermAction) ))
|
669
|
-
raise(Error::Perms, 'Does not have permission to search'
|
680
|
+
raise(Error::Perms, 'Does not have permission to search')
|
670
681
|
end
|
671
682
|
|
672
683
|
# run the search
|
@@ -689,10 +700,10 @@ class Api
|
|
689
700
|
sort: {
|
690
701
|
method: :string,
|
691
702
|
allowed: Set[
|
692
|
-
'title_desc'
|
693
|
-
'title_asc'
|
694
|
-
'index_desc'
|
695
|
-
'index_asc'
|
703
|
+
'title_desc',
|
704
|
+
'title_asc',
|
705
|
+
'index_desc',
|
706
|
+
'index_asc',
|
696
707
|
].freeze,
|
697
708
|
whitelist: true,
|
698
709
|
}.freeze
|
@@ -704,12 +715,12 @@ class Api
|
|
704
715
|
# Search for indexes
|
705
716
|
#
|
706
717
|
def index_search(query)
|
707
|
-
Items.validate(query, 'Index Search'
|
718
|
+
Items.validate(query, 'Index Search', ValIndexSearch)
|
708
719
|
|
709
720
|
# permissions check
|
710
721
|
# - have global search permissions / read access to the case
|
711
722
|
unless _search?(query)
|
712
|
-
raise(Error::Perms, 'Do not have permission to search'
|
723
|
+
raise(Error::Perms, 'Do not have permission to search')
|
713
724
|
end
|
714
725
|
|
715
726
|
# run the query
|
@@ -746,13 +757,13 @@ class Api
|
|
746
757
|
# Analyze stats
|
747
758
|
#
|
748
759
|
def stats(query)
|
749
|
-
Items.validate(query, 'Stats Search'
|
760
|
+
Items.validate(query, 'Stats Search', ValStatsSearch)
|
750
761
|
|
751
762
|
# permissions check
|
752
763
|
# - have global search permissions / read access to the case
|
753
764
|
# - are searching for a user/role/group you have
|
754
765
|
unless _search?(query) || (query[:credit] && @urg.include?(query[:credit]))
|
755
|
-
raise(Error::Perms, 'Do not have permissions to search'
|
766
|
+
raise(Error::Perms, 'Do not have permissions to search')
|
756
767
|
end
|
757
768
|
|
758
769
|
@cache.stats(query)
|
@@ -775,7 +786,7 @@ class Api
|
|
775
786
|
# Get case tags
|
776
787
|
#
|
777
788
|
def case_tags(query)
|
778
|
-
Items.validate(query, 'Case Tags Search'
|
789
|
+
Items.validate(query, 'Case Tags Search', ValCaseTags)
|
779
790
|
return @cache.case_tags(query)
|
780
791
|
end # def case_tags()
|
781
792
|
|
@@ -796,12 +807,12 @@ class Api
|
|
796
807
|
# Get entry tags
|
797
808
|
#
|
798
809
|
def entry_tags(query)
|
799
|
-
Items.validate(query, 'Entry Tags Search'
|
810
|
+
Items.validate(query, 'Entry Tags Search', ValEntryTags)
|
800
811
|
|
801
812
|
# permissions
|
802
813
|
# - read access to case
|
803
814
|
unless access_list(query[:caseid]).include?(ICFS::PermRead)
|
804
|
-
raise(Error::Perms, 'missing perms: %s'
|
815
|
+
raise(Error::Perms, 'missing perms: %s' % ICFS::PermRead)
|
805
816
|
end
|
806
817
|
return @cache.entry_tags(query)
|
807
818
|
end # def entry_tags()
|
@@ -837,13 +848,13 @@ class Api
|
|
837
848
|
# Get action tags
|
838
849
|
#
|
839
850
|
def action_tags(query)
|
840
|
-
Items.validate(query, 'Task Tags Search'
|
851
|
+
Items.validate(query, 'Task Tags Search', ValActionTags)
|
841
852
|
|
842
853
|
# only allow searches for user/roles you have
|
843
854
|
unless @ur.include?(query[:assigned]) ||
|
844
855
|
(query[:assigned] == ICFS::UserCase && query[:caseid] &&
|
845
856
|
access_list(query[:caseid]).include?(ICFS::PermAction) )
|
846
|
-
raise(Error::Perms, 'May not search for other\'s tasks'
|
857
|
+
raise(Error::Perms, 'May not search for other\'s tasks')
|
847
858
|
end
|
848
859
|
|
849
860
|
# run the search
|
@@ -867,9 +878,9 @@ class Api
|
|
867
878
|
# Get index tags
|
868
879
|
#
|
869
880
|
def index_tags(query)
|
870
|
-
Items.validate(query, 'Index Tags'
|
881
|
+
Items.validate(query, 'Index Tags', ValIndexTags)
|
871
882
|
unless access_list(query[:caseid]).include?(ICFS::PermRead)
|
872
|
-
raise(Error::Perms, 'missing perms: %s'
|
883
|
+
raise(Error::Perms, 'missing perms: %s' % ICFS::PermRead)
|
873
884
|
end
|
874
885
|
return @cache.index_tags(query)
|
875
886
|
end
|
@@ -894,8 +905,8 @@ class Api
|
|
894
905
|
# Sanity checks
|
895
906
|
|
896
907
|
# form & values
|
897
|
-
Items.validate(ent, 'entry'
|
898
|
-
Items.validate(cse, 'case'
|
908
|
+
Items.validate(ent, 'entry', Items::ItemEntryNew)
|
909
|
+
Items.validate(cse, 'case', Items::ItemCaseEdit)
|
899
910
|
|
900
911
|
# access users/roles/groups are valid, unless manually specifying user
|
901
912
|
unless unam
|
@@ -903,7 +914,7 @@ class Api
|
|
903
914
|
acc["grant"].each do |gnt|
|
904
915
|
urg = @users.read(gnt)
|
905
916
|
if !urg
|
906
|
-
raise(Error::NotFound, 'User/role/group %s not found'
|
917
|
+
raise(Error::NotFound, 'User/role/group %s not found' % urg)
|
907
918
|
end
|
908
919
|
end
|
909
920
|
end
|
@@ -917,26 +928,26 @@ class Api
|
|
917
928
|
if tid
|
918
929
|
tmpl = case_read(tid)
|
919
930
|
unless tmpl['template']
|
920
|
-
raise(Error::Perms, 'Not a template'
|
931
|
+
raise(Error::Perms, 'Not a template')
|
921
932
|
end
|
922
933
|
|
923
934
|
al = access_list(tid)
|
924
935
|
unless al.include?(ICFS::PermManage)
|
925
|
-
raise(Error::Perms, 'May not create cases from this template'
|
936
|
+
raise(Error::Perms, 'May not create cases from this template')
|
926
937
|
end
|
927
938
|
end
|
928
939
|
|
929
940
|
# no action/indexes
|
930
941
|
if ent['action']
|
931
|
-
raise(Error::Value, 'No Action for a new case entry'
|
942
|
+
raise(Error::Value, 'No Action for a new case entry')
|
932
943
|
end
|
933
944
|
if ent['index']
|
934
|
-
raise(Error::Value, 'No Index for a new case entry'
|
945
|
+
raise(Error::Value, 'No Index for a new case entry')
|
935
946
|
end
|
936
947
|
|
937
948
|
# Allow case creation without a Users system in place
|
938
949
|
user = @user ? @user : unam
|
939
|
-
raise(ArgumentError, 'No user specified'
|
950
|
+
raise(ArgumentError, 'No user specified') if user.nil?
|
940
951
|
|
941
952
|
####################
|
942
953
|
# Prep
|
@@ -947,7 +958,7 @@ class Api
|
|
947
958
|
cse['caseid'] = cid
|
948
959
|
cse['log'] = 1
|
949
960
|
cse['tags'] ||= [ ICFS::TagNone ]
|
950
|
-
citem = Items.generate(cse, 'case'
|
961
|
+
citem = Items.generate(cse, 'case', Items::ItemCase)
|
951
962
|
|
952
963
|
# entry
|
953
964
|
ent['icfs'] = 1
|
@@ -989,7 +1000,7 @@ class Api
|
|
989
1000
|
@cache.lock_take(cid)
|
990
1001
|
begin
|
991
1002
|
if @cache.case_read(cid)
|
992
|
-
raise(Error::Conflict, 'Case already exists'
|
1003
|
+
raise(Error::Conflict, 'Case already exists')
|
993
1004
|
end
|
994
1005
|
|
995
1006
|
now = Time.now.to_i
|
@@ -997,12 +1008,12 @@ class Api
|
|
997
1008
|
# finish items
|
998
1009
|
ent['time'] ||= now
|
999
1010
|
ent['files'].each{|fi| fi['log'] ||= 1 } if ent['files']
|
1000
|
-
eitem = Items.generate(ent, 'entry'
|
1011
|
+
eitem = Items.generate(ent, 'entry', Items::ItemEntry)
|
1001
1012
|
log['time'] = now
|
1002
1013
|
log['entry']['hash'] = ICFS.hash(eitem)
|
1003
|
-
litem = Items.generate(log, 'log'
|
1014
|
+
litem = Items.generate(log, 'log', Items::ItemLog)
|
1004
1015
|
cur['hash'] = ICFS.hash(litem)
|
1005
|
-
nitem = Items.generate(cur, 'current'
|
1016
|
+
nitem = Items.generate(cur, 'current', Items::ItemCurrent)
|
1006
1017
|
|
1007
1018
|
# write to cache
|
1008
1019
|
@cache.entry_write(cid, 1, eitem)
|
@@ -1041,22 +1052,22 @@ class Api
|
|
1041
1052
|
|
1042
1053
|
# form & content
|
1043
1054
|
if idx || cse
|
1044
|
-
Items.validate(ent, 'New Entry'
|
1055
|
+
Items.validate(ent, 'New Entry', Items::ItemEntryNew)
|
1045
1056
|
else
|
1046
|
-
Items.validate(ent, 'Editable Entry'
|
1057
|
+
Items.validate(ent, 'Editable Entry', Items::ItemEntryEdit)
|
1047
1058
|
end
|
1048
|
-
Items.validate(act, 'action'
|
1049
|
-
Items.validate(idx, 'index'
|
1050
|
-
Items.validate(cse, 'case'
|
1059
|
+
Items.validate(act, 'action', Items::ItemActionEdit) if act
|
1060
|
+
Items.validate(idx, 'index', Items::ItemIndexEdit) if idx
|
1061
|
+
Items.validate(cse, 'case', Items::ItemCaseEdit) if cse
|
1051
1062
|
|
1052
1063
|
# edit index OR case, not both
|
1053
1064
|
if idx && cse
|
1054
|
-
raise(Error::Value, 'May not edit both case and index at once'
|
1065
|
+
raise(Error::Value, 'May not edit both case and index at once')
|
1055
1066
|
end
|
1056
1067
|
|
1057
1068
|
# no changing the action
|
1058
1069
|
if act && ent['action'] && act['action'] && act['action'] != ent['action']
|
1059
|
-
raise(Error::Conflict, 'May not change entry\'s action'
|
1070
|
+
raise(Error::Conflict, 'May not change entry\'s action')
|
1060
1071
|
end
|
1061
1072
|
|
1062
1073
|
# access users/roles/groups are valid
|
@@ -1065,7 +1076,7 @@ class Api
|
|
1065
1076
|
acc['grant'].each do |gnt|
|
1066
1077
|
urg = @users.read(gnt)
|
1067
1078
|
if !urg
|
1068
|
-
raise(Error::NotFound, 'User/role/group %s not found'
|
1079
|
+
raise(Error::NotFound, 'User/role/group %s not found' % gnt)
|
1069
1080
|
end
|
1070
1081
|
end
|
1071
1082
|
end
|
@@ -1078,12 +1089,12 @@ class Api
|
|
1078
1089
|
tsk = act['tasks'][ix]
|
1079
1090
|
ur = @users.read(tsk['assigned'])
|
1080
1091
|
if !ur
|
1081
|
-
raise(Error::NotFound, 'User/role %s not found'
|
1092
|
+
raise(Error::NotFound, 'User/role %s not found' %
|
1082
1093
|
tsk['assigned'])
|
1083
1094
|
end
|
1084
1095
|
type = ur['type']
|
1085
1096
|
if type != 'user' && type != 'role'
|
1086
|
-
raise(Error::Values, 'Not a user or role: %s'
|
1097
|
+
raise(Error::Values, 'Not a user or role: %s' %
|
1087
1098
|
tsk['assigned'])
|
1088
1099
|
end
|
1089
1100
|
end
|
@@ -1157,13 +1168,13 @@ class Api
|
|
1157
1168
|
|
1158
1169
|
# current
|
1159
1170
|
json = @cache.current_read(cid)
|
1160
|
-
cur = Items.parse(json, 'current'
|
1171
|
+
cur = Items.parse(json, 'current', Items::ItemCurrent)
|
1161
1172
|
|
1162
1173
|
# entry
|
1163
1174
|
if ent['entry']
|
1164
1175
|
enum = ent['entry']
|
1165
1176
|
json = @cache.entry_read(cid, enum)
|
1166
|
-
ent_pri = Items.parse(json, 'entry'
|
1177
|
+
ent_pri = Items.parse(json, 'entry', Items::ItemEntry)
|
1167
1178
|
nxt['entry'] = cur['entry']
|
1168
1179
|
else
|
1169
1180
|
enum = cur['entry'] + 1
|
@@ -1180,7 +1191,7 @@ class Api
|
|
1180
1191
|
end
|
1181
1192
|
if anum
|
1182
1193
|
json = @cache.action_read(cid, anum)
|
1183
|
-
act_pri = Items.parse(json, 'action'
|
1194
|
+
act_pri = Items.parse(json, 'action', Items::ItemAction)
|
1184
1195
|
nxt['action'] = cur['action']
|
1185
1196
|
elsif act
|
1186
1197
|
anum = cur['action'] + 1
|
@@ -1225,7 +1236,7 @@ class Api
|
|
1225
1236
|
|
1226
1237
|
# may not change action
|
1227
1238
|
if ent_pri['action'] && (ent['action'] != ent_pri['action'])
|
1228
|
-
raise(Error::Conflict, 'May not change entry\'s action'
|
1239
|
+
raise(Error::Conflict, 'May not change entry\'s action')
|
1229
1240
|
end
|
1230
1241
|
|
1231
1242
|
# may not remove or add action, index, case tags
|
@@ -1235,7 +1246,7 @@ class Api
|
|
1235
1246
|
ent['tags'].include?(ICFS::TagIndex) ) ||
|
1236
1247
|
(ent_pri['tags'].include?(ICFS::TagCase) !=
|
1237
1248
|
ent['tags'].include?(ICFS::TagCase) ) )
|
1238
|
-
raise(Error::Conflict, 'May not change entry\'s special tags'
|
1249
|
+
raise(Error::Conflict, 'May not change entry\'s special tags')
|
1239
1250
|
end
|
1240
1251
|
end
|
1241
1252
|
|
@@ -1247,7 +1258,7 @@ class Api
|
|
1247
1258
|
|
1248
1259
|
# not allowed to delete tasks
|
1249
1260
|
if pri_tsk.size > cur_tsk.size
|
1250
|
-
raise(Error::Conflict, 'May not delete tasks'
|
1261
|
+
raise(Error::Conflict, 'May not delete tasks')
|
1251
1262
|
end
|
1252
1263
|
|
1253
1264
|
# check each task
|
@@ -1259,17 +1270,17 @@ class Api
|
|
1259
1270
|
|
1260
1271
|
# may not delete a tasking
|
1261
1272
|
if pt && pt['assigned'] != ct['assigned']
|
1262
|
-
raise(Error::Conflict, 'May not delete task'
|
1273
|
+
raise(Error::Conflict, 'May not delete task')
|
1263
1274
|
end
|
1264
1275
|
|
1265
1276
|
# new taskings require action to be open
|
1266
1277
|
if !pt && !act_open
|
1267
|
-
raise(Error::Value, 'New tasks require the action be open'
|
1278
|
+
raise(Error::Value, 'New tasks require the action be open')
|
1268
1279
|
end
|
1269
1280
|
|
1270
1281
|
# may not have a task open if action is closed
|
1271
1282
|
if ct['status'] && !act_open
|
1272
|
-
raise(Error::Value, 'Open tasks on closed action'
|
1283
|
+
raise(Error::Value, 'Open tasks on closed action')
|
1273
1284
|
end
|
1274
1285
|
|
1275
1286
|
# can set any values for our tasks
|
@@ -1280,7 +1291,7 @@ class Api
|
|
1280
1291
|
|
1281
1292
|
# must be flagged if new tasking or re-opening
|
1282
1293
|
if !ct['flag'] && (!pt || (ct['status'] && !pt['status']))
|
1283
|
-
raise(Error::Value, 'New or re-opened taskings must flag'
|
1294
|
+
raise(Error::Value, 'New or re-opened taskings must flag')
|
1284
1295
|
end
|
1285
1296
|
|
1286
1297
|
# no changing other's taskings, no deflagging, and no
|
@@ -1289,7 +1300,7 @@ class Api
|
|
1289
1300
|
(pt['title'] != ct['title']) || (pt['time'] != ct['time']) ||
|
1290
1301
|
(pt['tags'] != ct['tags']) || (pt['flag'] && !ct['flag']) ||
|
1291
1302
|
(pt['status'] && !ct['status'] && !perm_act) )
|
1292
|
-
raise(Error::Value, 'May not change other\'s tasks'
|
1303
|
+
raise(Error::Value, 'May not change other\'s tasks')
|
1293
1304
|
end
|
1294
1305
|
end
|
1295
1306
|
|
@@ -1306,7 +1317,7 @@ class Api
|
|
1306
1317
|
if cse
|
1307
1318
|
# no changing template
|
1308
1319
|
unless cse['template'] == cse_pri['template']
|
1309
|
-
raise(Error::Conflict, 'May not change template status'
|
1320
|
+
raise(Error::Conflict, 'May not change template status')
|
1310
1321
|
end
|
1311
1322
|
|
1312
1323
|
# manage required
|
@@ -1321,7 +1332,7 @@ class Api
|
|
1321
1332
|
# permissions
|
1322
1333
|
perms_miss = perms - al
|
1323
1334
|
unless perms_miss.empty?
|
1324
|
-
raise(Error::Perms, 'Missing perms: %s'
|
1335
|
+
raise(Error::Perms, 'Missing perms: %s' %
|
1325
1336
|
perms_miss.to_a.sort.join(', ') )
|
1326
1337
|
end
|
1327
1338
|
|
@@ -1342,7 +1353,7 @@ class Api
|
|
1342
1353
|
end
|
1343
1354
|
end
|
1344
1355
|
ent['files'].each{|fi| fi['log'] ||= lnum } if ent['files']
|
1345
|
-
eitem = Items.generate(ent, 'entry'
|
1356
|
+
eitem = Items.generate(ent, 'entry', Items::ItemEntry)
|
1346
1357
|
log['entry'] = {
|
1347
1358
|
'num' => enum,
|
1348
1359
|
'hash' => ICFS.hash(eitem)
|
@@ -1352,7 +1363,7 @@ class Api
|
|
1352
1363
|
if act
|
1353
1364
|
act['action'] = anum
|
1354
1365
|
act['log'] = lnum
|
1355
|
-
aitem = Items.generate(act, 'action'
|
1366
|
+
aitem = Items.generate(act, 'action', Items::ItemAction)
|
1356
1367
|
log['action'] = {
|
1357
1368
|
'num' => anum,
|
1358
1369
|
'hash' => ICFS.hash(aitem)
|
@@ -1363,7 +1374,7 @@ class Api
|
|
1363
1374
|
if idx
|
1364
1375
|
idx['index'] = xnum
|
1365
1376
|
idx['log'] = lnum
|
1366
|
-
xitem = Items.generate(idx, 'index'
|
1377
|
+
xitem = Items.generate(idx, 'index', Items::ItemIndex)
|
1367
1378
|
log['index'] = {
|
1368
1379
|
'num' => xnum,
|
1369
1380
|
'hash' => ICFS.hash(xitem)
|
@@ -1373,7 +1384,7 @@ class Api
|
|
1373
1384
|
# case
|
1374
1385
|
if cse
|
1375
1386
|
cse['log'] = lnum
|
1376
|
-
citem = Items.generate(cse, 'case'
|
1387
|
+
citem = Items.generate(cse, 'case', Items::ItemCase)
|
1377
1388
|
log['case_hash'] = ICFS.hash(citem)
|
1378
1389
|
end
|
1379
1390
|
|
@@ -1381,11 +1392,11 @@ class Api
|
|
1381
1392
|
log['log'] = lnum
|
1382
1393
|
log['prev'] = cur['hash']
|
1383
1394
|
log['time'] = now
|
1384
|
-
litem = Items.generate(log, 'log'
|
1395
|
+
litem = Items.generate(log, 'log', Items::ItemLog)
|
1385
1396
|
nxt['hash'] = ICFS.hash(litem)
|
1386
1397
|
|
1387
1398
|
# next
|
1388
|
-
nitem = Items.generate(nxt, 'current'
|
1399
|
+
nitem = Items.generate(nxt, 'current', Items::ItemCurrent)
|
1389
1400
|
|
1390
1401
|
|
1391
1402
|
####################
|