The University of Arizona
PictureGram API

PictureGram API #

This Sample API specification describes how a client will interact with a Sample API, but does not describe how the API functionality is implimented.

Reference API Endpoint #

The endpoint base URL is:

https://csc346picturegram.test.apps.uits.arizona.edu/

This is used as the base URL for all API methods described below.

GET /healthcheck #

Returns a basic healthcheck for the API. Useful for testing out if you are able to connect to the API, and if the API can access all of the information it needs. If query string arguments are passed as part of the URL, they will be echoed as part of the request section.

Request

GET /healthcheck?fruit=apple HTTP/1.1
Host: csc346picturegram.test.apps.uits.arizona.edu
curl --location --request GET \
    'https://csc346picturegram.test.apps.uits.arizona.edu/healthcheck?fruit=apple'

Response 200

{
    "status": "OK",
    "request": {
        "method": "GET",
        "path": "/Prod/healthcheck",
        "protocol": "HTTP/1.1",
        "sourceIp": "67.1.115.222",
        "userAgent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:122.0) Gecko/20100101 Firefox/122.0",
        "headers": {
            "accept": "text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,*/*;q=0.8",
            "accept-encoding": "gzip, deflate, br",
            "accept-language": "en-US,en;q=0.5",
            "content-length": "0",
            "host": "csc346picturegram.test.apps.uits.arizona.edu",
            "sec-fetch-dest": "document",
            "sec-fetch-mode": "navigate",
            "sec-fetch-site": "none",
            "sec-fetch-user": "?1",
            "upgrade-insecure-requests": "1",
            "user-agent": "Mozilla/5.0 (Macintosh; Intel Mac OS X 10.15; rv:122.0) Gecko/20100101 Firefox/122.0",
            "x-amzn-trace-id": "Root=1-65c42df0-5f4ee70e0bf634c72db3126a",
            "x-forwarded-for": "67.1.115.222",
            "x-forwarded-port": "443",
            "x-forwarded-proto": "https"
        },
        "queryString": "fruit=apple"
    }
}

GET /authenticate/<ticket>?service=<serviceURL> #

Attempts to validate a CAS ticket and returns an API session key. This requires a query string argument containing the serviceURL to authenticate as inaddition to the CAS ticket to validate. This serviceURL must match the one used when calling the GET /login action.

Request

GET /authenticate/ST-1662939?service=<serviceURL> HTTP/1.1
Host: csc346picturegram.test.apps.uits.arizona.edu
 
curl --location --request GET \
    'https://csc346picturegram.test.apps.uits.arizona.edu/authenticate/ST-1662939?service=<serviceURL>'

Response 200

{
  "status": "OK",
  "jwt": "eyJ0eXAiO.eyJ1aWQiOiJm...aXNjaGVybSIsIml.MxKiIhc_6hbz2rpjzGo",
  "username": "yournetid"
}

Response 400

{
  "status": "ERROR",
  "message": "Invalid Ticket: <error>"
}

GET /users #

Get a list of all the users of this service.

Request

GET /users HTTP/1.1
Host: csc346picturegram.test.apps.uits.arizona.edu
 
curl --location --request GET \
    'https://csc346picturegram.test.apps.uits.arizona.edu/users'

Response 200

{
    "status": "OK",
    "users": [
        {
            "usernam": "fischerm",
            "name": "Mark Fischer"
        },
        {
            "usernam": "ym1014",
            "name": "Yingjie Ma"
        },
        {
            "usernam": "harshitanarnoli",
            "name": "Harshita Narnoli"
        }
    ],
    "numusers": 3
}

POST /posts #

Create a new post. This action requires you to pass a JWT authentication token in as a Bearer token in an Authorization header. The body of the POST contains the message to add. The username is retrieved from the JWT auth token, and the timestamp is logged on the API server.

Properties #

Key Notes Required
message The text of the post. Yes
image_full_url URL to a full-size image. Do not set this if there is no image for this post. No
image_thumbnail_url URL to a thumbnail image. Do not set this if there is no image for this post. No

body

{
    "message": "This is some new message for a post.",
    "image_full_url": "https://example.com/fullsize_image.jpg",
    "image_thumbnail_url": "https://example.com/thumbnail_image.jpg",
}

Request

POST /posts HTTP/1.1
Host: csc346picturegram.test.apps.uits.arizona.edu
Authorization: Bearer eyJ0eXAiOiJKV1QiLC...You2iKxkAh8_Dr1lS0
Content-Type: application/json

{
    "message": "This is some new message to post in a post."
}
curl --request POST 'https://csc346picturegram.test.apps.uits.arizona.edu/posts' \
--header 'Authorization: Bearer eyJ0eXAiOiJKV1QiLC...You2iKxkAh8_Dr1lS0' \
--header 'Content-Type: application/json' \
--data-raw '{
    "message": "This is some new message to post in a post."
}'

Response 200

{
    "status": "OK"
}

GET /posts #

Get a list of posts. Currently this returns only the first 5 recent posts.

Request

GET /posts HTTP/1.1
Host: csc346picturegram.test.apps.uits.arizona.edu
 
curl --location --request GET \
    'https://csc346picturegram.test.apps.uits.arizona.edu/posts'

Response 200

