Profile as a Service

Application / Service Architecture

_images/PaS-architecture.png

Object Data Models

User

  • gcId a unique user identifier (string)
  • name user’s name (string)
  • email user’s email (string)
  • avatar url to user’s profile avatar (url)
  • titleEn user’s english position title (string)
  • titleFr user’s french position title (string)
  • mobilePhone mobile phone number (string)
  • officePhone office phone number (string)
  • address user’s work address (address object)
  • supervisor user object of identified supervisor (user object)
  • org organizational tier group object (org tier object)
  • Employees array of user objects that have this user as their supervisor (user object array)
  • OwnerOfOrgTier array of organizational tier objects that have this user as their owner (organizational tier array)

Address

  • id unique address object identifier (int)
  • streetAddress (string)
  • city (string)
  • province (string)
  • postalCode (string)
  • country (string)

Organization Tier

  • id unique organizaitonal tier object identifier (int)
  • nameEn english name of organizational tier (string)
  • nameFr french name of organizational tier (string)
  • organization top level organization object (organization object)
  • ownerID user object of the user who is listed as the owner of this org tier (user object)
  • OrgMembers array of user objects who are associated with this org tier (user object array)

Organization

  • id unique organization object identifier (int)
  • nameEn english name of organization (string)
  • nameFr french name of organization (string)
  • acronymEn english acronym of the organization (string)
  • acronymFr french acronym of the organization (string)
  • OrgTiers array of organizational tiers that are associated with this organization (organizational tier array)

Core Endpoints

All available endpoints use GraphQL query language.

/graphiql

This endpoint is used to access the graphiql interface which permits querying into the graphQL core through an easy to understand user interface. See /graphqlcore for available queries and mutations.

/graphqlcore

This endpoint is used by client applications that do not require a graphical interface. This endpoint is a pure API.

Queries

Queries do not require authentication of the client through the means of an access token.

Base query for all available information of a user without search criteria
profiles{
    gcID,
    name,
    email,
    avatar,
    mobilePhone,
    officePhone,
    titleEn,
    titleFr,
    address{
        id,
        streetAddress,
        city,
        province,
        postalCode,
        country
    }
    supervisor{
        gcID,
        name,
        email,
        avatar,
        mobilePhone,
        officePhone,
        titleEn,
        titleFr,
        address{
            id,
            streetAddress,
            city,
            province,
            postalCode,
            country
        }
    }
    org{
        id,
        nameEn,
        nameFr,
        organization{
            id,
            nameEn,
            nameFr,
            acronymEn,
            acronymFr,
        },
        ownerID{
            gcID,
            name,
            email,
            avatar,
            mobilePhone,
            officePhone,
            titleEn,
            titleFr,
            address{
                id,
                streetAddress,
                city,
                province,
                postalCode,
                country
            }
        }
    }
    OwnerOfOrgTier{
        nameEn,
        nameFr,
        organization{
            id,
            nameEn,
            nameFr,
            acronymEn,
            acronymFr,
        },
        OrgMembers{
            gcID,
            name,
            email,
            avatar,
            mobilePhone,
            officePhone,
            titleEn,
            titleFr,
            address{
                id,
                streetAddress,
                city,
                province,
                postalCode,
                country
            }

        }
    }
}
Query search criteria

Search criteria fields can be used separately or chained together to easily filter through data.

Profile

Available Arguments:

  • gcId exact match (string)
  • name name contains (string)
  • email exact match (string)
  • mobilePhone mobile number contains (string)
  • officePhone office number contains (string)
  • titleEn title contains (string)
  • titleFr title contains (string)

Example with all available arguments:

query{
    profiles(
        gcID:"string",
        name:"string",
        email:"string",
        mobilePhone:"string",
        officePhone:"string",
        titleEn:"string",
        titleFr:"string"
    )
}

Addresses

Available arguments:

  • id exact match (int)
  • streetAddress street address contains (string)
  • city city contains (string)
  • province exact match (string)
  • postalCode exact match (string)
  • country exact match (string)

Example with all available arguments

query{
    addresses(
        id:2,
        streetAddress:"string",
        city:"string",
        province:"string",
        postalCode:"string",
        country:"string"
    )
}

Organizational Tiers

Available arguments:

  • id exact match (int)
  • nameEn english name contains (string)
  • nameFr french name contains (string)

Example with all available arguments:

query{
    orgtiers(
        id:2,
        nameEn:"string",
        nameFr:"string",
    )
}

Organizations

Available arguments:

  • id exact match (int)
  • nameEn name of organization contains (string)
  • nameFr name of organization contains (string)
  • acronymEn exact match (string)
  • acronymFr exact match (string)
query{
    organizations(
        id:1,
        nameEn:"string",
        nameFr:"string",
        acronymEn:"string",
        acronymFr:"string"
    )
}
Paginiation

Retrieving too much data on a single request is unpractical and may even break your app. Pagination exists to solve this problem, allowing the client to specify how many items it wants.

The simple way defined in the GraphQL pagination documentation is to slice the results using two parameters: first, which returns the first n items and skip, which skips the first n items.

These two pagination parameters have been implemented on all of the search query functions.

The example query below will search for all profiles that contain the name “Bryan” but instead of returning the complete array the query b elow is requesting items 2 and 3 in the array. Skip the first item in the array and send the next 2 in the array.

