icfs 0.1.3 → 0.2.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (42) hide show
  1. checksums.yaml +4 -4
  2. data/bin/icfs_demo_fcgi.rb +2 -0
  3. data/{bin/icfs_demo_ssl_gen.rb → devel/demo/ssl_gen.rb} +25 -13
  4. data/devel/demo/ssl_gen.yml +14 -0
  5. data/devel/icfs-wrk/Dockerfile +1 -1
  6. data/devel/run/base.rb +92 -0
  7. data/devel/run/copy-s3.rb +2 -0
  8. data/devel/run/email.rb +36 -0
  9. data/devel/run/email_imap.rb +43 -0
  10. data/devel/run/email_smime.rb +47 -0
  11. data/devel/run/init-icfs.rb +2 -0
  12. data/devel/run/webrick.rb +5 -57
  13. data/lib/icfs/api.rb +101 -90
  14. data/lib/icfs/cache.rb +2 -0
  15. data/lib/icfs/cache_elastic.rb +127 -125
  16. data/lib/icfs/{web/config.rb → config.rb} +3 -3
  17. data/lib/icfs/{web/config_redis.rb → config_redis.rb} +8 -8
  18. data/lib/icfs/{web/config_s3.rb → config_s3.rb} +8 -8
  19. data/lib/icfs/demo/auth.rb +5 -7
  20. data/lib/icfs/demo/static.rb +2 -0
  21. data/lib/icfs/elastic.rb +10 -8
  22. data/lib/icfs/email/basic.rb +242 -0
  23. data/lib/icfs/email/core.rb +293 -0
  24. data/lib/icfs/email/from.rb +52 -0
  25. data/lib/icfs/email/imap.rb +148 -0
  26. data/lib/icfs/email/smime.rb +139 -0
  27. data/lib/icfs/items.rb +5 -3
  28. data/lib/icfs/store.rb +20 -18
  29. data/lib/icfs/store_fs.rb +7 -5
  30. data/lib/icfs/store_s3.rb +4 -2
  31. data/lib/icfs/users.rb +5 -3
  32. data/lib/icfs/users_fs.rb +8 -6
  33. data/lib/icfs/users_redis.rb +12 -10
  34. data/lib/icfs/users_s3.rb +6 -4
  35. data/lib/icfs/utils/backup.rb +30 -29
  36. data/lib/icfs/utils/check.rb +36 -34
  37. data/lib/icfs/validate.rb +24 -15
  38. data/lib/icfs/web/auth_ssl.rb +7 -9
  39. data/lib/icfs/web/client.rb +671 -679
  40. data/lib/icfs.rb +174 -10
  41. metadata +16 -7
  42. 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'.freeze) if !urgp
71
- raise(Error::Value, 'Not a user'.freeze) if urgp['type'] != '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'.freeze % [cid, anum]
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'.freeze, Items::ItemCase)
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'.freeze, Items::ItemCase)
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'.freeze % ICFS::PermRead)
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'.freeze, Items::ItemLog)
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'.freeze, Items::ItemEntry)
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'.freeze %
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'.freeze, Items::ItemEntry)
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'.freeze) if !fi
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'.freeze % [cid, anum]
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'.freeze, Items::ItemAction)
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'.freeze % ICFS::PermRead )
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'.freeze, Items::ItemAction)
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'.freeze % ICFS::PermRead )
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'.freeze, Items::ItemIndex)
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'.freeze, Items::ItemIndex)
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'.freeze % ICFS::PermRead)
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'.freeze, Items::ItemCurrent)
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'.freeze, ValCaseSearch)
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'.freeze,
520
- 'time_asc'.freeze,
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'.freeze, ValLogSearch)
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'.freeze,
560
- 'time_asc'.freeze,
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'.freeze, ValEntrySearch)
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'.freeze)
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'.freeze,
649
- 'time_asc'.freeze,
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'.freeze, ValActionSearch)
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'.freeze)
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'.freeze,
693
- 'title_asc'.freeze,
694
- 'index_desc'.freeze,
695
- 'index_asc'.freeze,
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'.freeze, ValIndexSearch)
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'.freeze)
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'.freeze, ValStatsSearch)
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'.freeze)
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'.freeze, ValCaseTags)
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'.freeze, ValEntryTags)
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'.freeze % ICFS::PermRead)
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'.freeze, ValActionTags)
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'.freeze)
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'.freeze, ValIndexTags)
881
+ Items.validate(query, 'Index Tags', ValIndexTags)
871
882
  unless access_list(query[:caseid]).include?(ICFS::PermRead)
872
- raise(Error::Perms, 'missing perms: %s'.freeze % ICFS::PermRead)
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'.freeze, Items::ItemEntryNew)
898
- Items.validate(cse, 'case'.freeze, Items::ItemCaseEdit)
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'.freeze % urg)
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'.freeze)
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'.freeze)
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'.freeze)
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'.freeze)
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'.freeze) if user.nil?
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'.freeze, Items::ItemCase)
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'.freeze)
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'.freeze, Items::ItemEntry)
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'.freeze, Items::ItemLog)
1014
+ litem = Items.generate(log, 'log', Items::ItemLog)
1004
1015
  cur['hash'] = ICFS.hash(litem)
1005
- nitem = Items.generate(cur, 'current'.freeze, Items::ItemCurrent)
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'.freeze, Items::ItemEntryNew)
1055
+ Items.validate(ent, 'New Entry', Items::ItemEntryNew)
1045
1056
  else
1046
- Items.validate(ent, 'Editable Entry'.freeze, Items::ItemEntryEdit)
1057
+ Items.validate(ent, 'Editable Entry', Items::ItemEntryEdit)
1047
1058
  end
1048
- Items.validate(act, 'action'.freeze, Items::ItemActionEdit) if act
1049
- Items.validate(idx, 'index'.freeze, Items::ItemIndexEdit) if idx
1050
- Items.validate(cse, 'case'.freeze, Items::ItemCaseEdit) if cse
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'.freeze)
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'.freeze)
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'.freeze % gnt)
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'.freeze %
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'.freeze %
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'.freeze, Items::ItemCurrent)
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'.freeze, Items::ItemEntry)
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'.freeze, Items::ItemAction)
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'.freeze)
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'.freeze)
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'.freeze)
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'.freeze)
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'.freeze)
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'.freeze)
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'.freeze)
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'.freeze)
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'.freeze)
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'.freeze %
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'.freeze, Items::ItemEntry)
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'.freeze, Items::ItemAction)
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'.freeze, Items::ItemIndex)
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'.freeze, Items::ItemCase)
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'.freeze, Items::ItemLog)
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'.freeze, Items::ItemCurrent)
1399
+ nitem = Items.generate(nxt, 'current', Items::ItemCurrent)
1389
1400
 
1390
1401
 
1391
1402
  ####################
data/lib/icfs/cache.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