[ 
https://issues.apache.org/jira/browse/KNOX-2983?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel
 ]

Attila Magyar updated KNOX-2983:
--------------------------------
    Description: 
h2. Motivation

Currently there is no way to add multiple identity assertion providers and 
combine the functionality of them. For example one might want to use the Concat 
identity assertion together with the Switch case provider. This is not possible 
due to a limitation of Knox which only allows having one identity assertion 
provider in the topology. Additionally, having a distinct provider for each 
functionality has its own limitations that prevents expressing complex mappings.

h2. Expression-Based principal mapping

The idea behind the Expression-Based principal mapping is that it leverages the 
language that was introduced by https://issues.apache.org/jira/browse/KNOX-2707.

{code}
<param>
  <name>expression.principal.mapping</name>
  <!-- expression that returns the new principal -->
  <value>...</value>
</param>
{code}

The value of *expression.principal.mapping* must be a valid expression that 
evaluates to a string, which will be the new, mapped principal.

For example, in the following example all authenticated users will be mapped to 
principal: 'bob'.

{code}
<param>
  <name>expression.principal.mapping</name>
  <value>'bob'</value>
</param>
{code}

By adding a conditional you can selectively apply the mapping to specific users.

{code}
<param>
  <name>expression.principal.mapping</name>
  <!-- Only map sam/tom to bob -->
  <value>
    (if (or (= username 'sam') 
            (= username 'tom')) 
        'bob')
  </value>
</param>
{code}

When the expression returns *null*, the original principal will be unchanged.

h2. Reference


h3. if

The *if* is an expression (rather than a statement), that has 2 or 3 
parameters. When you call it with 2 parameters it will behave like an 
*if-then*, when you call it with 3 parameters it will behave like an 
*if-then-else* expression. 

The first parameters is a conditional that must evaluate to either true or 
false. In case of true, the first branch is evaluated, otherwise the 2nd branch 
is evaluated. If the 2nd branch is omitted, and the conditional is false, then 
null is returned.

Returns 1: {code}(if true 1){code} 
Returns null: {code}(if false 1){code} 
Returns 2: {code}(if false 1 2){code} 
Returns 1: {code}(if true 1 2){code} 

h4. concat

The concat function takes variable number of arguments and concats them into 
one single string.

{code}
(concat 'The' 'sun' 'will' 'come' 'up' 'tomorrow.')
{code}

This can be used to concat/prepend a prefix or suffix to the usename.

{code}
(concat 'prefix_' username '_suffix')
{code}

h4. uppercase / lowercase

Convert a string to upper case and lower case letters.

{code}
(uppercase 'sam')
{code}

returns 'SAM'

{code}
(lowercase 'SAM')
{code}

returns 'sam'

The combination of uppercase/lowercase and concat can be used to capitalize a 
username

{code}
(concat
    (uppercase (substr username 0 1))
    (lowercase (substr username 1)))
{code}


h4. substr

The substr function works the same way as Java's subString. It takes one or two 
parameters, where the first is the begin index, and the second is the end index.

The substring begins with the character at the specified index and extends to 
the end of this string.

{code}
(substr 'unhappy' 2)
{code}

returns 'happy'

The end index is exclusive. The substring begins at the specified beginIndex 
and extends to the character at index endIndex - 1.

{code}
(substr 'hamburger' 4 8) 
{code}

returns 'urge'


h4. strlen

The strlen function returns the length of a string.

{code}
(strlen 'apple')
{code}

returns 5

For example, a combination of substr and strlen can be used to cut the first 
and last characters of a username

{code}
(substr username 1 (- (strlen username) 1))  
{code}
 

h4. contains

Check if a string includes a substring.

{code}
(contains 'dm' 'admin')
{code}

returns true since 'admin' contains 'dm'

h4. index-of

Find a substring in the given string and returns the (zero based) index.

{code}
(index-of 'ppl' 'apple')
{code}

