Subject: [scim] Conditional Patch

From: Phil Hunt <[email-masked]>
Date: Wed, 29 Aug 2012 14:29:31 -0700

Folks,

I know there has been a lot of discussion about modifying the patch command to make it easier to read.  A new requirement came up that seems more generally useful, especially in cross domain scenarios.

Issue, sometimes when you modify an attribute you want to confirm the state of an attribute (or set) before completing the operation.  This could be done with a search, but the preference would be to do it in a single operation.

Let me take the (somewhat horrible) example of modifying passwords (it could be anything else).  Before modifying the password, you want to confirm the old password is a match.

This could be expressed in a couple of ways:

Option 1 - replace old value

PATCH /Users/phunt321

{ "schemas": "......",
  
 "password": {[
    {"value" : "oldpassword",
    "operation" : "delete"}
   {"value":"newpassword"}
   ]}
}

Issue --> if password is single valued, then treating as multi-valued may make no sense unless we allow it.  It can only really test if a pre-existing value is present -- not that broadly useful.

Option 2 - a more generalized conditional modify

PATCH /Users/phunt321
{
 "schemas":" .... ",

 "password": {
    "value":"newpassword",
    "condition":"filter=password eq \"oldvalue\" and status eq \"active\"",
    "critical" : "true"
}

In the above example, the condition is a filter about the resource that must match (in this case testing the old value matches and that status is active). Critical indicates whether the entire PATCH fails if the filter does not match.

It seems that in the cross-domain cases there may be many times when we can't assume full state of a resource is known. It may be reasonable in many cases (other than password setting), that the client may want to do a conditional patch in a single operation (as opposed to a query followed by a modify).
   
Phil

@independentid
www.independentid.com
[email-masked]

---

From: Samuel Erdtman <[email-masked]>
Date: Thu, 30 Aug 2012 08:13:52 +0200

Interesting, another way to do the same thing but without cluttering
the resource representation would be to put the filter part in the
query instead of within the resource-object, this would in addition to
allow conditional updates of one user allow for updates of all users
matching a certain criteria.

To update the title of all Tour Guides:
PATCH /Users?filter=title eq "Tour Guide",
{
  "title": "Tour Master",
}

To update the title of one specific Tour Guide if he is a tour guide
PATCH /Users?filter=id eq "saerd" and title eq "Tour Guide",
{
  "title": "Tour Guide Manager",
}

To update one users password if that user is active
PATCH /Users?filter=id eq "saerd" and active eq "true",
{
  "password": "newvalue",
}

Thoughts?

Cheers
//Samuel

On Wed, Aug 29, 2012 at 11:29 PM, Phil Hunt <[email-masked]> wrote:
> _______________________________________________
> scim mailing list
> [email-masked]
> https://www.ietf.org/mailman/listinfo/scim

---

From: Phil Hunt <[email-masked]>
Date: Wed, 29 Aug 2012 23:37:53 -0700

Yes agreed. However as with GET there is need to keep some filter terms out of the URL.

Phil

---

From: Phil Hunt <[email-masked]>
Date: Wed, 29 Aug 2012 23:42:04 -0700

Also on the URL, the condition would apply to the entire operation rather than just one particular attribute.  

Both could be useful though. 

Phil

---

From: Phil Hunt <[email-masked]>
Date: Thu, 30 Aug 2012 14:52:29 -0700

Murray and Leif suggested taking a look at:
draft-ietf-appsawg-json-patch - http://tools.ietf.org/html/draft-ietf-appsawg-json-patch-02

The spec seems relatively simple and might improve the overall PATCH operation. 

My only concern is that the spec is based on another spec JSON Pointer (http://tools.ietf.org/html/draft-ietf-appsawg-json-pointer-01)

JSON Pointer is good for straight forward JSON structures, however it ends up being a bit like XML Paths. I wonder if a version of this where we use just attributes wouldn't work even better.

Phil

@independentid
www.independentid.com
[email-masked]

---

From: Kelly Grizzle <[email-masked]>
Date: Fri, 31 Aug 2012 13:51:22 +0000

Yes - I have looked at this also and think there is some good stuff here.  It is similar to what Ganesh proposed for PATCH but limits the verbs and (as you pointed out) relies on JSON Pointer rather than unique identifiers.

I agree that JSON Pointer may not be the way to go.  My primary concern is the use of indexes to address list elements (this is always where things get tricky, isn't it?) since list indexes are not very stable.

In your password example this could look more like:

 PATCH /Users/phunt321
 {
   "schemas":" .... ",
 
   "commands": [
     {
       "operation": "replace",
       "attribute": "password",
       "value": "newpassword",
       "previousValue": "oldvalue"
     }
   ]
 }

I think something like this would be cleaner than the current use of meta.attributes and operation="delete", and would lend itself better to extensions like you are proposing.

--Kelly

-----Original Message-----
From: [email-masked] [mailto:[email-masked]] On Behalf Of Phil Hunt
Sent: Thursday, August 30, 2012 4:52 PM
To: scim WG
Subject: Re: [scim] Conditional Patch

Phil

@independentid
www.independentid.com
[email-masked]

On 2012-08-29, at 11:42 PM, Phil Hunt wrote:

>> query instead of within the resource-object, this would in addition 
>> to allow conditional updates of one user allow for updates of all 
>> users matching a certain criteria.
>> 
>> PATCH /Users?filter=title eq "Tour Guide", {
>> "title": "Tour Master",
>> }
>> 
>> PATCH /Users?filter=id eq "saerd" and title eq "Tour Guide", {
>> To update one users password if that user is active PATCH 
>> /Users?filter=id eq "saerd" and active eq "true", {
>> "password": "newvalue",
>> }
>> 
>> Thoughts?
>> 
>> Cheers
>> //Samuel
>> 
>> 
>>

---

From: Phil Hunt <[email-masked]>
Date: Fri, 31 Aug 2012 08:41:24 -0700

Agreed. Reliance on index position increases the amount of binding and thus the chance of breakage as state between cross-domain entities is likely to be more inconsistent over time. 

The "replace" operation is useful in times when the client wants to be sure about what value is being replaced.

Phil

@independentid
www.independentid.com
[email-masked]