query{
    profiles(name:"Bryan", first:2, skip:1){
        name,
        avatar,
        email
    }
}

Mutations

Mutations do require authentication in the form of the users valid OpenID Connect access token. The access token must be passed in the request header in the form Authorization: Bearer {access token}.

Profile Mutations

Available arguments to send in a mutation:

  • gcId a users identifier (string)

  • profileInfo an array object with values to modify (dict)

    • name user’s name (string)

    • email user’s email (string)

    • titleEn user’s english position title (string)

    • titleFr user’s french position title (string)

    • mobilePhone mobile phone number (string)

    • officePhone office phone number (string)

    • address user’s work address (address object)

      • streetAddress (string)
      • city (string)
      • province (string)
      • postalCode (string)
      • country (string)
    • supervisor user object of identified supervisor (user object)

      • gcID a users identifier (string)
    • org organizational tier group object

      • orgID an organizatinal tier’s unique id (int)

Example mutation using all available arguments:

mutation{
    modifyProfile(
        gcId:2,
        profileInfo:{
        name:"string",
        email:"string",
        titleEn:"string",
        titleFr:"string",
        mobilePhone:"string",
        officePhone:"string",
        address:{
            streetAddress:"string",
            city:"string",
            province:"string",
            postalCode:"string",
            country:"string",
        }
        supervisor:{
            gcId:3
        }
        org:{
            orgId:1
        }
    }
    )
}
Organization Tier Mutations

Create an OrgTier

Available arguments to send in a mutation:

  • nameEn english name of org tier (string)
  • nameFr french name of org tier (string)
  • organizationId organization unique id (int)
  • ownerGcId unique user who owns the organization (int)

Example mutation to create an OrgTier:

mutation{
    createOrgTier(
        nameEn:"string",
        nameFr:"string",
        organizationId:3
        ownerGcId:2
     )
}

Modify an OrgTier

Available arguments to send in a mutation:

  • orgId unique identifier of the org tier to modify (int)

  • dataToModify array of information to modify (dict)

    • nameEn english name of org tier (string)
    • nameFr french name of org tier (string)
    • organizationId organization unique id (int)
    • ownerGcId unique user who owns the organization (int)

Example mutation to modify an OrgTier:

mutation{
    modifyOrgTier(
        orgId:2,
        dataToModify:{
        nameEn:"string",
        nameFr:"string",
        organizationId:4,
        ownerGcId:23
        }
    )
}

Delete an OrgTier

Available arguments to send in a mutation:

  • orgTierId unique identifier of the org tier (int)

Example mutation to delete an OrgTier:

mutation{
    deleteOrgTier(
        orgTierId:6
        )
}

/protected

This endpoint is similar to the graphqlcore endpoint however is used for data management applications that have access to additional graphQL mutations. This endpoint is protected by token authentication and requires an account and active token on the graphql-core.

Image Resource Server API

The Profile as a Service leverages PictShare which is a multi lingual, open source image hosting application with a simple resizing and upload API for the hosting of profile avatar images. PictShare is licensed under the Apache-2.0 License

Features

  • Simple API to upload any image from remote servers to your instance [via URL](#upload-from-url) and [via Base64](#upload-from-base64-string)
  • 100% file based - no database needed
  • Simple album functions with embedding support
  • Converts gif to (much smaller) MP4
  • MP4 resizing
  • PictShare removes all exif data so you can upload photos from your phone and all GPS tags and camera model info get wiped
  • Smart [resize, filter and rotation](#smart-query-system) features
  • Duplicates don’t take up space. If the exact same images is uploaded twice, the second upload will link to the first
  • Detailed traffic and view statistics of your images via ‘Pictshare stats <https://github.com/chrisiaut/pictshare_stats>’_

Smart query system

PictShare images can be changed after upload just by modifying the URL. It works like this:

https://base.domain/<options>/<image>

For example: https://avatar.gccollab.ca/100x100/negative/b260e36b60.jpg will show you the uploaded Image `b260e36b60.jpg` but resize it to 100x100 pixels and apply the “negative” filter. The original image on the resource server will stay untouched.

Available options

Original URL: https://www.pictshare.net/b260e36b60.jpg

Note: If an option needs a value it works like this: optionname_value. Eg: pixelate_10 If there is an option requested that’s not recognized by PictShare it’s simply ignored, so this will work: https://www.pictshare.net/pictshare-is-awesome/b260e36b60.jpg and also even this will work: https://www.pictshare.net/b260e36b60.jpg/how-can-this-still/work/

Resizing
Option Parameter Example URL
<width>x<height> -none- https://pictshare.net/20x20/b260e36b60.jpg
forcecesize -none- https://pictshare.net/100x400/forcesize/b260e36b60.jpg
MP4 options
Option Parameter Example URL
-none- -none- https://www.pictshare.net/65714d22f0.mp4
raw -none- https://www.pictshare.net/raw/65714d22f0.mp4
preview -none- https://www.pictshare.net/preview/65714d22f0.mp4

You can also combine as many options as you want. Even multiple times! Want your image to be negative, resized, grayscale , with increased brightness and negate it again? No problem: https://pictshare.net/500x500/grayscale/negative/brightness_100/negative/b260e36b60.jpg

Security and privacy

  • No exif data is stored on the server, all jpegs get cleaned on upload