You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 68 Next »

This is a wiki for the standard API for Groups, Subjects, Permissions

This is a RESTful API which is initially focused on HTTP/JSON.

Error rendering macro 'children'

null

Open issues

  • For lists of resources, e.g. /groups, the first 100 records will be returned if no paging is specified
  • If pagingEnabled is false, or the limit is too high, the server's max limit will be imposed.  Note, this max limit must be at least 1000.
  • Validation on sorting/paging: you cannot send an offset without a limit.  If you send pagingEnabled = false, then you shouldnt send in paging settings
  • Fields (extra/omit)
  • The folder path separator is a colon ":".  An actual colon in a name part is represented by slash-colon ("\:").
  • Groups and roles will be returned by group resources...  yes

Standards

  • top level: error (error code), error_description (free form), error_uri, status, warning, success
  • Fields can be marked as
    • Mandatory: implementors must implement this field
    • Default: when searching for the resource, these fields will be returned.  All fields are returned if the resource is requested.  If the user cant access one of the subresources, it is still returned (non admins see the admin URI)
  • Timestamps are ISO 8601, e.g.: 2012-10-04T03:10:14.123Z     note: no other 8601 representations are allowed.
  • Request/response wrapper.  Requests and response are wrapper in an object wrapper.  Responses wrap objects which are the real responses, e.g. they are a field in the response wrapper.  Responses have top level fields: meta, responseMeta:
    • meta  (generic metadata about the resource)
      • lastModified (default, mandatory): timestamp when the resource was modified
      • selfUri (default, mandatory): URI to the current resource, includes URL params which are expected by server (not authn params etc)
      • structureName: name of the struct which is returned.  This might be different if there is an error
    • responseMeta : metadata about this particular request/response that goes from server to client
      • responseTimestamp (mandatory): the timestamp that this was sent from the server (at the end of the processing)
      • millis (mandatory): number of milliseconds that the server took in processing this request
      • requestProcessed (mandatory): freeform text about the request that the server processed, when debugging to make sure the server is processing the right params
      • httpStatusCode: number of the HTTP status code
  • Fields returned are controlled with the "fields" parameter, the "extraFields" parameter, and the "omitFields" parameter.  The values of these params are not case-sensitive.
    • The values to these params can be qualified by object type, or if not qualified, refer to the requested resource object.  e.g. for a group resource, or a group search, "id" or "group.id" will refer to the group id field.
    • If you do not specify anything, then all fields will be returned for the resource, and the default fields will be returned for a search (default fields are fields which are not generally difficult to compute, and which are commonly used).
    • If you specify "fields", then only the fields specified will be returned for the objects specified.  E.g. fields=”id,name,meta.statusCode”
    • If you send in “extraFields” then in addition to the typical fields in the meta object, the totalCount field will also be supplied.   E.g. extraFields=meta.totalCount
    • If the values of these parameters conflict, there will be an error.  You should not refer to the same object in more than one of the params.  i.e. if you refer to group in "fields", then dont refer to it in "extraFields" or "omitFields".  If you request a field which does not exist, it will be a warning, not an error.
    • If fields has "all" for the object type, then send all fields for that object type.  If fields has "default" then send the default fields (e.g. the fields for a search result).  If fields has "allEverywhere" then for all object types, send all fields
    • If you ask for a field that doesnt exist you will get a warning
  • If unexpected fields are added to the request or reponse, it should not break the processing of the request or response.  This is important for versioning.  i.e. if you are not expecting the field group.foo, just ignore it (or log it), but do not throw an error.
  • Fields should be named with camelcase.  e.g. thisIsSomeField   names should be compatible with java variable names
  • Any URI fields should be named "uri" or end in "Uri", unless it is a standard (e.g. oauth).  e.g. membersUri, Note the URL is relative, though can be converted to absolute by considering the responseMeta.serviceRootUri field  (ADD MORE HERE)
  • The folder path separator is specified in the request and response.  If the path separator appears in a folder extension or object extension, then URL encode it.  Note, if this path is in a URL, then it will be URL encoded again.  Needless to say it is ideal if there arent path separators in extensions, or percents in extensions, though if they are, its ok, they can be escaped.  In requests, the path separator must be sent in a URL param: pathSeparator.  It must be one character.  In the response from the server, the separator is specified in the serviceMeta.pathSeparator.  This is sent back with all responses.  Note, if a client sends in a path separator to the server, the server does not have to use the same path separator in the response.  Note URL encoding should be lowercases for a-f.  Note, if a different separator is used, then the separator the server uses cannot be used in the path or an error will occur.   e.g. if a:b:c has the path separator of : and is changed to have underscore, it would look like this:  a_b_c    If this path with colon   a_:b:c   is converted to use underscore, then it would be   a%5f_b_c     And if this path with colons   a_:b%5f:c    is converted to use underscores  a%5f_b%255f_c   
  • Method is the HTTP method, unless the HTTP ?method=DELETE  is set, which has a value of a valid method, e.g. GET, PUT, POST, DELETE.  Case insensitive on value
  • If there are extra attributes, these in an extensions map in the object
  • POST can take a param: createIfNotExist=true for create if not exist
  • 401 means you arent authenticated, 403 means you are authenticated and you arent allowed
  • Act as can be specified with: actAs=netId:jsmith (or whatever URI for the subject).  The server will determine if that is allowed.
  • Resources must end in the format requested.  Possible formats are json and xml.  e.g. https://groups.institution.edu/groupsApp/authzStandardApi/v1/groups.json or https://groups.institution.edu/groupsApp/authzStandardApi/v1/groups.xml
  • Charset of the values is utf8
  • Escaping of group names should be URL encoding until we think of a better way
  • Names should be uri's.  e.g. group name could be name:a:b:c
  • HTTP params are single valued, if there are two values for one param it is an error
  • If an HTTP param is not expected, it should give a warning
  • Fields and http params should not start with underscore, they should be alphanumeric and uncontroversial so they can be processed by various languages/formats
  • Responses should be indented if this param is passed: ?indent=true is passed
  • Boolean HTTP params can be: true|false or t|f or yes|no or y|n case insensitive
  • For sorting and paging, see the section below
  • For inserts, a POST will be used
  • PUTs are by default as insert or an update.  Or you could use an eTag to specify the version to edit (IfMatch) to edit a specific version.  Or you could use the version in the object's representation
    • A PUT with a If-Match that does not match will return a 412 error (precondition failed)
  • Every PUT or POST needs to have a uri identifier in the URL.  e.g. name:test:myGroup

