scim-kit 0.3.2 → 0.5.2

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cd17a93f0e199bc2b7312d8643714ed2735724f911da7af62366e7b02f42fc5e
4
- data.tar.gz: 8bc20d24ddc2593667785155056b278a06c10f73a83c5d76d0c9b661c9acf73e
3
+ metadata.gz: 8191e7a73edef42d693bc7fee15fcb14036f37c6cb622aab488bf626fd490538
4
+ data.tar.gz: 2c26974e050b0e9b1515f0a138bbc566da7e9dc4f70b7c6323d26baa48b8af0a
5
5
  SHA512:
6
- metadata.gz: 6ecf2c8514298d164cfa844c52d3e706848e89d46b79b91e989476cedbd834097ed472e05b4f1c8bfa519acc8d46a416397bf414159d6ef97c73c7c26a0bb843
7
- data.tar.gz: f7bead86283182163aa08103d32f869c03e148f3186970a74d32d47aaf9780561b04a1bbd68e3a1b6743660dbcdd6d0d383ec3bd07f10b590c70680a4453f222
6
+ metadata.gz: d8efa5e84229bf10034fd39cdc31ea719d7cdb9e607f13ed220fa55a843423124cefa5f44b8b4c90bd5017366eda29b225bf88f551d00e7d8817c0d7489a745d
7
+ data.tar.gz: 20847130b08299715942567e64221ef142991f69f4f131e894c5e9c214c3939ad6eaf158dddcf193a6344219e8bc9e0d43a3daa237bc08efc0fb576ffec4ff94
@@ -0,0 +1,9 @@
1
+ ---
2
+ version: 2
3
+ updates:
4
+ - package-ecosystem: "bundler"
5
+ directory: "/"
6
+ schedule:
7
+ interval: "daily"
8
+ assignees:
9
+ - "xlgmokha"
@@ -0,0 +1,41 @@
1
+ name: ci
2
+ on:
3
+ push:
4
+ branches: [main]
5
+ pull_request:
6
+ branches: [main]
7
+ jobs:
8
+ test:
9
+ runs-on: ubuntu-latest
10
+ strategy:
11
+ matrix:
12
+ ruby-version: ['2.5', '2.6', '2.7', '3.0']
13
+ steps:
14
+ - uses: actions/checkout@v2
15
+ - name: Set up Ruby
16
+ uses: ruby/setup-ruby@v1
17
+ with:
18
+ ruby-version: ${{ matrix.ruby-version }}
19
+ - run: sh bin/setup
20
+ - name: Running tests…
21
+ run: sh bin/test
22
+ style:
23
+ runs-on: ubuntu-latest
24
+ steps:
25
+ - uses: actions/checkout@v2
26
+ - uses: ruby/setup-ruby@v1
27
+ with:
28
+ ruby-version: '3.0'
29
+ bundler-cache: true
30
+ - name: Running style checks…
31
+ run: sh bin/style
32
+ audit:
33
+ runs-on: ubuntu-latest
34
+ steps:
35
+ - uses: actions/checkout@v2
36
+ - uses: ruby/setup-ruby@v1
37
+ with:
38
+ ruby-version: '3.0'
39
+ bundler-cache: true
40
+ - name: Running audit…
41
+ run: sh bin/audit
data/.gitignore CHANGED
@@ -9,5 +9,4 @@
9
9
 
10
10
  # rspec failure tracking
11
11
  .rspec_status
12
- Gemfile.lock
13
12
  .byebug_history
data/.rspec CHANGED
@@ -1,3 +1,3 @@
1
- --format documentation
1
+ --format progress
2
2
  --color
3
3
  --require spec_helper
data/.rubocop.yml CHANGED
@@ -9,24 +9,92 @@ AllCops:
9
9
  - 'vendor/**/*'
10
10
  TargetRubyVersion: 2.5
11
11
 
12
- Layout/IndentArray:
12
+ Layout/ArgumentAlignment:
13
+ EnforcedStyle: with_fixed_indentation
14
+
15
+ Layout/EndOfLine:
16
+ EnforcedStyle: lf
17
+
18
+ Layout/FirstArrayElementIndentation:
13
19
  EnforcedStyle: consistent
14
20
 
21
+ Layout/LineLength:
22
+ Exclude:
23
+ - 'spec/**/*.rb'
24
+ IgnoredPatterns:
25
+ - '^#*'
26
+
27
+ Layout/MultilineMethodCallIndentation:
28
+ Enabled: true
29
+ EnforcedStyle: indented
30
+
31
+ Layout/ParameterAlignment:
32
+ Enabled: true
33
+ EnforcedStyle: with_fixed_indentation
34
+ IndentationWidth: 2
35
+
36
+ Lint/AmbiguousBlockAssociation:
37
+ Exclude:
38
+ - 'spec/**/*.rb'
39
+
40
+ Lint/RaiseException:
41
+ Enabled: true
42
+
43
+ Lint/StructNewOverride:
44
+ Enabled: true
45
+
46
+ Metrics/AbcSize:
47
+ Exclude:
48
+ - 'lib/scim/kit/v2/service_provider_configuration.rb'
49
+
15
50
  Metrics/BlockLength:
16
51
  Exclude:
17
52
  - '*.gemspec'
53
+ - 'Rakefile'
18
54
  - 'spec/**/*.rb'
19
55
 
20
- Metrics/LineLength:
56
+ Metrics/ModuleLength:
21
57
  Exclude:
22
58
  - 'spec/**/*.rb'
23
- IgnoredPatterns:
24
- - '^#*'
25
59
 
26
60
  Naming/FileName:
27
61
  Exclude:
28
62
  - 'lib/scim-kit.rb'
29
63
 
