Module: ICFS::Items

Defined in:
lib/icfs/items.rb

Overview

Items

Constant Summary collapse

FieldIcfs =

ICFS version

{
  method: :integer,
  min: 1,
  max: 1,
}.freeze
FieldCaseid =

Caseid

{
  method: :string,
  min: 1,
  max: 32,
  invalid: /[[:cntrl:][:space:]"\#$%'()*+\/;<=>?@\[\]\\^`{|}~]/.freeze,
}.freeze
FieldTitle =

Title

{
  method: :string,
  min: 1,
  max: 128,
  invalid: /[[:cntrl:]]/.freeze,
}.freeze
FieldTag =

Tag No control characters may not start with brackets or whitespace

{
  method: :string,
  min: 1,
  max: 32,
  invalid: /[[:cntrl:]]|^[\[\{ ]/.freeze,
}.freeze
FieldTagEntry =

Tag for Entry

{
  method: :string,
  min: 1,
  max: 32,
  allowed: Set[
    ICFS::TagAction,
    ICFS::TagIndex,
    ICFS::TagCase,
  ].freeze,
  invalid: /[[:cntrl:]]|^[\[\{ ]/.freeze,
}.freeze
FieldTagSpecial =

Special tags

{
  method: :string,
  allowed: Set[
    ICFS::TagNone,
    ICFS::TagAction,
    ICFS::TagIndex,
    ICFS::TagCase,
  ].freeze,
  whitelist: true,
}.freeze
FieldTagAny =

Any tag, including empty

{
  method: :any,
  check: [
    FieldTag,
    FieldTagSpecial
  ].freeze,
}.freeze
FieldPermNormal =

a normal perm name No control characters may not start with square brackets, curly brackets, or whitespace

{
  method: :string,
  min: 1,
  max: 64,
  invalid: /[[:cntrl:]]|^[\[\{ ]/.freeze,
}.freeze
FieldPermReserve =

A reserved case name square brackets

{
  method: :string,
  allowed: Set[
    ICFS::PermRead,
    ICFS::PermWrite,
    ICFS::PermManage,
    ICFS::PermAction
  ].freeze,
  whitelist: true
}.freeze
FieldPermGlobal =

A global permission curly brackets, no control characters

{
  method: :string,
  min: 1,
  max: 64,
  valid: /^\{[^[:cntrl:]]+\}$/.freeze,
  whitelist: true,
}.freeze
FieldPermCase =

A case perm

{
  method: :any,
  check: [
    FieldPermNormal,
    FieldPermReserve,
  ].freeze
}.freeze
FieldPermAny =

Any perm

{
  method: :any,
  check: [
    FieldPermNormal,
    FieldPermReserve,
    FieldPermGlobal,
  ].freeze
}.freeze
FieldUsergrp =

a user/group name No control characters no space, no punctuation except , - : _

{
  method: :string,
  min: 3,
  max: 32,
  invalid: /[\x00-\x2b\x2e\x2f\x3b-\x40\x5b-\x5e\x60\x7b-\x7f]/.freeze,
}.freeze
FieldHash =

a hash

{
  method: :string,
  min: 64,
  max: 64,
  invalid: /[^0-9a-f]/.freeze
}.freeze
FieldContent =

Content

{
  method: :string,
  min: 1,
  max: 8*1024,
  invalid: /[^[:graph:][:space:]]/.freeze,
}.freeze
FieldStat =

a stat name

{
  method: :string,
  min: 1,
  max: 32,
  invalid: /[[:cntrl:]\t\r\n\v\f]|^_/.freeze,
}.freeze
FieldFilename =

a filename

{
  method: :string,
  min: 1,
  max: 128,
  invalid: /[[:cntrl:]\\\/]|^\./.freeze
}.freeze
SubTagsEmpty =

Empty Tags

{
  method: :array,
  min: 1,
  max: 1,
  check: {
    method: :equals,
    check: ICFS::TagNone
  }.freeze
}.freeze
SubTagsEntry =

Entry Tags

{
  method: :array,
  min: 1,
  check: FieldTagEntry
}.freeze
SubTagsNormal =

Tags

{
  method: :array,
  min: 1,
  check: FieldTag
}.freeze
SubTags =

Tags

{
  method: :any,
  check: [ SubTagsEmpty, SubTagsNormal ].freeze
}.freeze
SubGrant =

Grant

{
  method: :hash,
  required: {
    'perm' => FieldPermCase,
    'grant' => {
      method: :array,
      min: 1,
      check: FieldUsergrp
    }.freeze
  }.freeze
}.freeze
SubAccess =

Access

{
  method: :array,
  min: 1,
  check: SubGrant
}.freeze
SubCaseStats =

Case stats

{
  method: :array,
  min:1,
  check: FieldStat,
}.freeze
SubLogItem =

An item in a log

{
  method: :hash,
  required: {
    'num' => Validate::IsIntPos,
    'hash' => FieldHash,
  }.freeze
}.freeze
SubIndexes =

Indexes

{
  method: :array,
  min: 1,
  check: Validate::IsIntPos,
}.freeze
SubPerms =

Perms

{
  method: :array,
  min: 1,
  check: FieldPermAny
}.freeze
SubStats =

Stats

{
  method: :array,
  min: 1,
  check: {
    method: :hash,
    required: {
      "name" => FieldStat,
      "value" => Validate::IsFloat,
      "credit" => {
        method: :array,
        min: 1,
        max: 32,
        check: FieldUsergrp
      }.freeze
    }.freeze
  }.freeze
}.freeze
SubFileOld =

An old file

{
  method: :hash,
  required: {
    'log' => Validate::IsIntPos,
    'num' => Validate::IsIntUns,
    'name' => FieldFilename,
  }.freeze
}.freeze
SubTaskCase =

Case task

{
  method: :hash,
  required: {
    'assigned' => {
      method: :string,
      allowed: Set[ ICFS::UserCase ].freeze,
      whitelist: true
    }.freeze,
    'title' => FieldTitle,
    'status' => Validate::IsBoolean,
    'flag' => Validate::IsBoolean,
    'time' => Validate::IsIntPos,
    'tags' => SubTags
  }.freeze
}.freeze
SubTaskNormal =

Normal task

{
  method: :hash,
  required: {
    'assigned' => FieldUsergrp,
    'title' => FieldTitle,
    'status' => Validate::IsBoolean,
    'flag' => Validate::IsBoolean,
    'time' => Validate::IsIntPos,
    'tags' => SubTags
  }.freeze
}.freeze
SubTasks =

Tasks

{
  method: :array,
  min: 1,
  0 => SubTaskCase,
  check: SubTaskNormal
}.freeze
SubTaskEditCase =

Case task

{
  method: :hash,
  required: {
    'assigned' => {
      method: :string,
      allowed: Set[ ICFS::UserCase ].freeze,
      whitelist: true
    }.freeze,
    'title' => FieldTitle,
    'status' => Validate::IsBoolean,
    'flag' => Validate::IsBoolean,
    'time' => Validate::IsIntPos,
  }.freeze,
  optional: {
    'tags' => SubTags
  }.freeze
}.freeze
SubTaskEditNormal =

Normal task

{
  method: :hash,
  required: {
    'assigned' => FieldUsergrp,
    'title' => FieldTitle,
    'status' => Validate::IsBoolean,
    'flag' => Validate::IsBoolean,
    'time' => Validate::IsIntPos,
  }.freeze,
  optional: {
    'tags' => SubTags
  }.freeze
}.freeze
SubTasksEdit =

TasksEdit

{
  method: :array,
  min: 1,
  0 => SubTaskEditCase,
  check: SubTaskEditNormal,
}.freeze
SubFileNew =

A new file

{
  method: :hash,
  required: {
    'temp' => Validate::IsTempfile,
    'name' => FieldFilename,
  }.freeze
}.freeze
ItemCaseEdit =

Case - Edit

{
  method: :hash,
  required: {
    'template' => Validate::IsBoolean,
    'status' => Validate::IsBoolean,
    'title' => FieldTitle,
    'access' => SubAccess,
  }.freeze,
  optional: {
    'caseid' => FieldCaseid,
    'tags' => SubTags,
    'stats' => SubCaseStats,
  }.freeze
}.freeze
ItemEntryNew =

Entry - New only

{
  method: :hash,
  required: {
    'title' => FieldTitle,
    'content' => FieldContent,
  }.freeze,
  optional: {
    'caseid' => FieldCaseid,
    'time' => Validate::IsIntPos,
    'tags' => SubTagsNormal,
    'index' => SubIndexes,
    'action' => Validate::IsIntPos,
    'perms' => SubPerms,
    'stats' => SubStats,
    'files' => {
      method: :array,
      min: 1,
      check: SubFileNew
    }.freeze
  }.freeze
}.freeze
ItemEntryEdit =

Entry - Edit or New

{
  method: :hash,
  required: {
    'title' => FieldTitle,
    'content' => FieldContent,
  }.freeze,
  optional: {
    'caseid' => FieldCaseid,
    'entry' => Validate::IsIntPos,
    'time' => Validate::IsIntPos,
    'tags' => SubTagsEntry,
    'index' => SubIndexes,
    'action' => Validate::IsIntPos,
    'perms' => SubPerms,
    'stats' => SubStats,
    'files' => {
      method: :array,
      min: 1,
      check: {
        method: :any,
        check: [ SubFileOld, SubFileNew ].freeze
      }.freeze
    }.freeze
  }.freeze
}.freeze
ItemActionEdit =

Action - Edit or New

{
  method: :hash,
  required: {
    'tasks' => SubTasksEdit
  }.freeze,
  optional: {
    'caseid' => FieldCaseid,
    'action' => Validate::IsIntPos
  }.freeze
}.freeze
ItemIndexEdit =

Index - Edit or New

{
  method: :hash,
  required: {
    'title' => FieldTitle,
    'content' => FieldContent,
  }.freeze,
  optional: {
    'caseid' => FieldCaseid,
    'index' => Validate::IsIntPos,
    'tags' => SubTags,
  }.freeze
}.freeze
ItemCase =

Case

{
  method: :hash,
  required: {
    'icfs' => FieldIcfs,
    'caseid' => FieldCaseid,
    'log' => Validate::IsIntPos,
    'template' => Validate::IsBoolean,
    'status' => Validate::IsBoolean,
    'title' => FieldTitle,
    'tags' => SubTags,
    'access' => SubAccess,
  }.freeze,
  optional: {
    'stats' => SubCaseStats,
    'entry' => Validate::IsIntPos,
  }.freeze,
}.freeze
ItemLog =

Log

{
  method: :hash,
  required: {
    'icfs' => FieldIcfs,
    'caseid' => FieldCaseid,
    'log' => Validate::IsIntPos,
    'prev' => FieldHash,
    'time' => Validate::IsIntPos,
    'user' => FieldUsergrp,
  }.freeze,
  optional: {
    'entry' => SubLogItem,
    'index' => SubLogItem,
    'action' => SubLogItem,
    'case' => {
      method: :hash,
      required: {
        'set' => Validate::IsBoolean,
        'hash' => FieldHash,
      }.freeze,
    }.freeze,
    'files_hash' => {
      method: :array,
      min: 1,
      check: FieldHash
    }.freeze,
  }.freeze,
}.freeze
ItemEntry =

Entry

{
  method: :hash,
  required: {
    'icfs' => FieldIcfs,
    'caseid' => FieldCaseid,
    'entry' => Validate::IsIntPos,
    'log' => Validate::IsIntPos,
    'user' => FieldUsergrp,
    'time' => Validate::IsIntPos,
    'title' => FieldTitle,
    'content' => FieldContent,
    'tags' => {
      method: :any,
      check: [
        SubTagsEmpty,
        SubTagsEntry,
      ].freeze
    }.freeze,
  }.freeze,
  optional: {
    'index' => SubIndexes,
    'action' => Validate::IsIntPos,
    'perms' => SubPerms,
    'stats' => SubStats,
    'files' => {
      method: :array,
      min: 1,
      check: SubFileOld
    }.freeze
  }.freeze
}.freeze
ItemAction =

Action

{
  method: :hash,
  required: {
    'icfs' => FieldIcfs,
    'caseid' => FieldCaseid,
    'action' => Validate::IsIntPos,
    'log' => Validate::IsIntPos,
    'tasks' => SubTasks
  }.freeze,
  optional: {
    'entry' => Validate::IsIntPos,
  }.freeze
}.freeze
ItemIndex =

Index

{
  method: :hash,
  required: {
    'icfs' => FieldIcfs,
    'caseid' => FieldCaseid,
    'index' => Validate::IsIntPos,
    'log' => Validate::IsIntPos,
    'title' => FieldTitle,
    'content' => FieldContent,
    'tags' => SubTags
  }.freeze,
  optional: {
    'entry' => Validate::IsIntPos,
  }.freeze
}.freeze
ItemCurrent =

Current

{
  method: :hash,
  required: {
    'icfs' => FieldIcfs,
    'caseid' => FieldCaseid,
    'log' => Validate::IsIntPos,
    'hash' => FieldHash,
    'entry' => Validate::IsIntPos,
    'action' => Validate::IsIntUns,
    'index' => Validate::IsIntUns,
  }.freeze
}.freeze

Class Method Summary collapse

Class Method Details

.generate(itm, name, val) ⇒ String

Validate and generate JSON

Parameters:

  • itm (Object)

    item to validate

  • name (String)

    description of the item

  • val (Hash)

    the check to use

Returns:

  • (String)

    JSON encoded item

Raises:



61
62
63
64
# File 'lib/icfs/items.rb', line 61

def self.generate(itm, name, val)
  Items.validate(itm, name, val)
  return JSON.pretty_generate(itm)
end

.parse(json, name, val) ⇒ Object

Parse JSON string and validate

Parameters:

  • json (String)

    the JSON to parse

  • name (String)

    description of the item

  • val (Hash)

    the check to use

Returns:

  • (Object)

    the item

Raises:



37
38
39
40
41
42
43
44
45
46
47
48
# File 'lib/icfs/items.rb', line 37

def self.parse(json, name, val)
  if json.nil?
    raise(Error::NotFound, '%s not found' % name)
  end
  begin
    itm = JSON.parse(json)
  rescue
    raise(Error::Value, 'JSON parsing failed')
  end
  Items.validate(itm, name, val)
  return itm
end

.validate(obj, name, val) ⇒ Object

Validate an object

Parameters:

  • obj (Object)

    object to validate

  • name (String)

    description of the object

  • val (Hash)

    the check to use

Raises:



76
77
78
79
80
81
82
# File 'lib/icfs/items.rb', line 76

def self.validate(obj, name, val)
  err = Validate.check(obj, val)
  if err
    raise(Error::Value, '%s has bad values: %s' %
      [name, err.inspect])
  end
end