TODO

Discuss history of memberships

Versioning

The version of the API is an integer which is sent in the URL.  If the API is changed in a backwards compatible way (e.g. extra fields which do not change names or structure), then the version number doesn't change. However, there is also a dot version number which includes another integer for the revision number which is changed whenever the API is changed in a backwards compatible way.  The server dot version is sent in the response metadata. 

Query params: paging, sorting

Clients can specify records on search requests to be sorted and/or paged.  Note, if not specified, lists will be sorted based on a default sort field.

To put paging in the request, use these params:   resource?offset=5&sortField=name&ascending=false&limit=200

Param name

Example value(s)

Description

pagingEnabled

true, false

To request that there shouldnt be paging, use this url param, pagingEnabled=false.  pagingEnabled can be true or false.  It doesnt have to be sent for "true", you can send limit instead.  If you send pagingEnabled=false and limit set to something, that is an error.  If pagingEnabled= false, the server can override this with an arbitrary limit and sortField.  However, the server should support at least a count of 1000

limit

100

To set the size of the page, use limit.  This number must be greater than 0.  Note: if the count is too high the server can override the request and lower the count.  However, the server must support at least a limit of 1000

offset

0

offset is zero indexes as to which page is returned.  If it is not set, and there is no offsetFieldValue, it defaults to 0.  Must be an integer greater than or equal to 0.

offsetFieldValue

"jsmith"

this is mutually exclusive with offset.  If this is set, then the results will return everything after this value in the result list, until the resultlist is blank, then there is nothing else.  This is more reliable than offset which can miss more records due to data churn while the paging is taking place.  Note, it is imperative that the sort field be unique and non-null.  If you want all records, you could sort on "id" and be safe.  After receiving the first batch, then send the last value of the sorted field in this param to get the next batch

sortField

"displayName"

sortField is the resource specific sort field to sort on.  Note, there could be more than one value that relates to the same field to make things easier to use.  This should not be case-sensitive.  If it is blank, and there is sorting, then a default sortField will be selected.  You can set the sort field without using paging if you like.

ascending

true|false

ascending is a boolean true or false.  This defaults to true.

extraFields=meta.totalCount

 

if the server should do a total count of records with the request and return in meta.totalCount.  If it is not specified, then it will not be returned.  This might affect the performance of the request if requested

When a search is returned, if it is paged or sorted or not cached, fields in the meta object will be returned with the total count (is extraFields=meta.totalCount is set) and a summary of what was done inside the meta object