64
+ Naming/RescuedExceptionsVariableName:
65
+ PreferredName: error
66
+
67
+ Style/Documentation:
68
+ Enabled: false
69
+
70
+ Style/HashEachMethods:
71
+ Enabled: true
72
+
73
+ Style/HashTransformKeys:
74
+ Enabled: true
75
+
76
+ Style/HashTransformValues:
77
+ Enabled: true
78
+
79
+ Style/IfUnlessModifier:
80
+ Exclude:
81
+ - 'lib/scim/kit/v2/attribute.rb'
82
+
83
+ Style/StringLiterals:
84
+ EnforcedStyle: 'single_quotes'
85
+
86
+ Style/TrailingCommaInArrayLiteral:
87
+ Enabled: false
88
+
89
+ Style/TrailingCommaInHashLiteral:
90
+ Enabled: false
91
+
92
+ RSpec/FilePath:
93
+ Enabled: false
94
+
95
+ RSpec/MultipleMemoizedHelpers:
96
+ Enabled: false
97
+
30
98
  RSpec/NamedSubject:
31
99
  Enabled: false
32
100
 
data/CHANGELOG.md CHANGED
@@ -1,4 +1,5 @@
1
- Version 0.3.2
1
+ Version 0.5.2
2
+
2
3
  # Changelog
3
4
  All notable changes to this project will be documented in this file.
4
5
 
@@ -6,7 +7,29 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
7
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
8
 
8
9
  ## [Unreleased]
