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.rb
CHANGED
@@ -9,7 +9,10 @@
|
|
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
|
require 'digest/sha2'
|
15
|
+
require 'date'
|
13
16
|
|
14
17
|
require_relative 'icfs/validate'
|
15
18
|
|
@@ -18,38 +21,49 @@ require_relative 'icfs/validate'
|
|
18
21
|
#
|
19
22
|
module ICFS
|
20
23
|
|
24
|
+
# version: major, minor, patch
|
25
|
+
Version = [0, 2, 0].freeze
|
26
|
+
|
27
|
+
# version pre-release
|
28
|
+
VersionPre = nil
|
29
|
+
|
30
|
+
# version string
|
31
|
+
VersionString = (
|
32
|
+
'%d.%d.%d' % Version +
|
33
|
+
(VersionPre ? ('-' + VersionPre) : '')
|
34
|
+
).freeze
|
21
35
|
|
22
36
|
# no tags
|
23
|
-
TagNone = '[none]'
|
37
|
+
TagNone = '[none]'
|
24
38
|
|
25
39
|
# edits an action
|
26
|
-
TagAction = '[action]'
|
40
|
+
TagAction = '[action]'
|
27
41
|
|
28
42
|
# edits an index
|
29
|
-
TagIndex = '[index]'
|
43
|
+
TagIndex = '[index]'
|
30
44
|
|
31
45
|
# edits the case
|
32
|
-
TagCase = '[case]'
|
46
|
+
TagCase = '[case]'
|
33
47
|
|
34
48
|
|
35
49
|
# permission to read case
|
36
|
-
PermRead = '[read]'
|
50
|
+
PermRead = '[read]'
|
37
51
|
|
38
52
|
# permission to write case
|
39
|
-
PermWrite = '[write]'
|
53
|
+
PermWrite = '[write]'
|
40
54
|
|
41
55
|
# permission to manage case
|
42
|
-
PermManage = '[manage]'
|
56
|
+
PermManage = '[manage]'
|
43
57
|
|
44
58
|
# permission to manage actions
|
45
|
-
PermAction = '[action]'
|
59
|
+
PermAction = '[action]'
|
46
60
|
|
47
61
|
# global permission to search
|
48
|
-
PermSearch = '{[search]}'
|
62
|
+
PermSearch = '{[search]}'
|
49
63
|
|
50
64
|
|
51
65
|
# user group
|
52
|
-
UserCase = '[case]'
|
66
|
+
UserCase = '[case]'
|
53
67
|
|
54
68
|
|
55
69
|
###############################################
|
@@ -67,6 +81,156 @@ module ICFS
|
|
67
81
|
end
|
68
82
|
|
69
83
|
|
84
|
+
###############################################
|
85
|
+
# Pull a time type
|
86
|
+
#
|
87
|
+
# @api private
|
88
|
+
#
|
89
|
+
def self._time_type(str)
|
90
|
+
case str.downcase
|
91
|
+
when 'y', 'yr', 'yrs', 'year', 'years'
|
92
|
+
return :year
|
93
|
+
when 'm', 'mon', 'mons', 'month', 'months'
|
94
|
+
return :month
|
95
|
+
when 'w', 'wk', 'wks', 'week', 'weeks'
|
96
|
+
return :week
|
97
|
+
when 'd', 'day', 'days'
|
98
|
+
return :day
|
99
|
+
when 'h', 'hr', 'hrs', 'hour', 'hours'
|
100
|
+
return :hour
|
101
|
+
when 'min', 'mins', 'minute', 'minutes'
|
102
|
+
return :minute
|
103
|
+
when 's', 'sec', 'secs', 'second', 'seconds'
|
104
|
+
return :second
|
105
|
+
else
|
106
|
+
return nil
|
107
|
+
end
|
108
|
+
end # self._time_type()
|
109
|
+
|
110
|
+
|
111
|
+
###############################################
|
112
|
+
# Adjust the time
|
113
|
+
#
|
114
|
+
# @api private
|
115
|
+
#
|
116
|
+
def self._time_adjust(num, type)
|
117
|
+
case type
|
118
|
+
when :year
|
119
|
+
ary = Time.now.utc.to_a
|
120
|
+
dte = Date.new(ary[5], ary[4], ary[3])
|
121
|
+
dte = dte << (-12 * num)
|
122
|
+
return Time.utc(dte.year, dte.month, dte.day,
|
123
|
+
ary[2], ary[1], ary[0]).to_i
|
124
|
+
when :month
|
125
|
+
ary = Time.now.utc.to_a
|
126
|
+
dte = Date.new(ary[5], ary[4], ary[3])
|
127
|
+
dte = dte << (-1 * num)
|
128
|
+
return Time.utc(dte.year, dte.month, dte.day,
|
129
|
+
ary[2], ary[1], ary[0]).to_i
|
130
|
+
when :week
|
131
|
+
return (Time.now + num * 7*24*60*60).to_i
|
132
|
+
when :day
|
133
|
+
return (Time.now + num * 24*60*60).to_i
|
134
|
+
when :hour
|
135
|
+
return (Time.now + num * 60*60).to_i
|
136
|
+
when :minute
|
137
|
+
return (Time.now + num * 60).to_i
|
138
|
+
when :second
|
139
|
+
return (Time.now + num).to_i
|
140
|
+
else
|
141
|
+
return nil
|
142
|
+
end
|
143
|
+
end
|
144
|
+
|
145
|
+
|
146
|
+
###############################################
|
147
|
+
# A time delta spec
|
148
|
+
TimeDelta = /^[[:space:]]*([Nn][Oo][Ww])?[[:space:]]*([+\-])[[:space:]]*(\d+)[[:space:]]*([^[space]]+)[[:space]]*$/.freeze
|
149
|
+
|
150
|
+
|
151
|
+
###############################################
|
152
|
+
# a relative spec
|
153
|
+
TimeRel = /^[[:space:]]*([Nn][Ee][Xx][Tt]|[Pp][Rr][Ee][Vv]|[Ll][Aa][Ss][Tt])[[:space:]]+([^[:space:]]+)[[:space:]]*$/.freeze
|
154
|
+
|
155
|
+
|
156
|
+
###############################################
|
157
|
+
# future time spec
|
158
|
+
TimeFuture = /^[[:space:]]*[Ii][Nn][[:space:]]+(\d+)[[:space:]]*([^[space]]+)[[:space]]*$/.freeze
|
159
|
+
|
160
|
+
|
161
|
+
###############################################
|
162
|
+
# historic time spec
|
163
|
+
TimeHistory = /^[[:space:]]*(\d+)[[:space:]]*([^[:space:]]+)[[:space:]]*[Aa][Gg][Oo][[:space:]]*$/.freeze
|
164
|
+
|
165
|
+
|
166
|
+
###############################################
|
167
|
+
# empty time spec
|
168
|
+
TimeEmpty = /^[[:space:]]*([Nn][Oo][Ww])?[[:space:]]*$/.freeze
|
169
|
+
|
170
|
+
|
171
|
+
###############################################
|
172
|
+
# A timezone spec
|
173
|
+
TimeZone = /[+\-]\d{2}:\d{2}[[:space:]]*$/.freeze
|
174
|
+
|
175
|
+
|
176
|
+
###############################################
|
177
|
+
# Parse a time string
|
178
|
+
#
|
179
|
+
# @param str [String] the time string
|
180
|
+
# @param cfg [Config] the config
|
181
|
+
#
|
182
|
+
# Handles:
|
183
|
+
# * blank or now
|
184
|
+
# * \[now\] +\\- <num> <type>
|
185
|
+
# * next\\prev <type>
|
186
|
+
# * in <num> <type>
|
187
|
+
# * <num> <type> ago
|
188
|
+
# * a specifc parseable time
|
189
|
+
#
|
190
|
+
def self.time_parse(str, cfg)
|
191
|
+
return nil if( !str || !str.is_a?(String) )
|
192
|
+
|
193
|
+
# empty
|
194
|
+
if ma = TimeEmpty.match(str)
|
195
|
+
return Time.now.to_i
|
196
|
+
|
197
|
+
# delta
|
198
|
+
elsif ma = TimeDelta.match(str)
|
199
|
+
num = ma[3].to_i
|
200
|
+
num = num * -1 if ma[2] == '-'
|
201
|
+
type = ICFS._time_type(ma[4])
|
202
|
+
return ICFS._time_adjust(num, type)
|
203
|
+
|
204
|
+
# relative
|
205
|
+
elsif ma = TimeRel.match(str)
|
206
|
+
num = (ma[1].downcase == 'next') ? 1 : -1
|
207
|
+
type = ICFS._time_type(ma[2])
|
208
|
+
return ICFS._time_adjust(num, type)
|
209
|
+
|
210
|
+
# future
|
211
|
+
elsif ma = TimeFuture.match(str)
|
212
|
+
num = ma[1].to_i
|
213
|
+
type = ICFS._time_type(ma[2])
|
214
|
+
return ICFS._time_adjust(num, type)
|
215
|
+
|
216
|
+
# history
|
217
|
+
elsif ma = TimeHistory.match(str)
|
218
|
+
p ma
|
219
|
+
num = -1 * ma[1].to_i
|
220
|
+
type = ICFS._time_type(ma[2])
|
221
|
+
return ICFS._time_adjust(num, type)
|
222
|
+
|
223
|
+
# parse a time spec
|
224
|
+
else
|
225
|
+
ma = TimeZone.match(str)
|
226
|
+
tstr = ma ? str : str + cfg.get('tz')
|
227
|
+
return Time.parse(tstr).to_i
|
228
|
+
|
229
|
+
end
|
230
|
+
|
231
|
+
rescue ArgumentError
|
232
|
+
return nil
|
233
|
+
end # def self.time_parse()
|
70
234
|
|
71
235
|
|
72
236
|
##########################################################################
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: icfs
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.2.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Graham A. Field
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2019-06-
|
11
|
+
date: 2019-06-29 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |2-
|
14
14
|
|
@@ -25,23 +25,35 @@ extra_rdoc_files: []
|
|
25
25
|
files:
|
26
26
|
- LICENSE.txt
|
27
27
|
- bin/icfs_demo_fcgi.rb
|
28
|
-
- bin/icfs_demo_ssl_gen.rb
|
29
28
|
- data/icfs.css
|
30
29
|
- data/icfs.js
|
31
|
-
- devel/
|
30
|
+
- devel/demo/ssl_gen.rb
|
31
|
+
- devel/demo/ssl_gen.yml
|
32
32
|
- devel/docker-compose.yml
|
33
33
|
- devel/icfs
|
34
34
|
- devel/icfs-wrk/Dockerfile
|
35
|
+
- devel/run/base.rb
|
35
36
|
- devel/run/copy-s3.rb
|
37
|
+
- devel/run/email.rb
|
38
|
+
- devel/run/email_imap.rb
|
39
|
+
- devel/run/email_smime.rb
|
36
40
|
- devel/run/init-icfs.rb
|
37
41
|
- devel/run/webrick.rb
|
38
42
|
- lib/icfs.rb
|
39
43
|
- lib/icfs/api.rb
|
40
44
|
- lib/icfs/cache.rb
|
41
45
|
- lib/icfs/cache_elastic.rb
|
46
|
+
- lib/icfs/config.rb
|
47
|
+
- lib/icfs/config_redis.rb
|
48
|
+
- lib/icfs/config_s3.rb
|
42
49
|
- lib/icfs/demo/auth.rb
|
43
50
|
- lib/icfs/demo/static.rb
|
44
51
|
- lib/icfs/elastic.rb
|
52
|
+
- lib/icfs/email/basic.rb
|
53
|
+
- lib/icfs/email/core.rb
|
54
|
+
- lib/icfs/email/from.rb
|
55
|
+
- lib/icfs/email/imap.rb
|
56
|
+
- lib/icfs/email/smime.rb
|
45
57
|
- lib/icfs/items.rb
|
46
58
|
- lib/icfs/store.rb
|
47
59
|
- lib/icfs/store_fs.rb
|
@@ -55,9 +67,6 @@ files:
|
|
55
67
|
- lib/icfs/validate.rb
|
56
68
|
- lib/icfs/web/auth_ssl.rb
|
57
69
|
- lib/icfs/web/client.rb
|
58
|
-
- lib/icfs/web/config.rb
|
59
|
-
- lib/icfs/web/config_redis.rb
|
60
|
-
- lib/icfs/web/config_s3.rb
|
61
70
|
homepage: https://github.com/g4field/icfs
|
62
71
|
licenses:
|
63
72
|
- GPL-3.0
|
data/devel/devel-webrick.yml
DELETED
@@ -1,49 +0,0 @@
|
|
1
|
-
#
|
2
|
-
# Investigative Case File System
|
3
|
-
#
|
4
|
-
# Copyright 2019 by Graham A. Field
|
5
|
-
#
|
6
|
-
# This program is free software: you can redistribute it and/or modify
|
7
|
-
# it under the terms of the GNU General Public License version 3.
|
8
|
-
#
|
9
|
-
# This program is distributed WITHOUT ANY WARRANTY; without even the
|
10
|
-
# implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
11
|
-
|
12
|
-
version: '3'
|
13
|
-
|
14
|
-
services:
|
15
|
-
|
16
|
-
# Elasticsearch instance
|
17
|
-
elastic:
|
18
|
-
image: docker.elastic.co/elasticsearch/elasticsearch:6.7.2
|
19
|
-
environment:
|
20
|
-
discovery-type: single-node
|
21
|
-
volume:
|
22
|
-
- elastic:/usr/share/elasticsearch/data
|
23
|
-
ports:
|
24
|
-
- "127.0.0.1:9200:9200"
|
25
|
-
|
26
|
-
# Minio S3-compatible object store
|
27
|
-
minio:
|
28
|
-
image: minio/minio
|
29
|
-
environment:
|
30
|
-
MINIO_ACCESS_KEY: minio_key
|
31
|
-
MINIO_SECRET_KEY: minio_secret
|
32
|
-
volume:
|
33
|
-
- minio:/data
|
34
|
-
command: ["server", "/data"]
|
35
|
-
|
36
|
-
# Redis cache
|
37
|
-
redis:
|
38
|
-
image: redis:alpine
|
39
|
-
|
40
|
-
# the app
|
41
|
-
app:
|
42
|
-
image: icfs-wrk
|
43
|
-
ports:
|
44
|
-
- "127.0.0.1:80:8080"
|
45
|
-
|
46
|
-
|
47
|
-
volumes:
|
48
|
-
- elastic
|
49
|
-
- minio
|