{
  "meta":{
    "offset": 4,
    "limit": 100,
    "sortField":"displayName",
    "ascending":true,
    "totalCount":468
    "lastModified":"2012-11-04T09:57:03.541Z", ... etc
  },
  "responseMeta":{...  etc
}
  • For lists of resources, e.g. /groups, the first 100 records will be returned if no paging is specified
  • If pagingEnabled is false, or the limit is too high, the server's max limit will be imposed.  Note, this max limit must be at least 1000.

Validations (will throw error):

  • You cannot send an offset without a limit
  • If you send pagingEnabled = false, then you shouldnt send in paging settings

Default resources

https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi?indent=true

Note: This always returns JSON... with pointers to the various formats

LastModified will be mandated from the API, when the API changes, or when the server has restarted

{
  "asasDefaultResource":{
    "jsonDefaultUri":"https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi.json",
    "xmlDefaultUri":"https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi.xml"
  },
  "meta":{
    "lastModified":"2012-11-04T09:57:03.541Z",
    "selfUri":"https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi?indent=true",
    "statusCode":"SUCCESS",
    "structureName":"defaultResourceContainer",
    "success":true
  },
  "responseMeta":{
    "httpStatusCode":200,
    "millis":274
  },
  "serviceMeta":{
    "serverVersion":"1.0",
    "serviceRootUri":"https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi"
  }
}

The default resource has urls to the various default resources, GET only.  e.g.

https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi.json?indent=true

{
  "asasDefaultVersionResource":{
    "serverType":"Grouper WS 2.0.1",
    "v1Uri":"https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi/v1.json"
  },
  "meta":{
    "lastModified":"2012-11-04T09:57:03.541Z",
    "selfUri":"https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi.json?indent=true",
    "statusCode":"SUCCESS",
    "structureName":"defaultVersionResourceContainer",
    "success":true
  },
  "responseMeta":{
    "httpStatusCode":200,
    "millis":15
  },
  "serviceMeta":{
    "serverVersion":"1.0",
    "serviceRootUri":"https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi"
  }
}

GET https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi/v1.json?indent=true

{
  "asasVersionResource":{
    "entitiesUri":"https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi/v1/entities.json",
    "foldersUri":"https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi/v1/folders.json",
    "groupsUri":"https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi/v1/groups.json",
    "permissionsUri":"https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi/v1/permissions.json"
  },
  "meta":{
    "lastModified":"2012-11-04T09:57:03.541Z",
    "selfUri":"https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi/v1.json?indent=true",
    "statusCode":"SUCCESS",
    "structureName":"versionResourceContainer",
    "success":true
  },
  "responseMeta":{
    "httpStatusCode":200,
    "millis":11
  },
  "serviceMeta":{
    "serverVersion":"1.0",
    "serviceRootUri":"https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi"
  }
}

https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi/v1.xml?indent=true

<?xml version="1.0" encoding="UTF-8"?>
<edu.internet2.middleware.authzStandardApiServer.corebeans.AsasVersionResourceContainer>
  <asasVersionResource>
    <entitiesUri>https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi/v1/entities.xml</entitiesUri>
    <foldersUri>https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi/v1/folders.xml</foldersUri>
    <groupsUri>https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi/v1/groups.xml</groupsUri>
    <permissionsUri>https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi/v1/permissions.xml</permissionsUri>
  </asasVersionResource>
  <meta>
    <lastModified>2012-11-04T09:57:03.541Z</lastModified>
    <selfUri>https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi/v1.xml?indent=true</selfUri>
    <statusCode>SUCCESS</statusCode>
    <structureName>versionResourceContainer</structureName>
    <success>true</success>
  </meta>
  <responseMeta>
    <httpStatusCode>200</httpStatusCode>
    <millis>614</millis>
  </responseMeta>
  <serviceMeta>
    <serverVersion>1.0</serverVersion>
    <serviceRootUri>https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi</serviceRootUri>
  </serviceMeta>
</edu.internet2.middleware.authzStandardApiServer.corebeans.AsasVersionResourceContainer>

sdf

Groups resource

The groups resource: https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi/v1/groups.json?indent=true&nbsp; (or .xml)

Allows query params (paging, sorting) described above

This is GET only. It will return a list of groups, and it might page the results based on server settings (see paging above).  Sample response

{
  "groups":[
    {
      "description":"java developers",
      "displayName":"apetro-unicon:friends:java-devs",
      "id":"6260127554e449b69000508960b21744",
      "name":"apetro-unicon:unicon-apetro-friends:java-devs",
      "status":"enabled",
      "uri":"https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi/v1/groups/name%3Aapetro-unicon%3Aunicon-apetro-friends%3Ajava-devs.json?pathSeparator=%3A"
    },
    {
      "description":"",
      "displayName":"aStem:A Group",
      "id":"d3490e96e0cf44539864b98e1c9b53d9",
      "name":"aStem:aGroup",
      "status":"enabled",
      "uri":"https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi/v1/groups/name%3AaStem%3AaGroup.json?pathSeparator=%3A"
    }
  ]
  ,
  "meta":{
    "ascending":true,
    "lastModified":"2012-11-17T23:39:07.574Z",
    "limit":100,
    "offset":0,
    "selfUri":"https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi/v1/groups.json?indent=true",
    "sortField":"name",
    "statusCode":"SUCCESS",
    "structureName":"groupSearchContainer",
    "success":true
  },
  "responseMeta":{
    "httpStatusCode":200,
    "millis":265
  },
  "serviceMeta":{
    "pathSeparator":":",
    "serverVersion":"1.0",
    "serviceRootUri":"https://grouperdemo.internet2.edu/grouper-ws_v2_0_0/authzStandardApi"
  }
}

Filter the results:https://groups.institution.edu/groupsApp/authzStandardApi/v1/groups?groups.status=active
or: groups.name=a:b:*
or: groups.parentFolder=a:b&groups.parentFolderScope=ONE_LEVEL (or ALL_IN_SUBTREE)

Individual group resource

The group resource: https://groups.institution.edu/groupsApp/authzStandardApi/v1/groups/a:b

This resource is available for GET, PUT, POST, DELETE

GET Sample response:

{
  "group":
    {
      "id": "123abc",
      "name": "a:b:c",
      "displayName": "A:B:C",
      "description": "This is the description",
      "status": "active"
    },
  "responseMeta": {
    "success": true,
    "serviceRootUrl": "https://groups.institution.edu/groupsApp/authzStandardApi",
    "serverVersion": "1.4",
    "resultCode": "SUCCESS"
  }
}

success is true if the URL is correct up until the group name part.

PUT (create) Sample request https://groups.institution.edu/groupsApp/authzStandardApi/v1/groups/a:b  :

{
  "group":
    {
      "name": "a:b:c",
      "displayName": "A:B:C",
      "description": "This is the description",
      "status": "active"
    }
}

Response 201 for created, 409 for already exists (resultCode: ERROR_ALREADY_EXISTS):

{
  "responseMeta": {
    "success": true,
    "serviceRootUrl": "https://groups.institution.edu/groupsApp/authzStandardApi",
    "serverVersion": "1.4",
    "resultCode": "SUCCESS_CREATED"
  }
}

POST (update)

Folders collection

PUT /folders/foo

PUT /folders/foo:bar

Special name for top level folder ":"

Folder separator is :

Folder save (PUT/POST)

Request:

PUT /grouperWs/authzStandardApi/v1/folders/name:test.xml HTTP/1.1
Connection: close
Authorization: Basic R3Jvabc123
User-Agent: Jakarta Commons-HttpClient/3.1
Host: localhost:8090
Content-Length: 0

Response:

HTTP/1.1 200 OK
Server: Apache-Coyote/1.1
Pragma: No-cache
Cache-Control: no-cache
Expires: Wed, 31 Dec 1969 19:00:00 EST
Content-Type: text/xml;charset=UTF-8
Content-Length: 955
Date: Mon, 14 Jan 2013 09:17:02 GMT
Connection: close


<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<folderSaveResponse>
  <folder>
    <creatorsUri>/v1/folders/name%3Atest/creators.xml</creatorsUri>
    <description/>
    <displayName>test</displayName>
    <folderAdminsUri>/v1/folders/name%3Atest/admins.xml</folderAdminsUri>
    <id>83580b7023524bb3bac27a2cb6b1e764</id>
    <name>test</name>
    <parentFolderUri>/v1/folders/name%3A%3A.xml</parentFolderUri>
    <status>active</status>
    <uri>/v1/folders/name%3Atest.xml</uri>
  </folder>
  <meta>
    <lastModified>2013-01-14T04:16:48.805Z</lastModified>
    <selfUri>http://localhost:8090/grouperWs/authzStandardApi/v1/folders/name:test.xml</selfUri>
    <statusCode>SUCCESS</statusCode>
    <structureName>folderSaveResponse</structureName>
    <success>true</success>
  </meta>
  <responseMeta>
    <httpStatusCode>200</httpStatusCode>
    <millis>26</millis>
  </responseMeta>
  <serviceMeta>
    <serverVersion>1.0</serverVersion>
    <serviceRootUri>http://localhost:8090/grouperWs/authzStandardApi</serviceRootUri>
  </serviceMeta>
</folderSaveResponse>

Individual folder resource

id

name

displayName

description

parentUri

folderAdminsUri

folderCreatorsUri

sdf

  • No labels