9
- - NA
10
+
11
+ ## [0.5.2] - 2020-05-20
12
+ ### Fixed
13
+
14
+ - fix: Parse sub attributes from schema https://github.com/xlgmokha/scim-kit/pull/38
15
+
16
+ ## [0.5.1] - 2020-05-20
17
+ ### Fixed
18
+ - Specify `Accept: application/scim+json` header when discovering a SCIM API.
19
+ - Specify `Content-Type: application/scim+json` header when discovering a SCIM API.
20
+ - Specify `User-Agent: scim/kit <version>` header when discovering a SCIM API.
21
+ - Follow HTTP redirects when discovering a SCIM API.
22
+ - Retry 3 times with backoff + jitter when a connection to a SCIM discovery API fails.
23
+ - Specify a 1 second open timeout.
24
+ - Specify a 5 second read timeout.
25
+
26
+ ## [0.5.0] - 2020-01-21
27
+ ### Added
28
+ - Add API to traverse a SCIM filter AST
29
+
30
+ ## [0.4.0] - 2019-06-15
31
+ ### Added
32
+ - add implementation of SCIM 2.0 filter parser. [RFC-7644](https://tools.ietf.org/html/rfc7644#section-3.4.2.2)
10
33
 
11
34
  ## [0.3.2] - 2019-02-23
12
35
  ### Changed
@@ -35,7 +58,11 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
35
58
  - \_assign does not coerce values by default.
36
59
  - errors are merged together instead of overwritten during attribute validation.
37
60
 
38
- [Unreleased]: https://github.com/mokhan/scim-kit/compare/v0.3.2...HEAD
61
+ [Unreleased]: https://github.com/mokhan/scim-kit/compare/v0.5.2...HEAD
62
+ [0.5.2]: https://github.com/mokhan/scim-kit/compare/v0.5.1...v0.5.2
63
+ [0.5.1]: https://github.com/mokhan/scim-kit/compare/v0.5.0...v0.5.1
64
+ [0.5.0]: https://github.com/mokhan/scim-kit/compare/v0.4.0...v0.5.0
65
+ [0.4.0]: https://github.com/mokhan/scim-kit/compare/v0.3.2...v0.4.0
39
66
  [0.3.2]: https://github.com/mokhan/scim-kit/compare/v0.3.1...v0.3.2
40
67
  [0.3.1]: https://github.com/mokhan/scim-kit/compare/v0.3.0...v0.3.1
41
68
  [0.3.0]: https://github.com/mokhan/scim-kit/compare/v0.2.16...v0.3.0
data/Gemfile.lock ADDED
@@ -0,0 +1,131 @@
1
+ PATH
2
+ remote: .
3
+ specs:
4
+ scim-kit (0.5.2)
5
+ activemodel (~> 6.1)
6
+ net-hippie (~> 1.0)
7
+ parslet (~> 2.0)
8
+ tilt (~> 2.0)
9
+ tilt-jbuilder (~> 0.7)
10
+
11
+ GEM
12
+ remote: https://rubygems.org/
13
+ specs:
14
+ actionview (6.1.4.4)
15
+ activesupport (= 6.1.4.4)
16
+ builder (~> 3.1)
17
+ erubi (~> 1.4)
18
+ rails-dom-testing (~> 2.0)
19
+ rails-html-sanitizer (~> 1.1, >= 1.2.0)
20
+ activemodel (6.1.4.4)
21
+ activesupport (= 6.1.4.4)
22
+ activesupport (6.1.4.4)
23
+ concurrent-ruby (~> 1.0, >= 1.0.2)
24
+ i18n (>= 1.6, < 2)
25
+ minitest (>= 5.1)
26
+ tzinfo (~> 2.0)
27
+ zeitwerk (~> 2.3)
28
+ addressable (2.8.0)
29
+ public_suffix (>= 2.0.2, < 5.0)
30
+ ast (2.4.2)
31
+ builder (3.2.4)
32
+ bundler-audit (0.9.0.1)
33
+ bundler (>= 1.2.0, < 3)
34
+ thor (~> 1.0)
35
+ concurrent-ruby (1.1.9)
36
+ crack (0.4.5)
37
+ rexml
38
+ crass (1.0.6)
39
+ diff-lcs (1.5.0)
40
+ erubi (1.10.0)
41
+ ffaker (2.20.0)
42
+ hashdiff (1.0.1)
43
+ i18n (1.8.11)
44
+ concurrent-ruby (~> 1.0)
45
+ jbuilder (2.11.5)
46
+ actionview (>= 5.0.0)
47
+ activesupport (>= 5.0.0)
48
+ loofah (2.13.0)
49
+ crass (~> 1.0.2)
50
+ nokogiri (>= 1.5.9)
51
+ mini_portile2 (2.6.1)
52
+ minitest (5.15.0)
53
+ net-hippie (1.1.1)
54
+ nokogiri (1.12.5)
55
+ mini_portile2 (~> 2.6.1)
56
+ racc (~> 1.4)
57
+ nokogiri (1.12.5-x86_64-linux)
58
+ racc (~> 1.4)
59
+ parallel (1.21.0)
60
+ parser (3.1.0.0)
61
+ ast (~> 2.4.1)
62
+ parslet (2.0.0)
63
+ public_suffix (4.0.6)
64
+ racc (1.6.0)
65
+ rails-dom-testing (2.0.3)
66
+ activesupport (>= 4.2.0)
67
+ nokogiri (>= 1.6)
68
+ rails-html-sanitizer (1.4.2)
69
+ loofah (~> 2.3)
70
+ rainbow (3.1.1)
71
+ rake (13.0.6)
72
+ regexp_parser (2.2.0)
73
+ rexml (3.2.5)
74
+ rspec (3.10.0)
75
+ rspec-core (~> 3.10.0)
76
+ rspec-expectations (~> 3.10.0)
77
+ rspec-mocks (~> 3.10.0)
78
+ rspec-core (3.10.1)
79
+ rspec-support (~> 3.10.0)
80
+ rspec-expectations (3.10.2)
81
+ diff-lcs (>= 1.2.0, < 2.0)
82
+ rspec-support (~> 3.10.0)
83
+ rspec-mocks (3.10.2)
84
+ diff-lcs (>= 1.2.0, < 2.0)
85
+ rspec-support (~> 3.10.0)
86
+ rspec-support (3.10.3)
87
+ rubocop (0.93.1)
88
+ parallel (~> 1.10)
89
+ parser (>= 2.7.1.5)
90
+ rainbow (>= 2.2.2, < 4.0)
91
+ regexp_parser (>= 1.8)
92
+ rexml
93
+ rubocop-ast (>= 0.6.0)
94
+ ruby-progressbar (~> 1.7)
95
+ unicode-display_width (>= 1.4.0, < 2.0)
96
+ rubocop-ast (1.15.1)
97
+ parser (>= 3.0.1.1)
98
+ rubocop-rspec (1.44.1)
99
+ rubocop (~> 0.87)
100
+ rubocop-ast (>= 0.7.1)
101
+ ruby-progressbar (1.11.0)
102
+ thor (1.2.1)
103
+ tilt (2.0.10)
104
+ tilt-jbuilder (0.7.1)
105
+ jbuilder
106
+ tilt (>= 1.3.0, < 3)
107
+ tzinfo (2.0.4)
108
+ concurrent-ruby (~> 1.0)
109
+ unicode-display_width (1.8.0)
110
+ webmock (3.14.0)
111
+ addressable (>= 2.8.0)
112
+ crack (>= 0.3.2)
113
+ hashdiff (>= 0.4.0, < 2.0.0)
114
+ zeitwerk (2.5.3)
115
+
116
+ PLATFORMS
117
+ ruby
118
+ x86_64-linux
119
+
120
+ DEPENDENCIES
121
+ bundler-audit (~> 0.6)
122
+ ffaker (~> 2.7)
123
+ rake (~> 13.0)
124
+ rspec (~> 3.0)
125
+ rubocop (~> 0.52)
126
+ rubocop-rspec (~> 1.22)
127
+ scim-kit!
128
+ webmock (~> 3.5)
129
+
130
+ BUNDLED WITH
131
+ 2.3.6
data/README.md CHANGED
@@ -1,7 +1,6 @@
1
1
  # Scim::Kit
2
2
 
3
- [![Build Status](https://travis-ci.org/mokhan/scim-kit.svg?branch=master)](https://travis-ci.org/mokhan/scim-kit)
4
- [![Code Climate](https://codeclimate.com/github/mokhan/scim-kit.svg)](https://codeclimate.com/github/mokhan/scim-kit)
3
+ [![Build Status](https://github.com/xlgmokha/scim-kit/workflows/ci/badge.svg)](https://github.com/xlgmokha/scim-kit/actions)
5
4
  [![Gem Version](https://badge.fury.io/rb/scim-kit.svg)](https://rubygems.org/gems/scim-kit)
6
5
 
7
6
  Scim::Kit is a library with the purpose of simplifying the generation
@@ -87,7 +86,7 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
87
86
 
88
87
  ## Contributing
89
88
 
90
- Bug reports and pull requests are welcome on GitHub at https://github.com/mokhan/scim-kit.
89
+ Bug reports and pull requests are welcome on GitHub at https://github.com/xlgmokha/scim-kit.
91
90
 
92
91
  ## License
93
92
 
data/Rakefile CHANGED
@@ -9,5 +9,4 @@ RSpec::Core::RakeTask.new(:spec)
9
9
  RuboCop::RakeTask.new(:rubocop)
10
10
  Bundler::Audit::Task.new
11
11
 
12
- task lint: [:rubocop, 'bundle:audit']
13
12
  task default: :spec
data/bin/audit ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/sh
2
+
3
+ set -e
4
+
5
+ cd "$(dirname "$0")/.."
6
+
7
+ bundle exec rake bundle:audit
data/bin/setup CHANGED
@@ -1,6 +1,9 @@
1
- #!/usr/bin/env bash
2
- set -euo pipefail
3
- IFS=$'\n\t'
4
- set -vx
1
+ #!/bin/sh
5
2
 
6
- bundle check || bundle install --jobs "$(sysctl -n hw.ncpu || nproc)"
3
+ set -e
4
+
5
+ cd "$(dirname "$0")/.."
6
+
7
+ gem update --system
8
+ gem install bundler
9
+ bundle install
data/bin/shipit ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/sh
2
+
3
+ set -e
4
+
5
+ cd "$(dirname "$0")/.."
6
+
7
+ bundle exec rake release
data/bin/style ADDED
@@ -0,0 +1,7 @@
1
+ #!/bin/sh
2
+
3
+ set -e
4
+
5
+ cd "$(dirname "$0")/.."
6
+
7
+ bundle exec rubocop "$@"
data/bin/test CHANGED
@@ -1,21 +1,9 @@
1
- #!/bin/bash
2
-
3
- # script/test: Run test suite for application. Optionally pass in a path to an
4
- # individual test file to run a single test.
5
-
1
+ #!/bin/sh
6
2
 
7
3
  set -e
8
4
 
9
5
  cd "$(dirname "$0")/.."
10
6
 
11
- [ -z "$DEBUG" ] || set -x
12
-
13
- echo ["$(date "+%H:%M:%S")"] "==> Running setup…"
14
- bin/setup
7
+ export RUBYOPT='-W0'
15
8
 
16
- echo ["$(date "+%H:%M:%S")"] "==> Running tests…"
17
- if [[ $# -eq 0 ]]; then
18
- bundle exec rake spec
19
- else
20
- bundle exec rspec "$1"
21
- fi
9
+ bundle exec rspec "$@"
@@ -0,0 +1,48 @@
1
+ # frozen_string_literal: true
2
+
3
+ module Scim
4
+ module Kit
5
+ class Http
6
+ attr_reader :driver, :retries
7
+
8
+ def initialize(driver: Http.default_driver, retries: 3)
9
+ @driver = driver
10
+ @retries = retries
11
+ end
12
+
13
+ def get(uri)
14
+ driver.with_retry(retries: retries) do |client|
15
+ response = client.get(uri)
16
+ ok?(response) ? JSON.parse(response.body, symbolize_names: true) : {}
17
+ end
18
+ rescue *Net::Hippie::CONNECTION_ERRORS => error
19
+ Scim::Kit.logger.error(error)
20
+ {}
21
+ end
22
+
23
+ def self.default_driver
24
+ @default_driver ||= Net::Hippie::Client.new(
25
+ follow_redirects: 3,
26
+ headers: headers,
27
+ logger: Scim::Kit.logger,
28
+ open_timeout: 1,
29
+ read_timeout: 5
30
+ )
31
+ end
32
+
33
+ def self.headers
34
+ {
35
+ 'Accept' => 'application/scim+json',
36
+ 'Content-Type' => 'application/scim+json',
37
+ 'User-Agent' => "scim/kit #{Scim::Kit::VERSION}"
38
+ }
39
+ end
40
+
41
+ private
42
+
43
+ def ok?(response)
44
+ response.is_a?(Net::HTTPSuccess)
45
+ end
46
+ end
47
+ end
48
+ end
@@ -108,7 +108,7 @@ module Scim
108
108
  def valid_complex?(item)
109
109
  return false unless item.is_a?(Hash)
110
110
 
111
- item.keys.each do |key|
111
+ item.each_key do |key|
112
112
  return false unless type_for(key)&.valid?(item[key])
113
113
  end
114
114
  end
@@ -40,7 +40,8 @@ module Scim
40
40
  attr_accessor :resource_types
41
41
  attr_accessor :schemas
42
42
 
43
- def initialize
43
+ def initialize(http: Scim::Kit::Http.new)
44
+ @http = http
44
45
  @resource_types = {}
45
46
  @schemas = {}
46
47
 
@@ -48,9 +49,11 @@ module Scim
48
49
  end
49
50
 
50
51
  def load_from(base_url)
52
+ base_url = "#{base_url}/"
51
53
  uri = URI.join(base_url, 'ServiceProviderConfig')
52
- self.service_provider_configuration =
53
- ServiceProviderConfiguration.parse(client.get(uri).body)
54
+ json = http.get(uri)
55
+
56
+ self.service_provider_configuration = ServiceProviderConfiguration.parse(json, json)
54
57
 
55
58
  load_items(base_url, 'Schemas', Schema, schemas)
56
59
  load_items(base_url, 'ResourceTypes', ResourceType, resource_types)
@@ -58,25 +61,15 @@ module Scim
58
61
 
59
62
  private
60
63
 
64
+ attr_reader :http
65
+
61
66
  def load_items(base_url, path, type, items)
62
- response = client.get(URI.join(base_url, path), headers: headers)
63
- hashes = JSON.parse(response.body, symbolize_names: true)
67
+ hashes = http.get(URI.join(base_url, path))
64
68
  hashes.each do |hash|
65
69
  item = type.from(hash)
66
70
  items[item.id] = item
67
71
  end
68
72
  end
69
-
70
- def client
71
- @client ||= Net::Hippie::Client.new
72
- end
73
-
74
- def headers
75
- {
76
- 'Accept' => 'application/scim+json',
77
- 'Content-Type' => 'application/scim+json'
78
- }
79
- end
80
73
  end
81
74
  end
82
75
  end
@@ -0,0 +1,56 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'parslet'
4
+
5
+ module Scim
6
+ module Kit
7
+ module V2
8
+ class Filter
9
+ # @private
10
+ class Node
11
+ def initialize(hash)
12
+ @hash = hash
13
+ end
14
+
15
+ def operator
16
+ self[:operator].to_sym
17
+ end
18
+
19
+ def attribute
20
+ self[:attribute].to_s
21
+ end
22
+
23
+ def value
24
+ self[:value].to_s[1..-2]
25
+ end
26
+
27
+ def not?
28
+ @hash.key?(:not)
29
+ end
30
+
31
+ def accept(visitor)
32
+ visitor.visit(self)
33
+ end
34
+
35
+ def left
36
+ self.class.new(self[:left])
37
+ end
38
+
39
+ def right
40
+ self.class.new(self[:right])
41
+ end
42
+
43
+ def inspect
44
+ @hash.inspect
45
+ end
46
+
47
+ private
48
+
49
+ def [](key)
50
+ @hash[key]
51
+ end
52
+ end
53
+ end
54
+ end
55
+ end
56
+ end
@@ -0,0 +1,98 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'parslet'
4
+
5
+ module Scim
6
+ module Kit
7
+ module V2
8
+ class Filter
9
+ # @private
10
+ class Visitor
11
+ VISITORS = {
12
+ and: :visit_and,
13
+ co: :visit_contains,
14
+ eq: :visit_equals,
15
+ ew: :visit_ends_with,
16
+ ge: :visit_greater_than_equals,
17
+ gt: :visit_greater_than,
18
+ le: :visit_less_than_equals,
19
+ lt: :visit_less_than,
20
+ ne: :visit_not_equals,
21
+ or: :visit_or,
22
+ pr: :visit_presence,
23
+ sw: :visit_starts_with
24
+ }.freeze
25
+
26
+ def visit(node)
27
+ visitor_for(node).call(node)
28
+ end
29
+
30
+ protected
31
+
32
+ def visitor_for(node)
33
+ method(VISITORS.fetch(node.operator, :visit_unknown))
34
+ end
35
+
36
+ def visit_and(node)
37
+ visit(node.left).merge(visit(node.right))
38
+ raise error_for(:visit_and)
39
+ end
40
+
41
+ def visit_or(_node)
42
+ raise error_for(:visit_or)
43
+ end
44
+
45
+ def visit_equals(_node)
46
+ raise error_for(:visit_equals)
47
+ end
48
+
49
+ def visit_not_equals(_node)
50
+ raise error_for(:visit_not_equals)
51
+ end
52
+
53
+ def visit_contains(_node)
54
+ raise error_for(:visit_contains)
55
+ end
56
+
57
+ def visit_starts_with(_node)
58
+ raise error_for(:visit_starts_with)
59
+ end
60
+
61
+ def visit_ends_with(_node)
62
+ raise error_for(:visit_ends_with)
63
+ end
64
+
65
+ def visit_greater_than(_node)
66
+ raise error_for(:visit_greater_than)
67
+ end
68
+
69
+ def visit_greater_than_equals(_node)
70
+ raise error_for(:visit_greater_than_equals)
71
+ end
72
+
73
+ def visit_less_than(_node)
74
+ raise error_for(:visit_less_than)
75
+ end
76
+
77
+ def visit_less_than_equals(_node)
78
+ raise error_for(:visit_less_than_equals)
79
+ end
80
+
81
+ def visit_presence(_node)
82
+ raise error_for(:visit_presence)
83
+ end
84
+
85
+ def visit_unknown(_node)
86
+ raise error_for(:visit_unknown)
87
+ end
88
+
89
+ private
90
+
91
+ def error_for(method)
92
+ ::Scim::Kit::NotImplementedError.new("#{method} is not implemented")
93
+ end
94
+ end
95
+ end
96
+ end
97
+ end
98
+ end
@@ -0,0 +1,137 @@
1
+ # frozen_string_literal: true
2
+
3
+ require 'parslet'
4
+
5
+ module Scim
6
+ module Kit
7
+ module V2
8
+ # Parses SCIM filter queries
9
+ class Filter < Parslet::Parser
10
+ root :filter
11
+
12
+ # FILTER = attrExp / logExp / valuePath / assignVariable / *1"not" "(" FILTER ")"
13
+ rule(:filter) do
14
+ logical_expression | filter_atom
15
+ end
16
+
17
+ rule(:filter_atom) do
18
+ (not_op? >> lparen >> filter >> rparen) | attribute_expression | value_path
19
+ end
20
+
21
+ # valuePath = attrPath "[" valFilter "]" ; FILTER uses sub-attributes of a parent attrPath
22
+ rule(:value_path) do
23
+ attribute_path >> lbracket >> value_filter >> rbracket
24
+ end
25
+
26
+ # valFilter = attrExp / logExp / *1"not" "(" valFilter ")"
27
+ rule(:value_filter) do
28
+ attribute_expression | logical_expression | not_op? >> lparen >> value_filter >> rparen
29
+ end
30
+
31
+ # attrExp = (attrPath SP "pr") / (attrPath SP compareOp SP compValue)
32
+ rule(:attribute_expression) do
33
+ (attribute_path >> space >> presence.as(:operator)) | (attribute_path >> space >> comparison_operator.as(:operator) >> space >> comparison_value.as(:value))
34
+ end
35
+
36
+ # logExp = FILTER SP ("and" / "or") SP FILTER
37
+ rule(:logical_expression) do
38
+ filter_atom.as(:left) >> space >> (and_op | or_op).as(:operator) >> space >> filter.as(:right)
39
+ end
40
+
41
+ # compValue = false / null / true / number / string ; rules from JSON (RFC 7159)
42
+ rule(:comparison_value) do
43
+ falsey | null | truthy | number | string
44
+ end
45
+
46
+ # compareOp = "eq" / "ne" / "co" / "sw" / "ew" / "gt" / "lt" / "ge" / "le"
47
+ rule(:comparison_operator) do
48
+ equal | not_equal | contains | starts_with | ends_with |
49
+ greater_than | less_than | less_than_equals | greater_than_equals
50
+ end
51
+
52
+ # attrPath = [URI ":"] ATTRNAME *1subAttr ; SCIM attribute name ; URI is SCIM "schema" URI
53
+ rule(:attribute_path) do
54
+ ((uri >> colon).repeat(0, 1) >> attribute_name >> sub_attribute.repeat(0, 1)).as(:attribute)
55
+ end
56
+
57
+ # ATTRNAME = ALPHA *(nameChar)
58
+ rule(:attribute_name) do
59
+ alpha >> name_character.repeat(0, nil)
60
+ end
61
+
62
+ # nameChar = "-" / "_" / DIGIT / ALPHA
63
+ rule(:name_character) { hyphen | underscore | digit | alpha }
64
+
65
+ # subAttr = "." ATTRNAME ; a sub-attribute of a complex attribute
66
+ rule(:sub_attribute) { dot >> attribute_name }
67
+
68
+ # uri = 1*ALPHA 1*(":" 1*ALPHA)
69
+ rule(:uri) do
70
+ # alpha.repeat(1, nil) >> (colon >> (alpha.repeat(1, nil) | version)).repeat(1, nil)
71
+ str('urn:ietf:params:scim:schemas:') >> (
72
+ str('core:2.0:User') |
73
+ str('core:2.0:Group') | (
74
+ str('extension') >>
75
+ colon >>
76
+ alpha.repeat(1) >>
77
+ colon >>
78
+ version >>
79
+ colon >>
80
+ alpha.repeat(1)
81
+ )
82
+ )
83
+ end
84
+
85
+ rule(:presence) { str('pr') }
86
+ rule(:and_op) { str('and') }
87
+ rule(:or_op) { str('or') }
88
+ rule(:not_op?) { (str('not') >> space).repeat(0, 1).as(:not) }
89
+ rule(:falsey) { str('false') }
90
+ rule(:truthy) { str('true') }
91
+ rule(:null) { str('null') }
92
+ rule(:number) do
93
+ str('-').maybe >> (
94
+ str('0') | (match('[1-9]') >> digit.repeat)
95
+ ) >> (
96
+ str('.') >> digit.repeat(1)
97
+ ).maybe >> (
98
+ match('[eE]') >> (str('+') | str('-')).maybe >> digit.repeat(1)
99
+ ).maybe
100
+ end
101
+ rule(:equal) { str('eq') }
102
+ rule(:not_equal) { str('ne') }
103
+ rule(:contains) { str('co') }
104
+ rule(:starts_with) { str('sw') }
105
+ rule(:ends_with) { str('ew') }
106
+ rule(:greater_than) { str('gt') }
107
+ rule(:less_than) { str('lt') }
108
+ rule(:greater_than_equals) { str('ge') }
109
+ rule(:less_than_equals) { str('le') }
110
+ rule(:string) do
111
+ quote >> (str('\\') >> any | str('"').absent? >> any).repeat >> quote
112
+ end
113
+ rule(:lparen) { str('(') }
114
+ rule(:rparen) { str(')') }
115
+ rule(:lbracket) { str('[') }
116
+ rule(:rbracket) { str(']') }
117
+ rule(:digit) { match('\d') }
118
+ rule(:quote) { str('"') }
119
+ rule(:single_quote) { str("'") }
120
+ rule(:space) { match('\s') }
121
+ rule(:alpha) { match['a-zA-Z'] }
122
+ rule(:dot) { str('.') }
123
+ rule(:colon) { str(':') }
124
+ rule(:hyphen) { str('-') }
125
+ rule(:underscore) { str('_') }
126
+ rule(:version) { digit >> dot >> digit }
127
+ rule(:assign) { str('=') }
128
+
129
+ class << self
130
+ def parse(filter)
131
+ Node.new(new.parse(filter))
132
+ end
133
+ end
134
+ end
135
+ end
136
+ end
137
+ end
@@ -26,8 +26,8 @@ module Scim
26
26
  end
27
27
 
28
28
  class << self
29
- def build(*args)
30
- item = new(*args)
29
+ def build(**args)
30
+ item = new(**args)
31
31
  yield item
32
32
  item
33
33
  end
@@ -31,8 +31,8 @@ module Scim
31
31
  end
32
32
 
33
33
  class << self
34
- def build(*args)
35
- item = new(*args)
34
+ def build(**args)
35
+ item = new(**args)
36
36
  yield item
37
37
  item
38
38
  end
@@ -45,7 +45,7 @@ module Scim
45
45
  ) do |x|
46
46
  x.meta = Meta.from(hash[:meta])
47
47
  hash[:attributes].each do |y|
48
- x.attributes << AttributeType.from(y)
48
+ x.attributes << parse_attribute_type(y)
49
49
  end
50
50
  end
51
51
  end
@@ -53,6 +53,16 @@ module Scim
53
53
  def parse(json)
54
54
  from(JSON.parse(json, symbolize_names: true))
55
55
  end
56
+
57
+ private
58
+
59
+ def parse_attribute_type(hash)
60
+ attribute_type = AttributeType.from(hash)
61
+ hash[:subAttributes]&.each do |sub_attr_hash|
62
+ attribute_type.attributes << parse_attribute_type(sub_attr_hash)
63
+ end
64
+ attribute_type
65
+ end
56
66
  end
57
67
  end
58
68
  end
@@ -3,7 +3,7 @@
3
3
  json.key_format! camelize: :lower
4
4
  if _type.complex? && !_type.multi_valued
5
5
  json.set! _type.name do
6
- dynamic_attributes.values.each do |attribute|
6
+ dynamic_attributes.each_value do |attribute|
7
7
  render attribute, json: json
8
8
  end
9
9
  end
data/lib/scim/kit/v2.rb CHANGED
@@ -11,6 +11,9 @@ require 'scim/kit/v2/meta'
11
11
  require 'scim/kit/v2/mutability'
12
12
  require 'scim/kit/v2/resource'
13
13
  require 'scim/kit/v2/error'
14
+ require 'scim/kit/v2/filter'
15
+ require 'scim/kit/v2/filter/node'
16
+ require 'scim/kit/v2/filter/visitor'
14
17
  require 'scim/kit/v2/resource_type'
15
18
  require 'scim/kit/v2/returned'
16
19
  require 'scim/kit/v2/schema'
@@ -65,7 +68,7 @@ module Scim
65
68
  false
66
69
  end
67
70
  },
68
- reference: ->(x) { x =~ /\A#{URI.regexp(%w[http https])}\z/ },
71
+ reference: ->(x) { x =~ /\A#{URI::DEFAULT_PARSER.make_regexp(%w[http https])}\z/ },
69
72
  string: ->(x) { x.is_a?(String) }
70
73
  }.freeze
71
74
 
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Scim
4
4
  module Kit
5
- VERSION = '0.3.2'
5
+ VERSION = '0.5.2'
6
6
  end
7
7
  end
data/lib/scim/kit.rb CHANGED
@@ -10,6 +10,7 @@ require 'tilt'
10
10
  require 'tilt/jbuilder'
11
11
 
12
12
  require 'scim/kit/dynamic_attributes'
13
+ require 'scim/kit/http'
13
14
  require 'scim/kit/templatable'
14
15
  require 'scim/kit/template'
15
16
  require 'scim/kit/v2'
@@ -20,6 +21,7 @@ module Scim
20
21
  module Kit
21
22
  class Error < StandardError; end
22
23
  class UnknownAttributeError < Error; end
24
+ class NotImplementedError < Error; end
23
25
  TYPE_ERROR = ArgumentError.new(:type)
24
26
 
25
27
  def self.logger
data/scim-kit.gemspec CHANGED
@@ -10,8 +10,8 @@ Gem::Specification.new do |spec|
10
10
  spec.authors = ['mo']
11
11
  spec.email = ['mo@mokhan.ca']
12
12
 
13
- spec.summary = 'A SCIM library.'
14
- spec.description = 'A SCIM library.'
13
+ spec.summary = 'A simple toolkit for working with SCIM 2.0'
14
+ spec.description = 'A simple toolkit for working with SCIM 2.0'
15
15
  spec.homepage = 'https://www.github.com/mokhan/scim-kit'
16
16
  spec.license = 'MIT'
17
17
 
@@ -27,18 +27,17 @@ Gem::Specification.new do |spec|
27
27
  File.basename(file)
28
28
  end
29
29
  spec.require_paths = ['lib']
30
- spec.required_ruby_version = '>= 2.5.0'
30
+ spec.required_ruby_version = Gem::Requirement.new('>= 2.5.0')
31
31
  spec.metadata['yard.run'] = 'yri'
32
32
 
33
- spec.add_dependency 'activemodel', '>= 5.2.0'
34
- spec.add_dependency 'net-hippie', '~> 0.2'
33
+ spec.add_dependency 'activemodel', '~> 6.1'
34
+ spec.add_dependency 'net-hippie', '~> 1.0'
35
+ spec.add_dependency 'parslet', '~> 2.0'
35
36
  spec.add_dependency 'tilt', '~> 2.0'
36
37
  spec.add_dependency 'tilt-jbuilder', '~> 0.7'
37
- spec.add_development_dependency 'bundler', '~> 1.17'
38
38
  spec.add_development_dependency 'bundler-audit', '~> 0.6'
39
- spec.add_development_dependency 'byebug'
40
39
  spec.add_development_dependency 'ffaker', '~> 2.7'
41
- spec.add_development_dependency 'rake', '~> 10.0'
40
+ spec.add_development_dependency 'rake', '~> 13.0'
42
41
  spec.add_development_dependency 'rspec', '~> 3.0'
43
42
  spec.add_development_dependency 'rubocop', '~> 0.52'
44
43
  spec.add_development_dependency 'rubocop-rspec', '~> 1.22'
metadata CHANGED
@@ -1,45 +1,45 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: scim-kit
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.5.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - mo
8
- autorequire:
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-02-23 00:00:00.000000000 Z
11
+ date: 2022-01-26 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activemodel
15
15
  requirement: !ruby/object:Gem::Requirement
16
16
  requirements:
17
- - - ">="
17
+ - - "~>"
18
18
  - !ruby/object:Gem::Version
19
- version: 5.2.0
19
+ version: '6.1'
20
20
  type: :runtime
21
21
  prerelease: false
22
22
  version_requirements: !ruby/object:Gem::Requirement
23
23
  requirements:
24
- - - ">="
24
+ - - "~>"
25
25
  - !ruby/object:Gem::Version
26
- version: 5.2.0
26
+ version: '6.1'
27
27
  - !ruby/object:Gem::Dependency
28
28
  name: net-hippie
29
29
  requirement: !ruby/object:Gem::Requirement
30
30
  requirements:
31
31
  - - "~>"
32
32
  - !ruby/object:Gem::Version
33
- version: '0.2'
33
+ version: '1.0'
34
34
  type: :runtime
35
35
  prerelease: false
36
36
  version_requirements: !ruby/object:Gem::Requirement
37
37
  requirements:
38
38
  - - "~>"
39
39
  - !ruby/object:Gem::Version
40
- version: '0.2'
40
+ version: '1.0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: tilt
42
+ name: parslet
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - "~>"
@@ -53,33 +53,33 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '2.0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: tilt-jbuilder
56
+ name: tilt
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - "~>"
60
60
  - !ruby/object:Gem::Version
61
- version: '0.7'
61
+ version: '2.0'
62
62
  type: :runtime
63
63
  prerelease: false
64
64
  version_requirements: !ruby/object:Gem::Requirement
65
65
  requirements:
66
66
  - - "~>"
67
67
  - !ruby/object:Gem::Version
68
- version: '0.7'
68
+ version: '2.0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: bundler
70
+ name: tilt-jbuilder
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - "~>"
74
74
  - !ruby/object:Gem::Version
75
- version: '1.17'
76
- type: :development
75
+ version: '0.7'
76
+ type: :runtime
77
77
  prerelease: false
78
78
  version_requirements: !ruby/object:Gem::Requirement
79
79
  requirements:
80
80
  - - "~>"
81
81
  - !ruby/object:Gem::Version
82
- version: '1.17'
82
+ version: '0.7'
83
83
  - !ruby/object:Gem::Dependency
84
84
  name: bundler-audit
85
85
  requirement: !ruby/object:Gem::Requirement
@@ -94,20 +94,6 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0.6'
97
- - !ruby/object:Gem::Dependency
98
- name: byebug
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: '0'
104
- type: :development
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: '0'
111
97
  - !ruby/object:Gem::Dependency
112
98
  name: ffaker
113
99
  requirement: !ruby/object:Gem::Requirement
@@ -128,14 +114,14 @@ dependencies:
128
114
  requirements:
129
115
  - - "~>"
130
116
  - !ruby/object:Gem::Version
131
- version: '10.0'
117
+ version: '13.0'
132
118
  type: :development
133
119
  prerelease: false
134
120
  version_requirements: !ruby/object:Gem::Requirement
135
121
  requirements:
136
122
  - - "~>"
137
123
  - !ruby/object:Gem::Version
138
- version: '10.0'
124
+ version: '13.0'
139
125
  - !ruby/object:Gem::Dependency
140
126
  name: rspec
141
127
  requirement: !ruby/object:Gem::Requirement
@@ -192,7 +178,7 @@ dependencies:
192
178
  - - "~>"
193
179
  - !ruby/object:Gem::Version
194
180
  version: '3.5'
195
- description: A SCIM library.
181
+ description: A simple toolkit for working with SCIM 2.0
196
182
  email:
197
183
  - mo@mokhan.ca
198
184
  executables:
@@ -200,25 +186,28 @@ executables:
200
186
  extensions: []
201
187
  extra_rdoc_files: []
202
188
  files:
189
+ - ".github/dependabot.yml"
190
+ - ".github/workflows/ci.yml"
203
191
  - ".gitignore"
204
- - ".gitlab-ci.yml"
205
192
  - ".rspec"
206
193
  - ".rubocop.yml"
207
- - ".travis.yml"
208
194
  - CHANGELOG.md
209
195
  - Gemfile
196
+ - Gemfile.lock
210
197
  - LICENSE.txt
211
198
  - README.md
212
199
  - Rakefile
213
- - bin/cibuild
200
+ - bin/audit
214
201
  - bin/console
215
- - bin/lint
216
202
  - bin/setup
203
+ - bin/shipit
204
+ - bin/style
217
205
  - bin/test
218
206
  - exe/scim-kit
219
207
  - lib/scim-kit.rb
220
208
  - lib/scim/kit.rb
221
209
  - lib/scim/kit/dynamic_attributes.rb
210
+ - lib/scim/kit/http.rb
222
211
  - lib/scim/kit/templatable.rb
223
212
  - lib/scim/kit/template.rb
224
213
  - lib/scim/kit/v2.rb
@@ -229,6 +218,9 @@ files:
229
218
  - lib/scim/kit/v2/complex_attribute_validator.rb
230
219
  - lib/scim/kit/v2/configuration.rb
231
220
  - lib/scim/kit/v2/error.rb
221
+ - lib/scim/kit/v2/filter.rb
222
+ - lib/scim/kit/v2/filter/node.rb
223
+ - lib/scim/kit/v2/filter/visitor.rb
232
224
  - lib/scim/kit/v2/messages.rb
233
225
  - lib/scim/kit/v2/meta.rb
234
226
  - lib/scim/kit/v2/mutability.rb
@@ -258,7 +250,7 @@ licenses:
258
250
  - MIT
259
251
  metadata:
260
252
  yard.run: yri
261
- post_install_message:
253
+ post_install_message:
262
254
  rdoc_options: []
263
255
  require_paths:
264
256
  - lib
@@ -273,8 +265,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
273
265
  - !ruby/object:Gem::Version
274
266
  version: '0'
275
267
  requirements: []
276
- rubygems_version: 3.0.2
277
- signing_key:
268
+ rubygems_version: 3.3.6
269
+ signing_key:
278
270
  specification_version: 4
279
- summary: A SCIM library.
271
+ summary: A simple toolkit for working with SCIM 2.0
280
272
  test_files: []
data/.gitlab-ci.yml DELETED
@@ -1,11 +0,0 @@
1
- image: ruby:2.6
2
-
3
- before_script:
4
- - apt-get update && apt-get install -y locales
5
- - echo "en_US.UTF-8 UTF-8" > /etc/locale.gen
6
- - locale-gen
7
- - export LC_ALL=en_US.UTF-8
8
-
9
- rspec:
10
- script:
11
- - bin/cibuild
data/.travis.yml DELETED
@@ -1,8 +0,0 @@
1
- ---
2
- sudo: false
3
- language: ruby
4
- cache: bundler
5
- rvm:
6
- - 2.5.3
7
- - 2.6.1
8
- before_install: gem install bundler -v 1.17.1
data/bin/cibuild DELETED
@@ -1,22 +0,0 @@
1
- #!/bin/sh
2
-
3
- # script/cibuild: Setup environment for CI to run tests. This is primarily
4
- # designed to run on the continuous integration server.
5
-
6
- set -e
7
-
8
- cd "$(dirname "$0")/.."
9
-
10
- echo ["$(date "+%H:%M:%S")"] "==> Started at…"
11
-
12
- # GC customizations
13
- export RUBY_GC_MALLOC_LIMIT=79000000
14
- export RUBY_GC_HEAP_INIT_SLOTS=800000
15
- export RUBY_HEAP_FREE_MIN=100000
16
- export RUBY_HEAP_SLOTS_INCREMENT=400000
17
- export RUBY_HEAP_SLOTS_GROWTH_FACTOR=1
18
-
19
- ruby -v
20
- gem install bundler --conservative
21
- bin/test
22
- bin/lint
data/bin/lint DELETED
@@ -1,11 +0,0 @@
1
- #!/bin/sh
2
-
3
- set -e
4
-
5
- [ -z "$DEBUG" ] || set -x
6
-
7
- echo [$(date "+%H:%M:%S")] "==> Running setup…"
8
- bin/setup
9
-
10
- echo [$(date "+%H:%M:%S")] "==> Running linters…"
11
- bundle exec rake lint