returns 1

{code}
(index-of 'xx' 'apple')
{code}

If the given substring is not found, -1 is returned.

For example this will find the '@' substring, and the part coming after the '@' 
sign.

{code}
(if (contains '@' username)
    (substr username (+ (strlen '@') 
                        (index-of '@' username))))
{code}

ad...@hwx.site will be converted to hwx.site

Similarly, this will cut everything after the @ sign, including the @ sign.

{code}
(if (contains '@' username)
     (substr 'ad...@hwx.site' 0 (index-of '@' 'ad...@hwx.site')))
{code}

ad...@hwx.site will be converted to admin

 
h4. starts-with / ends-with

starts-with and ends-with can be used if a string begins or ends with a given 
substring.

{code}
(starts-with 'apple' 'app')
{code}

returns true

{code}
(ends-with 'apple' 'ple')
{code}

returns false

For example, remove a prefix from a username

{code}
(if (starts-with username 'prefix_')
    (substr username (strlen 'prefix_')))
{code}

prefix_admin will be converted to admin

h4. hash

The hash function creates a hash table for holding key value pairs. The number 
or arguments varies, but it must be an even number.

{code}
(hash)
{code}

returns an empty hash table

{code}
(hash 'key1' 'value1' 'key2' 'value2')
{code}

returns a hash table with key1=value1, and key2=value2.

h4. at

The at function returns the value for the given key from a hash table.

{code}
(at username 
    (hash
         'tom' 'Thomas'
         'sam' 'Samual'
         'admin' 'Administrator'))
{code}

This maps the user 'admin' to 'Administrator', 'tom' to 'Thomas' and 'sam' to 
'Samuel'

h4. regex-template

