• Topic
  • Discussion
  • VOS.VirtuosoOdsControllers(Last) -- DAVWikiAdmin? , 2017-06-29 07:43:30 Edit WebDAV System Administrator 2017-06-29 07:43:30

    ODS Controllers

    The ODS provide an controllers (API) to manipulate the user accounts as well as instances, and instances specific data. The controllers can be accessed via REST using authentication based on OAuth, sessions or password hash. The details are presented bellow.

    Access point

    The API can be accessed via REST using http://host:port/ods/api/[method]. Parameters specific to each method are given as URL parameters if using GET, as www-url-encoded or multipart/form-data if using POST.

    The API can be accessed via UI page using http://host:port/ods/oauth_test.vsp.

    Authentication

    Most API calls which modify data, i.e., IUD operations, need authentication; thus the request should contain OAuth authentication, or session or password hash. The user account used to authenticate in either case MUST have relevant access to the ODS object. This is done by having owner or author membership to the given application.

    OAuth

    The user account for authentication must have OAuth tokens generated via ODS -> Settings -> OAuth keys. This UI provides a list of all applications to which the user has access (i.e., he is member or owner). If an instance needs to be accessed with OAuth, user simply selects the instance from the list and clicks 'generate keys'. The generated consumer key & token will be associated to the active ODS user account and selected application instance.

    Once a consumer token is available, the sequence below must be done in order to establish an authorized session:

    1. client uses request_token to get a token/secret pair for establishing session using consumer token
    2. client asks OAuth server to authorize the token from step 1
    3. using authorized token from step 1, client asks OAuth server for authentication token
    4. with authentication token from step 3, clients can access instance data associated with the consumer token from step 1

    To demonstrate the above, we supply a simple client written in VSP:


    <html>
    <?vsp
        declare consumer_key, consumer_secret, oauth_token, oauth_secret, signature, timest, nonce varchar;
        declare srv, res, signature_base, ret_url, url, tmp, sid varchar;
        declare meth, pars any;
        consumer_key := {?'key'};
        srv := sprintf ('http://localhost:%s/OAuth/', server_http_port ());
        sid := null;
        res := '';
    
        sid :=  {?'sid'};
        if (sid = '')
          sid := null;  
        else
          {
            -- if selected token is not same as one from the session we need to get new authentication token
            if (consumer_key <> OAUTH..get_consumer_key (sid))
         {
           OAUTH..session_terminate (sid);
                sid := null;
         }
          }
    
        meth := get_keyword ('meth', params, 'weblog.post.new');;
        pars := get_keyword ('pars', params, 'inst_id=15&title=testing&description=Some test post');;
    
        if ({?'rt'} is not null and sid is null) -- request new token for the session
          {
       url := srv||'request_token';
       url := OAUTH..sign_request ('GET', url, '', consumer_key, sid);
            res := http_get (url);
       sid := OAUTH..parse_response (sid, consumer_key, res);
       OAUTH..set_session_data (sid, params);
       ret_url := sprintf ('http://localhost:%s/oauth/oauth_client.vsp?ready=%U', server_http_port (), sid);
       -- call authorize
            url := sprintf ('%sauthorize?oauth_token=%U&oauth_callback=%U', srv, OAUTH..get_auth_token (sid), ret_url);
       http_status_set (301);
            http_header (sprintf ('Location: %s\r\n', url));
            return;
          }
        else if ({?'ready'} is not null) -- get access token
          {
       -- we go here when token above is authorized
            sid := {?'ready'};
       url := srv||'access_token';
       consumer_key := OAUTH..get_consumer_key (sid);
       url := OAUTH..sign_request ('GET', url, '', consumer_key, sid);
            res := http_get (url);
       sid := OAUTH..parse_response (sid, consumer_key, res);
    
          }
        if (sid is not null) -- access token is ready, and we can call API
          {
            -- here we are ready to call service
       if ({?'rt'} is null)
              {
                tmp := OAUTH..get_session_data (sid);
                pars := get_keyword ('pars', tmp, pars);
           meth := get_keyword ('meth', tmp, meth);
         }
       url := sprintf ('http://localhost:%s/ods/api/%s', server_http_port (), meth);
       tmp := split_and_decode (pars);
       params := '';
       for (declare i,l int, l:=length (tmp); i < l; i := i + 2)
          {
            params := params || sprintf ('%U=%U&', tmp[i], tmp[i+1]);
          }
       --params := sprintf ('inst_id=%d&description=%U&title=%U', 15, 'Some test post', 'testing');
       consumer_key := OAUTH..get_consumer_key (sid);
       url := OAUTH..sign_request ('GET', url, params, consumer_key, sid);
            res := http_get (url);
            --dbg_obj_print (res);
          }
    ?>
        <head><title>OAuth Client</title></head>
        <body>
       <h1>OAuth client for ODS Controllers</h1>
       <form method="POST" action="oauth_client.vsp">
       <input type="hidden" name="sid" value="<?V sid ?>"/>
       APPLICATION : <br/> <select name="key">
       <?vsp for select a_name, a_key from OAUTH..APP_REG do { ?>
                <option value="<?V a_key ?>" <?vsp if (consumer_key = a_key) http ('selected'); ?>><?V a_name ?></option>
       <?vsp } ?>
                  </select>
       <?vsp
       if (sid is not null) http (sprintf (' TOKEN: %s', OAUTH..get_auth_token (sid)));
       ?>
       <br/>
       ODS API: <br/><input type="text" name="meth" value="<?V meth ?>" size=50/> <br/>
       PARAMETERS: <br/> <textarea name="pars" rows="5" cols="50"><?V pars ?></textarea> <br/>
            <input type="submit" value="Execute" name="rt"/><br/>
       </form>
       RESULT:
       <hr/>
       <pre><?V res ?></pre>
        </body>
    </html>
    

    The following is a sample session recorded with the client above :


    GET /OAuth/request_token?oauth_consumer_key=50082d0fb861b0e6e67d5d986b8333607ed
    c5f36&oauth_nonce=b8f1089077cbce6e&oauth_signature_method=HMAC-SHA1&oauth_times
    tamp=1211212829&oauth_version=1.0&oauth_signature=V1zmk757LBHcmqVJ6obMhNX5hKA%3
    D HTTP/1.1
    Host: localhost:8890
    
    HTTP/1.1 200 Ok
    Content-Length: NNN
    <CR/LF>
    oauth_token=86da75079d3aee0fab57a36fcffbf900768e4de3&oauth_token_secret=M...
    

    GET /OAuth/authorize?oauth_token=86da75079d3aee0fab57a36fcffbf900768e4de3&oauth
    _callback=http%3A//localhost%3A8890/oauth/oauth_client.vsp%3Fready%3D00c874b2fa
    b2f6424008b5064fe83e88 HTTP/1.1
    Host: localhost:8890
    
    HTTP/1.1 301 Moved
    Location: /ods/oauth_authorize.vspx?....
    

    GET /OAuth/access_token?oauth_consumer_key=50082d0fb861b0e6e67d5d986b8333607edc
    5f36&oauth_nonce=242cc4875a0059f6&oauth_signature_method=HMAC-SHA1&oauth_timest
    amp=1211212831&oauth_token=86da75079d3aee0fab57a36fcffbf900768e4de3&oauth_versi
    on=1.0&oauth_signature=sqs/8nmNNnNJiZ/eBa688uNeg9o%3D HTTP/1.1
    Host: localhost:8890
    
    HTTP/1.1 200 Ok
    Content-Length: NNN
    <CR/LF>
    oauth_token=N..&oauth_token_secret=M...
    


    GET /ods/api/weblog.post.new?description=Some%20test%20post&inst_id=15&oauth_co
    nsumer_key=50082d0fb861b0e6e67d5d986b8333607edc5f36&oauth_nonce=2f4765d20664e69
    6&oauth_signature_method=HMAC-SHA1&oauth_timestamp=1211213321&oauth_token=db83a
    37d74faf53edc8ed56d418ded3a70fcc0bc&oauth_version=1.0&title=testing&oauth_signa
    ture=oocIyr6kgoEQkC3WVwzvl6w62W4%3D HTTP/1.1
    Host: localhost:8890
    
    
    HTTP/1.1 200 Ok
    Content-Length: NNN
    <CR/LF>
    <result><code>1&lt/code></result>
    

    Session based

    The request to the API in this type of authentication must have 'sid' & 'realm' via 'user.authenticate' method:

    To get session id:


    curl -i "http://localhost:8890/ods/api/user.authenticate?user_name=demo&passwor
    d_hash=fe1774cfea9f7b402796751a4616c04a6f010ecb"
    HTTP/1.1 200 OK
    Content-Type: text/plain; charset="UTF-8"
    Content-Length: 32
    
    bfb2b13e4218a99f65b956eb6ba657cb << SID
    
    

    Perform weblog.post.new API call:


    curl -i "http://localhost:8890/ods/api/weblog.post.new?title=test&description=S
    ome%20test%20post&inst_id=15&sid=bfb2b13e4218a99f65b956eb6ba657cb&realm=wa"
    HTTP/1.1 200 OK
    Connection: Keep-Alive
    Content-Type: text/xml; charset="UTF-8"
    Content-Length: 53
    <CR/LF>
    <result><code>1&lt/code></result>
    

    password hash

    This approach is similar to above, but instead of sid and realm we just pass as parameters to request the user_name & password_hash .

    Response format

    IUD operations

    The IUD methods return an XML response with code & message format follows:

    On success

    <result><code>NNN</code><message>human readable explanation if applicable</message></result>

    On failure

    <failed><code>NNN</code><failed>human readable explanation</message></failed>

    Search (get)

    The search methods returns results in RDF format according to FOAF, SIOC and SIOC types module ontology. See ODS RDF model.

    API methods

    All APIs are acting on behalf of the user who established authentication, i.e., the user which is authorized. The APIs where user is subject of removal or freeze as well as registration the user name is passed as parameter. Therefore user.register, user.delete would need user name as input parameter where user.update, instance.create will use the user from authentication information.

    Framework


    user.register (
        name varchar,
        password varchar,
        email varchar
        )
    user.authenticate (
        user_name varchar,
        password_hash varchar
        )
    user.update (user_info any)
    user.password_change (new_password varchar)
    user.delete (name varchar)
    user.enable (name varchar)
    user.disable (name varchar)
    user.get (name varchar)
    user.search (pattern varchar)
    user.invite (
        friends_email varchar,
        custom_message varchar default ''
        )
    user.invitation (
        invitation_id varchar,
        approve int
        )
    user.invitations.get ()
    user.relation_terminate (friend varchar)
    user.tagging_rules.add (
        rulelist_name varchar,
        rules any,
        is_public int default 1
        )
    user.tagging_rules.delete (rulelist_name varchar)
    user.tagging_rules.update (
        rulelist_name varchar,
        rules any
        )
    user.hyperlinking_rules.add (rules any)
    user.hyperlinking_rules.update (rules any)
    user.hyperlinking_rules.delete (rules any)
    user.annotation.add (
        claimIri varchar,
        claimRelation varchar,
        claimValue varchar
        )
    user.annotation.delete (
        claimIri varchar,
        claimRelation varchar,
        claimValue varchar
        )
    
    instance.create (
        type varchar,
        name varchar,
        description varchar,
        model int,
        public int
        )
    instance.update (
        inst_id int,
        name varchar,
        description varchar,
        model int,
        public int
        )
    instance.delete (inst_id int)
    instance.freeze (name varchar)
    instance.unfreeze (name varchar)
    instance.join (inst_id int)
    instance.disjoin (inst_id int)
    instance.join_approve (
        inst_id int,
        uname varchar
        )
    instance.notification.services ()
    instance.notification.set (
        inst_id int,
        services any
        )
    instance.notification.cancel (
        inst_id int,
        services any
        )
    instance.notification.log (inst_id int)
    instance.get (inst_id int)
    instance.get.id (name varchar)
    
    site.search (
        pattern varchar,
        options any
        )
    

    Briefcase

    Weblog

    Addressbook

    Bookmarks

    Polls

    Calendar

    Feed Manager

    Webmail

    Discussion

    Gallery

    Wiki

    Messenger

    References

    CategoryODS CategoryVirtuoso