{
    "status": "OK",
    "count": 3,
    "messages": [
        {
            "image_thumbnail_url": "https://example.com/images/DSC7866-sm.jpg",
            "message": "Congratulations! If you're seeing these posts then you've probably got your basic app working.",
            "username": "fischerm",
            "image_description": "Night time celebration of students in graduation gowns in the forground, with fireworks exploading in the background.",
            "image_full_url": "https://example.com/images/DSC7866.jpg",
            "type": "chat"
            "timestamp": "1708811130.770543",
        },
        {
            "message": "Another sample post with no image attached.",
            "username": "fischerm",
            "type": "chat",
            "timestamp": "1708811082.482178"
        },
        {
            "message": "Initial message post.",
            "username": "fischerm",
            "type": "chat",
            "timestamp": "1708811045.597851"
        }
    ],
    "last_message_timestamp": "1664771391.765176"
}

GET /posts/after/<startTime> #

Get a list of posts that were posted after the startTime. The startTime slot should be a seconds based timestamp with optional decimal, such as 1664848042.519957.

Request

GET /posts/after/1664848042.519957 HTTP/1.1
Host: csc346picturegram.test.apps.uits.arizona.edu
 
curl --location --request GET \
    'https://csc346picturegram.test.apps.uits.arizona.edu/posts/after/1664848042.519957'

Response 200

{
    "status": "OK",
    "count": 3,
    "messages": [
        {
            "image_thumbnail_url": "https://example.com/images/DSC7866-sm.jpg",
            "message": "Congratulations! If you're seeing these posts then you've probably got your basic app working.",
            "username": "fischerm",
            "image_description": "Night time celebration of students in graduation gowns in the forground, with fireworks exploading in the background.",
            "image_full_url": "https://example.com/images/DSC7866.jpg",
            "type": "chat"
            "timestamp": "1708811130.770543",
        },
        {
            "message": "Another sample post with no image attached.",
            "username": "fischerm",
            "type": "chat",
            "timestamp": "1708811082.482178"
        },
        {
            "message": "Initial message post.",
            "username": "fischerm",
            "type": "chat",
            "timestamp": "1708811045.597851"
        }
    ],
    "last_message_timestamp": "1664771391.765176"
}

GET /posts/before/<endTime> #

Get a list of posts that were posted before the endTime. The endTime slot should be a seconds based timestamp with optional decimal, such as 1664771391.765176.

Request

GET /posts/before/1664771391.765176 HTTP/1.1
Host: csc346picturegram.test.apps.uits.arizona.edu
 
curl --location --request GET \
    'https://csc346picturegram.test.apps.uits.arizona.edu/posts/before/1664771391.765176'

Response 200

{
    "status": "OK",
    "count": 3,
    "messages": [
        {
            "image_thumbnail_url": "https://example.com/images/DSC7866-sm.jpg",
            "message": "Congratulations! If you're seeing these posts then you've probably got your basic app working.",
            "username": "fischerm",
            "image_description": "Night time celebration of students in graduation gowns in the forground, with fireworks exploading in the background.",
            "image_full_url": "https://example.com/images/DSC7866.jpg",
            "type": "chat"
            "timestamp": "1708811130.770543",
        },
        {
            "message": "Another sample post with no image attached.",
            "username": "fischerm",
            "type": "chat",
            "timestamp": "1708811082.482178"
        },
        {
            "message": "Initial message post.",
            "username": "fischerm",
            "type": "chat",
            "timestamp": "1708811045.597851"
        }
    ],
    "last_message_timestamp": "1664771391.765176"
}

GET /login?service=<serviceURL> #

This is not really an API call, as you make this request directly as a browser navigation. This URL should be constructed in such a way that the user clicks on a link to this URL. The API call will result in a 302 redirection to the University's WebAuth system for authentication, and then handle the response, and redirect back to your app.

The return URL from this process is the serviceURL passed in as the service query string parameter. Note that the response to this is not a JSON object, it is an HTTP response of text/html with a location header set with the redirection to the Shibboleth Identity Provider. The service URL provided to Shibboleth is a return call to this API and the processlogin action.

Request

GET /login?service=http://localhost:8080/ HTTP/1.1
Host: csc346picturegram.test.apps.uits.arizona.edu
 
curl --location --request GET \
    'https://csc346picturegram.test.apps.uits.arizona.edu/login?service=http://localhost:8080/'

Response 302

HTTP/1.1 302 
date: Thu, 20 Oct 2022 17:44:54 GMT
content-type: text/html
content-length: 0
location: https://shibboleth.arizona.edu/webauth/login?service=https://csc346picturegram.test.apps.uits.arizona.edu/processlogin/aHR0cDovL2xvY2FsaG9zdDo4MDgwLw
 

GET /processlogin/<serviceToken>?ticket=<CASticket> #

This is not really an API call, as you make this request directly as a browser navigation. This URL is only ever called by the user's browser as it is redirected from the Shibboleth Idnetity Provider after the user has logged in. This method takes the serviceToken, decodes the base64 encoded data in it which contains the URL of your application. This is how the API knows where to redirect this response to, along with the CAS ticket. The API call will result in a 302 redirection to the University's WebAuth system for authentication, and then handle the response, and redirect back to your app.

Note that the response to this is not a JSON object, it is an HTTP response of text/html with a location header set with the redirection to your application, along with the CAS ticket.

Request

GET /processlogin/aHR0cDovL2xv?ticket=ST-1666...54638 HTTP/1.1
Host: csc346picturegram.test.apps.uits.arizona.edu
 
curl --location --request GET \
    'https://csc346picturegram.test.apps.uits.arizona.edu/processlogin/aHR0cDovL2xv?ticket=ST-1666...54638'

Response 302

HTTP/1.1 302 
date: Thu, 20 Oct 2022 17:44:54 GMT
content-type: text/html
content-length: 0
location: http://localhost:8080/?ticket=ST-166628...mn8idKJW1b8BPdk7