The regex-template template function works the same was as the [Regex type 
identity assertion 
provider|https://knox.apache.org/books/knox-2-0-0/user-guide.html#Regular+Expression+Identity+Assertion+Provider].

{code}
(regex-template  username '(.*)@(.*?)\..*' '{1}_{[2]}' (hash 'us' 'USA' 'ca' 
'CANADA') true)
{code}

The above expression turns `nob...@us.imaginary.tld` to `nobody_USA`.

The regular expression contains optional groups and the template can reference 
those groups. The last 2 parameters are optional. For more information  
[see|https://knox.apache.org/books/knox-2-0-0/user-guide.html#Regular+Expression+Identity+Assertion+Provider].

  was:
h2. Motivation

Currently there is no way to add multiple identity assertion providers and 
combine the functionality of them. For example one might want to use the Concat 
identity assertion together with the Switch case provider. This is not possible 
due to a limitation of Knox which only allows having one identity assertion 
provider in the topology. Additionally, having a distinct provider for each 
functionality has its own limitations that prevents expressing complex mappings.

h2. Expression-Based principal mapping

The idea behind the Expression-Based principal mapping is that it leverages the 
language that was introduced by https://issues.apache.org/jira/browse/KNOX-2707.

{code}
<param>
  <name>expression.principal.mapping</name>
  <!-- expression that returns the new principal -->
  <value>...</value>
</param>
{code}

The value of *expression.principal.mapping* must be a valid expression that 
evaluates to a string, which will be the new, mapped principal.

For example, in the following example all authenticated users will be mapped to 
principal: 'bob'.

{code}
<param>
  <name>expression.principal.mapping</name>
  <value>'bob'</value>
</param>
{code}

By adding a conditional you can selectively apply the mapping to specific users.

{code}
<param>
  <name>expression.principal.mapping</name>
  <!-- Only map sam/tom to bob -->
  <value>
    (if (or (= username 'sam') 
            (= username 'tom')) 
        'bob')
  </value>
</param>
{code}

When the expression returns *null*, the original principal will be unchanged.

h2. Reference


h3. if

The *if* is an expression (rather than a statement), that has 2 or 3 
parameters. When you call it with 2 parameters it will behave like an 
*if-then*, when you call it with 3 parameters it will behave like an 
*if-then-else* expression. 

The first parameters is a conditional that must evaluate to either true or 
false. In case of true, the first branch is evaluated, otherwise the 2nd branch 
is evaluated. If the 2nd branch is omitted, and the conditional is false, then 
null is returned.

Returns 1: {code}(if true 1){code} 
Returns null: {code}(if false 1){code} 
Returns 2: {code}(if false 1 2){code} 
Returns 1: {code}(if true 1 2){code} 

h4. concat

The concat function takes variable number of arguments and concats them into 
one single string.

{code}
(concat 'The' 'sun' 'will' 'come' 'up' 'tomorrow.')
{code}

This can be used to concat/prepend a prefix or suffix to the usename.

{code}
(concat 'prefix_' username '_suffix')
{code}

h4. uppercase / lowercase

Convert a string to upper case and lower case letters.

{code}
(uppercase 'sam')
{code}

returns 'SAM'

{code}
(lowercase 'SAM')
{code}

returns 'sam'

The combination of uppercase/lowercase and concat can be used to capitalize a 
username

{code}
(concat
    (uppercase (substr username 0 1))
    (lowercase (substr username 1)))
{code}


h4. substr

The substr function works the same way as Java's subString. It takes one or two 
parameters, where the first is the begin index, and the second is the end index.

The substring begins with the character at the specified index and extends to 
the end of this string.

{code}
(substr 'unhappy' 2)
{code}

returns 'happy'

The end index is exclusive. The substring begins at the specified beginIndex 
and extends to the character at index endIndex - 1.

{code}
(substr 'hamburger' 4 8) 
{code}

returns 'urge'


h4. strlen

The strlen function returns the length of a string.

{code}
(strlen 'apple')
{code}

returns 5

For example, a combination of substr and strlen can be used to cut the first 
and last characters of a username

{code}
(substr username 1 (- (strlen username) 1))  
{code}
 

h4. contains

Check if a string includes a substring.

{code}
(contains 'dm' 'admin')
{code}

returns true since 'admin' contains 'dm'

h4. index-of

Find a substring in the given string and returns the (zero based) index.

{code}
(index-of 'ppl' 'apple')
{code}

returns 1

{code}
(index-of 'xx' 'apple')
{code}

If the given substring is not found, -1 is returned.

For example this will find the '@' substring, and the part coming after the '@' 
sign.

{code}
(if (contains '@' username)
    (substr username (+ (strlen '@') 
                        (index-of '@' username))))
{code}

ad...@hwx.site will be converted to hwx.site

Similarly, this will cut everything after the @ sign, including the @ sign.

{code}
(if (contains '@' username)
     (substr 'ad...@hwx.site' 0 (index-of '@' 'ad...@hwx.site')))
{code}

ad...@hwx.site will be converted to admin

 
h4. starts-with / ends-with

starts-with and ends-with can be used if a string begins or ends with a given 
substring.

{code}
(starts-with 'apple' 'app')
{code}

returns true

{code}
(ends-with 'apple' 'ple')
{code}

returns false

For example, remove a prefix from a username

{code}
(if (starts-with username 'prefix_')
    (substr username (strlen 'prefix_')))
{code}

prefix_admin will be converted to admin

h4. hash

The hash function creates a hash table for holding key value pairs. The number 
or arguments varies, but it must be an even number.

{code}
(hash)
{code}

returns an empty hash table

{code}
(hash 'key1' 'value1' 'key2' 'value2')
{code}

returns a hash table with key1=value1, and key2=value2.

h4. at

The at function returns the value for the given key from a hash table.

{code}
(at username 
    (hash
         'tom' 'Thomas'
         'sam' 'Samual'
         'admin' 'Administrator'))
{code}

This maps the user 'admin' to 'Administrator', 'tom' to 'Thomas' and 'sam' to 
'Samuel'

h4. regex-template

The regex-template template function works the same was as the [Regex type 
identity assertion 
provider|https://knox.apache.org/books/knox-2-0-0/user-guide.html#Regular+Expression+Identity+Assertion+Provider].

{code}
    (regex-template  username '(.*)@(.*?)\..*' '{1}_{[2]}' (hash 'us' 'USA' 
'ca' 'CANADA') true)
{code}

The above expression turns `nob...@us.imaginary.tld` to `nobody_USA`.

The regular expression contains optional groups and the template can reference 
those groups. The last 2 parameters are optional. For more information  
[see|https://knox.apache.org/books/knox-2-0-0/user-guide.html#Regular+Expression+Identity+Assertion+Provider].


> Combine the functionality of different identity assertion providers
> -------------------------------------------------------------------
>
>                 Key: KNOX-2983
>                 URL: https://issues.apache.org/jira/browse/KNOX-2983
>             Project: Apache Knox
>          Issue Type: Improvement
>            Reporter: Attila Magyar
>            Assignee: Attila Magyar
>            Priority: Major
>          Time Spent: 0.5h
>  Remaining Estimate: 0h
>
> h2. Motivation
> Currently there is no way to add multiple identity assertion providers and 
> combine the functionality of them. For example one might want to use the 
> Concat identity assertion together with the Switch case provider. This is not 
> possible due to a limitation of Knox which only allows having one identity 
> assertion provider in the topology. Additionally, having a distinct provider 
> for each functionality has its own limitations that prevents expressing 
> complex mappings.
> h2. Expression-Based principal mapping
> The idea behind the Expression-Based principal mapping is that it leverages 
> the language that was introduced by 
> https://issues.apache.org/jira/browse/KNOX-2707.
> {code}
> <param>
>   <name>expression.principal.mapping</name>
>   <!-- expression that returns the new principal -->
>   <value>...</value>
> </param>
> {code}
> The value of *expression.principal.mapping* must be a valid expression that 
> evaluates to a string, which will be the new, mapped principal.
> For example, in the following example all authenticated users will be mapped 
> to principal: 'bob'.
> {code}
> <param>
>   <name>expression.principal.mapping</name>
>   <value>'bob'</value>
> </param>
> {code}
> By adding a conditional you can selectively apply the mapping to specific 
> users.
> {code}
> <param>
>   <name>expression.principal.mapping</name>
>   <!-- Only map sam/tom to bob -->
>   <value>
>     (if (or (= username 'sam') 
>             (= username 'tom')) 
>         'bob')
>   </value>
> </param>
> {code}
> When the expression returns *null*, the original principal will be unchanged.
> h2. Reference
> h3. if
> The *if* is an expression (rather than a statement), that has 2 or 3 
> parameters. When you call it with 2 parameters it will behave like an 
> *if-then*, when you call it with 3 parameters it will behave like an 
> *if-then-else* expression. 
> The first parameters is a conditional that must evaluate to either true or 
> false. In case of true, the first branch is evaluated, otherwise the 2nd 
> branch is evaluated. If the 2nd branch is omitted, and the conditional is 
> false, then null is returned.
> Returns 1: {code}(if true 1){code} 
> Returns null: {code}(if false 1){code} 
> Returns 2: {code}(if false 1 2){code} 
> Returns 1: {code}(if true 1 2){code} 
> h4. concat
> The concat function takes variable number of arguments and concats them into 
> one single string.
> {code}
> (concat 'The' 'sun' 'will' 'come' 'up' 'tomorrow.')
> {code}
> This can be used to concat/prepend a prefix or suffix to the usename.
> {code}
> (concat 'prefix_' username '_suffix')
> {code}
> h4. uppercase / lowercase
> Convert a string to upper case and lower case letters.
> {code}
> (uppercase 'sam')
> {code}
> returns 'SAM'
> {code}
> (lowercase 'SAM')
> {code}
> returns 'sam'
> The combination of uppercase/lowercase and concat can be used to capitalize a 
> username
> {code}
> (concat
>     (uppercase (substr username 0 1))
>     (lowercase (substr username 1)))
> {code}
> h4. substr
> The substr function works the same way as Java's subString. It takes one or 
> two parameters, where the first is the begin index, and the second is the end 
> index.
> The substring begins with the character at the specified index and extends to 
> the end of this string.
> {code}
> (substr 'unhappy' 2)
> {code}
> returns 'happy'
> The end index is exclusive. The substring begins at the specified beginIndex 
> and extends to the character at index endIndex - 1.
> {code}
> (substr 'hamburger' 4 8) 
> {code}
> returns 'urge'
> h4. strlen
> The strlen function returns the length of a string.
> {code}
> (strlen 'apple')
> {code}
> returns 5
> For example, a combination of substr and strlen can be used to cut the first 
> and last characters of a username
> {code}
> (substr username 1 (- (strlen username) 1))  
> {code}
>  
> h4. contains
> Check if a string includes a substring.
> {code}
> (contains 'dm' 'admin')
> {code}
> returns true since 'admin' contains 'dm'
> h4. index-of
> Find a substring in the given string and returns the (zero based) index.
> {code}
> (index-of 'ppl' 'apple')
> {code}
> returns 1
> {code}
> (index-of 'xx' 'apple')
> {code}
> If the given substring is not found, -1 is returned.
> For example this will find the '@' substring, and the part coming after the 
> '@' sign.
> {code}
> (if (contains '@' username)
>     (substr username (+ (strlen '@') 
>                         (index-of '@' username))))
> {code}
> ad...@hwx.site will be converted to hwx.site
> Similarly, this will cut everything after the @ sign, including the @ sign.
> {code}
> (if (contains '@' username)
>      (substr 'ad...@hwx.site' 0 (index-of '@' 'ad...@hwx.site')))
> {code}
> ad...@hwx.site will be converted to admin
>  
> h4. starts-with / ends-with
> starts-with and ends-with can be used if a string begins or ends with a given 
> substring.
> {code}
> (starts-with 'apple' 'app')
> {code}
> returns true
> {code}
> (ends-with 'apple' 'ple')
> {code}
> returns false
> For example, remove a prefix from a username
> {code}
> (if (starts-with username 'prefix_')
>     (substr username (strlen 'prefix_')))
> {code}
> prefix_admin will be converted to admin
> h4. hash
> The hash function creates a hash table for holding key value pairs. The 
> number or arguments varies, but it must be an even number.
> {code}
> (hash)
> {code}
> returns an empty hash table
> {code}
> (hash 'key1' 'value1' 'key2' 'value2')
> {code}
> returns a hash table with key1=value1, and key2=value2.
> h4. at
> The at function returns the value for the given key from a hash table.
> {code}
> (at username 
>     (hash
>          'tom' 'Thomas'
>          'sam' 'Samual'
>          'admin' 'Administrator'))
> {code}
> This maps the user 'admin' to 'Administrator', 'tom' to 'Thomas' and 'sam' to 
> 'Samuel'
> h4. regex-template
> The regex-template template function works the same was as the [Regex type 
> identity assertion 
> provider|https://knox.apache.org/books/knox-2-0-0/user-guide.html#Regular+Expression+Identity+Assertion+Provider].
> {code}
> (regex-template  username '(.*)@(.*?)\..*' '{1}_{[2]}' (hash 'us' 'USA' 'ca' 
> 'CANADA') true)
> {code}
> The above expression turns `nob...@us.imaginary.tld` to `nobody_USA`.
> The regular expression contains optional groups and the template can 
> reference those groups. The last 2 parameters are optional. For more 
> information  
> [see|https://knox.apache.org/books/knox-2-0-0/user-guide.html#Regular+Expression+Identity+Assertion+Provider].



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to