Module Information and Requirements

The Site Registration Module allows admin users, with the requisite permissions, to add new sites and delete existing sites from the RhinoOMS system. Similar to the User Registration Module, RhinoOMS implements a multi-layered cloud-based security protocol that is seperate from, but integrated into, the RhinoOMS app. Put simply, this means that to add/delete a site from the RhinoOMS system, an admin must make physical changes within the RhinoOMS app and source code, as well as physical changes to both Amazon Web Service’s (AWS) Redshift and S3 security permissions (via the AWS Console and awscli). This involves implementation within the RhinoOMS app and an R-based script editor (e.g., RStudio), as well as a Geographical Information System (GIS), AWS Query Editor (for Redshift) and AWS Identity and Access Management platform (for S3). This multi-layered approach helps to ensure RhinoOMS sites are securely managed and site-specific data are securely regulated. To proceed, please ensure you have the following:

  • Site name
  • Simplified polygon shapefile of the site (datam: WGS84; unprojected)
  • Admin S3 and Redshift credentials
  • Stable internet connection

Step-by-step guidelines to adding a site

Step 1

Start the RhinoOMS app, and ensure you are successfuly logged into Redshift and S3.

Step 2

To add a site, enter the site name into the text box. Ensure that only letters and underscores are used when entering the site name.

Step 3

Click the Add Site button to submit the new site’s details to the RhinoOMS system. Please be patient and allow for the data verification process and upload to complete.

Step 4

In an R-based script editor, like RStudio, open the config.R script (from your Github branch) and add the new site to the dtbs_schm object (aka. database schema). As of this writing, the dtbs_schm object is generated using the following R code:

dtbs_schm <- tibble::tibble(
      id = c(
        "Addo_Elephant_National_Park", 
        "Tsavo_West_National_Park", 
        "Lewa_Borana_Conservancy", 
        "Ol_Pejeta_Conservancy", 
        "Great_Fish_Nature_Reserve", 
        "full"
      ),
      schema = c(
        "aenp",
        "twnp",
        "lbc",
        "opc",
        "gfnr",
        "rhinooms"
      ),
      group = c(
        "aenpgroup",
        "twnpgroup",
        "lbcgroup",
        "opcgroup",
        "gfnrgroup",
        "rhinoomsgroup"
      ),
      x = c(
        "25.6",
        "38.1",
        "37.36",
        "36.86",
        "26.8",
        "26.8"
      ),
      y = c(
        "-33.3",
        "-3.4",
        "0.236",
        "0.02",
        "-33.005",
        "-33.005"
      ),
      zoom = c(
        "9",
        "8",
        "10",
        "10",
        "10",
        "10"
      )
    )

Step 5

Save these modifications to the config.R script, and commit these changes to the RhinoOMS docker container by copying the file into the /srv/shiny-server/ directory within the container.

Step 6

Open your GIS software of choice (e.g., ESRI ArcMap, QGIS), and merge the new simplified polygon shapefile (of the new site) with the existing RhinoOMS_Site_Boundaries.shp located within the /data/maps/ directory. Please note that the new simplified polygon shapefile’s attributes must match those of the existing RhinoOMS_Site_Boundaries.shp before merging (i.e., headers equal “Id” and “NAME”). As of this writing, an example of the current attributes are:

Step 7

Save these modifications back to the original RhinoOMS_Site_Boundaries.shp located within the /data/maps/ directory, and commit these changes to the RhinoOMS docker container by copying the files into the /srv/shiny-server/data/maps/ directory within the container.

Step 8

Go to the AWS Console (https://aws.amazon.com), sign in using your admin AWS credentials, then go to Amazon S3 and create the following buckets, prefixed with the site abreviation used in the config.R script:
aenp-rhinooms-immobilisation-evidence
aenp-rhinooms-mortality-evidence
aenp-rhinooms-notching-evidence
aenp-rhinooms-registration-evidence
aenp-rhinooms-sightings-evidence
aenp-rhinooms-translocation-evidence
aenp-rhinooms-temp

Step 9

Ensure that, for each bucket, versioning is enabled and encryption is enabled using the RhinoOMS_EK enccryption key. See below:

Step 10

Ensure that, for each bucket, the permissions are setup similar to the settings below:

Step 11

Go to AWS IAM Management Console, then click on Policies, then click on Create policy. Once the policy editor has opened, select the JSON tab, and enter to following JSON script (modified to reflect the new site) to enable read access to the newly created buckets:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "s3:GetBucketObjectLockConfiguration",
                "kms:Encrypt",
                "s3:GetBucketPolicyStatus",
                "s3:GetBucketNotification",
                "s3:DescribeJob",
                "s3:GetAnalyticsConfiguration",
                "s3:ListBucketByTags",
                "s3:GetLifecycleConfiguration",
                "s3:GetBucketTagging",
                "s3:GetInventoryConfiguration",
                "s3:ListBucketVersions",
                "s3:GetBucketLogging",
                "s3:ListBucket",
                "s3:GetAccelerateConfiguration",
                "s3:GetBucketPolicy",
                "s3:GetEncryptionConfiguration",
                "s3:GetBucketRequestPayment",
                "kms:DescribeKey",
                "s3:GetBucketPublicAccessBlock",
                "s3:UpdateJobStatus",
                "s3:GetBucketVersioning",
                "s3:GetBucketAcl",
                "s3:GetBucketCORS",
                "s3:GetBucketLocation"
            ],
            "Resource": [
              "arn:aws:kms:eu-west-1:329552323341:key/db997637-3313-45a9-9070-98a3ee8ad6c4",
              "arn:aws:s3:::aenp-rhinooms-immobilisation-evidence",
              "arn:aws:s3:::aenp-rhinooms-mortality-evidence",
              "arn:aws:s3:::aenp-rhinooms-notching-evidence",
              "arn:aws:s3:::aenp-rhinooms-registration-evidence",
              "arn:aws:s3:::aenp-rhinooms-sightings-evidence",
              "arn:aws:s3:::aenp-rhinooms-translocation-evidence",
              "arn:aws:s3:::aenp-rhinooms-temp"
            ]
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:Encrypt",
                "kms:DescribeKey",
                "s3:GetBucketPolicyStatus",
                "s3:GetBucketPublicAccessBlock",
                "s3:GetBucketLogging",
                "s3:GetAccelerateConfiguration",
                "s3:UpdateJobStatus",
                "s3:GetBucketAcl",
                "s3:GetBucketNotification",
                "s3:GetBucketPolicy",
                "s3:GetBucketObjectLockConfiguration",
                "s3:DescribeJob",
                "s3:GetBucketCORS",
                "s3:GetAnalyticsConfiguration",
                "s3:GetBucketLocation"
            ],
            "Resource": [
              "arn:aws:kms:eu-west-1:329552323341:key/db997637-3313-45a9-9070-98a3ee8ad6c4",
              "arn:aws:s3:::aenp-rhinooms-immobilisation-evidence",
              "arn:aws:s3:::aenp-rhinooms-mortality-evidence",
              "arn:aws:s3:::aenp-rhinooms-notching-evidence",
              "arn:aws:s3:::aenp-rhinooms-registration-evidence",
              "arn:aws:s3:::aenp-rhinooms-sightings-evidence",
              "arn:aws:s3:::aenp-rhinooms-translocation-evidence",
              "arn:aws:s3:::aenp-rhinooms-temp",
              "arn:aws:s3:*:*:job/*"
            ]
        },
        {
            "Sid": "VisualEditor2",
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:Encrypt",
                "kms:DescribeKey",
                "s3:GetBucketLogging",
                "s3:RestoreObject",
                "s3:GetAccelerateConfiguration",
                "s3:GetBucketPolicy",
                "s3:ReplicateObject",
                "s3:GetObjectAcl",
                "s3:GetBucketObjectLockConfiguration",
                "s3:AbortMultipartUpload",
                "s3:GetObjectTagging",
                "s3:GetBucketPublicAccessBlock",
                "s3:GetBucketPolicyStatus",
                "s3:GetObjectRetention",
                "s3:UpdateJobStatus",
                "s3:GetBucketAcl",
                "s3:GetObjectLegalHold",
                "s3:GetBucketNotification",
                "s3:GetObject",
                "s3:GetObjectTorrent",
                "s3:DescribeJob",
                "s3:GetBucketCORS",
                "s3:GetAnalyticsConfiguration",
                "s3:GetBucketLocation",
                "s3:GetObjectVersion"
            ],
            "Resource": "arn:aws:s3:::*/*"
        },
        {
            "Sid": "VisualEditor3",
            "Effect": "Allow",
            "Action": [
                "s3:GetAccountPublicAccessBlock",
                "s3:ListAllMyBuckets",
                "s3:ListJobs",
                "s3:CreateJob",
                "s3:HeadBucket"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor4",
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:Encrypt",
                "kms:DescribeKey",
                "s3:GetObjectVersionTagging",
                "s3:ReplicateObject",
                "s3:GetObjectAcl",
                "s3:GetBucketObjectLockConfiguration",
                "s3:GetObjectVersionAcl",
                "s3:GetBucketPolicyStatus",
                "s3:GetObjectRetention",
                "s3:GetObjectLegalHold",
                "s3:GetBucketNotification",
                "s3:ListMultipartUploadParts",
                "s3:GetObject",
                "s3:DescribeJob",
                "s3:GetAnalyticsConfiguration",
                "s3:GetObjectVersionForReplication",
                "s3:GetLifecycleConfiguration",
                "s3:ListBucketByTags",
                "s3:GetInventoryConfiguration",
                "s3:GetBucketTagging",
                "s3:GetBucketLogging",
                "s3:ListBucketVersions",
                "s3:RestoreObject",
                "s3:ListBucket",
                "s3:GetAccelerateConfiguration",
                "s3:GetBucketPolicy",
                "s3:GetEncryptionConfiguration",
                "s3:GetObjectVersionTorrent",
                "s3:AbortMultipartUpload",
                "s3:GetBucketRequestPayment",
                "s3:GetObjectTagging",
                "s3:GetBucketPublicAccessBlock",
                "s3:UpdateJobStatus",
                "s3:GetBucketVersioning",
                "s3:GetBucketAcl",
                "s3:GetObjectTorrent",
                "s3:GetBucketCORS",
                "s3:GetBucketLocation",
                "s3:GetObjectVersion"
            ],
            "Resource": [
              "arn:aws:kms:eu-west-1:329552323341:key/db997637-3313-45a9-9070-98a3ee8ad6c4",
              "arn:aws:s3:::aenp-rhinooms-immobilisation-evidence",
              "arn:aws:s3:::aenp-rhinooms-mortality-evidence",
              "arn:aws:s3:::aenp-rhinooms-notching-evidence",
              "arn:aws:s3:::aenp-rhinooms-registration-evidence",
              "arn:aws:s3:::aenp-rhinooms-sightings-evidence",
              "arn:aws:s3:::aenp-rhinooms-translocation-evidence",
              "arn:aws:s3:::aenp-rhinooms-temp"
            ]
        }
    ]
}

Step 12

Save the previous policy, giving it the name rhinooms-aenp-r. Create another policy, select the JSON tab, and enter to following JSON script (modified to reflect the new site) to enable write access to the newly created buckets:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "s3:GetBucketObjectLockConfiguration",
                "kms:Encrypt",
                "s3:GetBucketPolicyStatus",
                "s3:GetBucketNotification",
                "s3:DescribeJob",
                "s3:GetAnalyticsConfiguration",
                "s3:ListBucketByTags",
                "s3:GetLifecycleConfiguration",
                "s3:GetBucketTagging",
                "s3:GetInventoryConfiguration",
                "s3:ListBucketVersions",
                "s3:GetBucketLogging",
                "s3:ListBucket",
                "s3:GetAccelerateConfiguration",
                "s3:GetBucketPolicy",
                "s3:PutEncryptionConfiguration",
                "s3:GetEncryptionConfiguration",
                "s3:GetBucketRequestPayment",
                "kms:DescribeKey",
                "s3:GetBucketPublicAccessBlock",
                "s3:UpdateJobStatus",
                "s3:GetBucketVersioning",
                "s3:GetBucketAcl",
                "s3:GetBucketCORS",
                "s3:GetBucketLocation"
            ],
            "Resource": [
                "arn:aws:kms:eu-west-1:329552323341:key/db997637-3313-45a9-9070-98a3ee8ad6c4",
                "arn:aws:s3:::aenp-rhinooms-immobilisation-evidence",
                "arn:aws:s3:::aenp-rhinooms-mortality-evidence",
                "arn:aws:s3:::aenp-rhinooms-notching-evidence",
                "arn:aws:s3:::aenp-rhinooms-registration-evidence",
                "arn:aws:s3:::aenp-rhinooms-sightings-evidence",
                "arn:aws:s3:::aenp-rhinooms-translocation-evidence",
                "arn:aws:s3:::aenp-rhinooms-temp"
            ]
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:Encrypt",
                "kms:DescribeKey",
                "s3:GetBucketPolicyStatus",
                "s3:GetBucketPublicAccessBlock",
                "s3:GetBucketLogging",
                "s3:GetAccelerateConfiguration",
                "s3:UpdateJobStatus",
                "s3:GetBucketAcl",
                "s3:GetBucketNotification",
                "s3:GetBucketPolicy",
                "s3:PutEncryptionConfiguration",
                "s3:GetBucketObjectLockConfiguration",
                "s3:DescribeJob",
                "s3:GetBucketCORS",
                "s3:GetAnalyticsConfiguration",
                "s3:GetBucketLocation"
            ],
            "Resource": [
                "arn:aws:kms:eu-west-1:329552323341:key/db997637-3313-45a9-9070-98a3ee8ad6c4",
                "arn:aws:s3:::aenp-rhinooms-immobilisation-evidence",
                "arn:aws:s3:::aenp-rhinooms-mortality-evidence",
                "arn:aws:s3:::aenp-rhinooms-notching-evidence",
                "arn:aws:s3:::aenp-rhinooms-registration-evidence",
                "arn:aws:s3:::aenp-rhinooms-sightings-evidence",
                "arn:aws:s3:::aenp-rhinooms-translocation-evidence",
                "arn:aws:s3:::aenp-rhinooms-temp",
                "arn:aws:s3:*:*:job/*"
            ]
        },
        {
            "Sid": "VisualEditor2",
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:Encrypt",
                "kms:DescribeKey",
                "s3:GetBucketLogging",
                "s3:RestoreObject",
                "s3:GetAccelerateConfiguration",
                "s3:GetBucketPolicy",
                "s3:ReplicateObject",
                "s3:PutEncryptionConfiguration",
                "s3:PutObjectAcl",
                "s3:GetBucketObjectLockConfiguration",
                "s3:AbortMultipartUpload",
                "s3:GetObjectTagging",
                "s3:GetBucketPublicAccessBlock",
                "s3:GetBucketPolicyStatus",
                "s3:GetObjectRetention",
                "s3:UpdateJobStatus",
                "s3:GetBucketAcl",
                "s3:GetObjectLegalHold",
                "s3:GetBucketNotification",
                "s3:PutObject",
                "s3:GetObjectTorrent",
                "s3:DescribeJob",
                "s3:GetBucketCORS",
                "s3:GetAnalyticsConfiguration",
                "s3:GetBucketLocation",
                "s3:GetObjectVersion"
            ],
            "Resource": "arn:aws:s3:::*/*"
        },
        {
            "Sid": "VisualEditor3",
            "Effect": "Allow",
            "Action": [
                "s3:GetAccountPublicAccessBlock",
                "s3:ListAllMyBuckets",
                "s3:ListJobs",
                "s3:CreateJob",
                "s3:HeadBucket"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor4",
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:Encrypt",
                "kms:DescribeKey",
                "s3:GetObjectVersionTagging",
                "s3:ReplicateObject",
                "s3:PutObjectAcl",
                "s3:GetBucketObjectLockConfiguration",
                "s3:GetObjectVersionAcl",
                "s3:GetBucketPolicyStatus",
                "s3:GetObjectRetention",
                "s3:PutObjectLegalHold",
                "s3:GetObjectLegalHold",
                "s3:GetBucketNotification",
                "s3:ListMultipartUploadParts",
                "s3:PutObject",
                "s3:DescribeJob",
                "s3:GetAnalyticsConfiguration",
                "s3:GetObjectVersionForReplication",
                "s3:GetLifecycleConfiguration",
                "s3:ListBucketByTags",
                "s3:GetInventoryConfiguration",
                "s3:GetBucketTagging",
                "s3:GetBucketLogging",
                "s3:ListBucketVersions",
                "s3:RestoreObject",
                "s3:ListBucket",
                "s3:GetAccelerateConfiguration",
                "s3:GetBucketPolicy",
                "s3:PutEncryptionConfiguration",
                "s3:GetEncryptionConfiguration",
                "s3:GetObjectVersionTorrent",
                "s3:AbortMultipartUpload",
                "s3:GetBucketRequestPayment",
                "s3:GetObjectTagging",
                "s3:GetBucketPublicAccessBlock",
                "s3:UpdateJobStatus",
                "s3:GetBucketVersioning",
                "s3:GetBucketAcl",
                "s3:GetObjectTorrent",
                "s3:PutObjectRetention",
                "s3:GetBucketCORS",
                "s3:GetBucketLocation",
                "s3:GetObjectVersion"
            ],
            "Resource": [
                "arn:aws:kms:eu-west-1:329552323341:key/db997637-3313-45a9-9070-98a3ee8ad6c4",
                "arn:aws:s3:::aenp-rhinooms-immobilisation-evidence",
                "arn:aws:s3:::aenp-rhinooms-mortality-evidence",
                "arn:aws:s3:::aenp-rhinooms-notching-evidence",
                "arn:aws:s3:::aenp-rhinooms-registration-evidence",
                "arn:aws:s3:::aenp-rhinooms-sightings-evidence",
                "arn:aws:s3:::aenp-rhinooms-translocation-evidence",
                "arn:aws:s3:::aenp-rhinooms-temp"
            ]
        }
    ]
}

Step 13

Save the previous policy, giving it the name rhinooms-aenp-w. Create another policy, select the JSON tab, and enter to following JSON script (modified to reflect the new site) to enable read-write access to the newly created buckets:

{
    "Version": "2012-10-17",
    "Statement": [
        {
            "Sid": "VisualEditor0",
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "s3:GetBucketObjectLockConfiguration",
                "kms:Encrypt",
                "s3:GetBucketPolicyStatus",
                "s3:GetBucketNotification",
                "s3:DescribeJob",
                "s3:GetAnalyticsConfiguration",
                "s3:ListBucketByTags",
                "s3:GetLifecycleConfiguration",
                "s3:GetBucketTagging",
                "s3:GetInventoryConfiguration",
                "s3:ListBucketVersions",
                "s3:GetBucketLogging",
                "s3:ListBucket",
                "s3:GetAccelerateConfiguration",
                "s3:GetBucketPolicy",
                "s3:PutEncryptionConfiguration",
                "s3:GetEncryptionConfiguration",
                "s3:GetBucketRequestPayment",
                "kms:DescribeKey",
                "s3:GetBucketPublicAccessBlock",
                "s3:UpdateJobStatus",
                "s3:GetBucketVersioning",
                "s3:GetBucketAcl",
                "s3:GetBucketCORS",
                "s3:GetBucketLocation"
            ],
            "Resource": [
              "arn:aws:kms:eu-west-1:329552323341:key/db997637-3313-45a9-9070-98a3ee8ad6c4",
              "arn:aws:s3:::aenp-rhinooms-immobilisation-evidence",
              "arn:aws:s3:::aenp-rhinooms-mortality-evidence",
              "arn:aws:s3:::aenp-rhinooms-notching-evidence",
              "arn:aws:s3:::aenp-rhinooms-registration-evidence",
              "arn:aws:s3:::aenp-rhinooms-sightings-evidence",
              "arn:aws:s3:::aenp-rhinooms-translocation-evidence",
              "arn:aws:s3:::aenp-rhinooms-temp"
            ]
        },
        {
            "Sid": "VisualEditor1",
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:Encrypt",
                "kms:DescribeKey",
                "s3:GetBucketPolicyStatus",
                "s3:GetBucketPublicAccessBlock",
                "s3:GetBucketLogging",
                "s3:GetAccelerateConfiguration",
                "s3:UpdateJobStatus",
                "s3:GetBucketAcl",
                "s3:GetBucketNotification",
                "s3:GetBucketPolicy",
                "s3:PutEncryptionConfiguration",
                "s3:GetBucketObjectLockConfiguration",
                "s3:DescribeJob",
                "s3:GetBucketCORS",
                "s3:GetAnalyticsConfiguration",
                "s3:GetBucketLocation"
            ],
            "Resource": [
              "arn:aws:kms:eu-west-1:329552323341:key/db997637-3313-45a9-9070-98a3ee8ad6c4",
              "arn:aws:s3:::aenp-rhinooms-immobilisation-evidence",
              "arn:aws:s3:::aenp-rhinooms-mortality-evidence",
              "arn:aws:s3:::aenp-rhinooms-notching-evidence",
              "arn:aws:s3:::aenp-rhinooms-registration-evidence",
              "arn:aws:s3:::aenp-rhinooms-sightings-evidence",
              "arn:aws:s3:::aenp-rhinooms-translocation-evidence",
              "arn:aws:s3:::aenp-rhinooms-temp",
                "arn:aws:s3:*:*:job/*"
            ]
        },
        {
            "Sid": "VisualEditor2",
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:Encrypt",
                "kms:DescribeKey",
                "s3:GetBucketLogging",
                "s3:RestoreObject",
                "s3:GetAccelerateConfiguration",
                "s3:GetBucketPolicy",
                "s3:ReplicateObject",
                "s3:PutEncryptionConfiguration",
                "s3:GetObjectAcl",
                "s3:PutObjectAcl",
                "s3:GetBucketObjectLockConfiguration",
                "s3:AbortMultipartUpload",
                "s3:GetObjectTagging",
                "s3:GetBucketPublicAccessBlock",
                "s3:GetBucketPolicyStatus",
                "s3:GetObjectRetention",
                "s3:UpdateJobStatus",
                "s3:GetBucketAcl",
                "s3:GetObjectLegalHold",
                "s3:GetBucketNotification",
                "s3:GetObject",
                "s3:PutObject",
                "s3:GetObjectTorrent",
                "s3:DescribeJob",
                "s3:GetBucketCORS",
                "s3:GetAnalyticsConfiguration",
                "s3:GetBucketLocation",
                "s3:GetObjectVersion"
            ],
            "Resource": "arn:aws:s3:::*/*"
        },
        {
            "Sid": "VisualEditor3",
            "Effect": "Allow",
            "Action": [
                "s3:GetAccountPublicAccessBlock",
                "s3:ListAllMyBuckets",
                "s3:ListJobs",
                "s3:CreateJob",
                "s3:HeadBucket"
            ],
            "Resource": "*"
        },
        {
            "Sid": "VisualEditor4",
            "Effect": "Allow",
            "Action": [
                "kms:Decrypt",
                "kms:ReEncrypt*",
                "kms:GenerateDataKey*",
                "kms:Encrypt",
                "kms:DescribeKey",
                "s3:GetObjectVersionTagging",
                "s3:ReplicateObject",
                "s3:GetObjectAcl",
                "s3:PutObjectAcl",
                "s3:GetBucketObjectLockConfiguration",
                "s3:GetObjectVersionAcl",
                "s3:GetBucketPolicyStatus",
                "s3:GetObjectRetention",
                "s3:PutObjectLegalHold",
                "s3:GetObjectLegalHold",
                "s3:GetBucketNotification",
                "s3:ListMultipartUploadParts",
                "s3:PutObject",
                "s3:GetObject",
                "s3:DescribeJob",
                "s3:GetAnalyticsConfiguration",
                "s3:GetObjectVersionForReplication",
                "s3:GetLifecycleConfiguration",
                "s3:ListBucketByTags",
                "s3:GetInventoryConfiguration",
                "s3:GetBucketTagging",
                "s3:GetBucketLogging",
                "s3:ListBucketVersions",
                "s3:RestoreObject",
                "s3:ListBucket",
                "s3:GetAccelerateConfiguration",
                "s3:GetBucketPolicy",
                "s3:PutEncryptionConfiguration",
                "s3:GetEncryptionConfiguration",
                "s3:GetObjectVersionTorrent",
                "s3:AbortMultipartUpload",
                "s3:GetBucketRequestPayment",
                "s3:GetObjectTagging",
                "s3:GetBucketPublicAccessBlock",
                "s3:UpdateJobStatus",
                "s3:GetBucketVersioning",
                "s3:GetBucketAcl",
                "s3:GetObjectTorrent",
                "s3:PutObjectRetention",
                "s3:GetBucketCORS",
                "s3:GetBucketLocation",
                "s3:GetObjectVersion"
            ],
            "Resource": [
              "arn:aws:kms:eu-west-1:329552323341:key/db997637-3313-45a9-9070-98a3ee8ad6c4",
              "arn:aws:s3:::aenp-rhinooms-immobilisation-evidence",
              "arn:aws:s3:::aenp-rhinooms-mortality-evidence",
              "arn:aws:s3:::aenp-rhinooms-notching-evidence",
              "arn:aws:s3:::aenp-rhinooms-registration-evidence",
              "arn:aws:s3:::aenp-rhinooms-sightings-evidence",
              "arn:aws:s3:::aenp-rhinooms-translocation-evidence",
              "arn:aws:s3:::aenp-rhinooms-temp"
            ]
        }
    ]
}

Step 14

Save the previous policy, giving it the name rhinooms-aenp-r-w.

Step 15

Within the AWS IAM Management Console, click on Groups, then click the Create New Group button. Create the rhinooms-aenp-r group, rhinooms-aenp-w group and rhinooms-aenp-r-w group, and attach their respective policies.

Step 16

Go to Amazon Redshift and click on the Editor tab on the left of your screen. This will open a window to allow you to connect to the database behind the RhinoOMS system. Create a new connection on cluster - rhinooms using database name - rhinosdtbs, then enter the master username and password. Then click Connect to database. See image below:

Step 17

In the query editor console, enter the following SQL scripts to add the new schema and group to Redshift:

  create schema aenp;
  create group aenpgroup;

Step 18

Enter the next SQL scripts to create dynamic views on the database, given the new site:

  create view 
    aenp.popmod as select * from rhinooms.popmod 
    where site = 'Addo_Elephant_National_Park';
    
  create view 
    aenp.sighting as select * from rhinooms.sighting 
    where site = 'Addo_Elephant_National_Park';
    
  create view 
    aenp.demographics as select * from rhinooms.demographics 
    where site = 'Addo_Elephant_National_Park';
    
  create view 
    aenp.mortality as select * from rhinooms.mortality 
    where site = 'Addo_Elephant_National_Park';
    
  create view 
    aenp.notching as select * from rhinooms.notching 
    where site = 'Addo_Elephant_National_Park';
    
  create view 
    aenp.immobilisation as select * from rhinooms.immobilisation 
    where site = 'Addo_Elephant_National_Park';
    
  create view 
    aenp.sts as select * from rhinooms.sts 
    where site = 'Addo_Elephant_National_Park';
    
  create view 
    aenp.translocation as select * from rhinooms.translocation 
    where site = 'Addo_Elephant_National_Park';
    
  create view 
    aenp.usr_accss_id as select * from rhinooms.usr_accss_id 
    where sitelevel = 'Addo_Elephant_National_Park';
    
  create view 
    aenp.rhino_id as select * from rhinooms.rhino_id 
    where site = 'Addo_Elephant_National_Park';
    
  create view 
    aenp.rhino_id_max_int as select 
    primarykey, rhinoid, rhinocode, site from 
    rhinooms.rhino_id;
    
  create view 
    aenp.usr_accss_id_max_pk as select 
    primarykey from 
    rhinooms.usr_accss_id;
    
  create view 
    aenp.immobilisation_max_id as select 
    immobilisationid from 
    rhinooms.immobilisation;
  
  create view 
    aenp.notching_max_id as select 
    notchid from 
    rhinooms.notching;
  
  create view 
    aenp.mortality_max_id as select 
    mortalityid from 
    rhinooms.mortality;
    
  create view 
    aenp.sighting_max_id as select 
    sightingid from 
    rhinooms.sighting;
    
  create view 
    aenp.translocation_max_id as select 
    translocationid from 
    rhinooms.translocation;
    
  create view 
    aenp.popmod_max_id as select 
    primarykey from 
    rhinooms.popmod;
    
  create view 
    aenp.rhino_id_temp_max_int as select 
    primarykey, rhinoid, site from 
    rhinooms.rhino_id_temp;

Step 19

Enter the next SQL scripts to setup permissions on the database, given the new site:

  grant usage on schema rhinooms to group aenpgroup;
  grant usage on schema aenp to group aenpgroup;
  revoke all on rhinooms.sighting from group aenpgroup;
  revoke all on rhinooms.demographics from group aenpgroup;
  revoke all on rhinooms.mortality from group aenpgroup;
  revoke all on rhinooms.notching from group aenpgroup;
  revoke all on rhinooms.immobilisation from group aenpgroup;
  revoke all on rhinooms.sts from group aenpgroup;
  revoke all on rhinooms.translocation from group aenpgroup;
  revoke all on rhinooms.usr_accss_id from group aenpgroup;
  revoke all on rhinooms.rhino_id from group aenpgroup;
  revoke all on rhinooms.rhino_id_max_int from group aenpgroup;
  revoke all on rhinooms.rhino_id_temp from group aenpgroup;
  revoke all on aenp.rhino_id_temp_max_int from group aenpgroup;
  revoke all on rhinooms.usr_accss_id_max_pk from group aenpgroup;
  revoke all on rhinooms.immobilisation_max_id from group aenpgroup;
  revoke all on rhinooms.notching_max_id from group aenpgroup;
  revoke all on rhinooms.mortality_max_id from group aenpgroup;
  revoke all on rhinooms.sighting_max_id from group aenpgroup;
  revoke all on rhinooms.translocation_max_id from group aenpgroup;
  revoke all on rhinooms.popmod_max_id from group aenpgroup;
  grant insert on rhinooms.sighting to group aenpgroup;
  grant insert on rhinooms.demographics to group aenpgroup;
  grant insert on rhinooms.mortality to group aenpgroup;
  grant insert on rhinooms.notching to group aenpgroup;
  grant insert on rhinooms.immobilisation to group aenpgroup;
  grant insert on rhinooms.sts to group aenpgroup;
  grant insert on rhinooms.translocation to group aenpgroup;
  grant insert on rhinooms.usr_accss_id to group aenpgroup;
  grant insert on rhinooms.rhino_id to group aenpgroup;
  grant insert on rhinooms.rhino_id_temp to group aenpgroup;
  grant select on aenp.sighting to group aenpgroup;
  grant select on aenp.demographics to group aenpgroup;
  grant select on aenp.mortality to group aenpgroup;
  grant select on aenp.notching to group aenpgroup;
  grant select on aenp.immobilisation to group aenpgroup;
  grant select on aenp.sts to group aenpgroup;
  grant select on aenp.translocation to group aenpgroup;
  grant select on aenp.usr_accss_id to group aenpgroup;
  grant select on aenp.rhino_id to group aenpgroup;
  grant select on aenp.rhino_id_max_int to group aenpgroup;
  grant select on aenp.usr_accss_id_max_pk to group aenpgroup;
  grant select on aenp.immobilisation_max_id to group aenpgroup;
  grant select on aenp.notching_max_id to group aenpgroup;
  grant select on aenp.mortality_max_id to group aenpgroup;
  grant select on aenp.sighting_max_id to group aenpgroup;
  grant select on aenp.translocation_max_id to group aenpgroup;
  grant select on aenp.popmod to group aenpgroup;
  grant select on aenp.popmod_max_id to group aenpgroup;
  grant select on aenp.rhino_id_temp_max_int to group aenpgroup;
  grant update on aenp.sighting to group aenpgroup;
  grant update on aenp.demographics to group aenpgroup;
  grant update on aenp.mortality to group aenpgroup;
  grant update on aenp.notching to group aenpgroup;
  grant update on aenp.immobilisation to group aenpgroup;
  grant update on aenp.sts to group aenpgroup;
  grant update on aenp.translocation to group aenpgroup;
  grant update on aenp.usr_accss_id to group aenpgroup;
  grant update on rhinooms.rhino_id to group aenpgroup;
  grant update on rhinooms.rhino_id_temp to group aenpgroup;

Step 20

To view all users linked to a specific group, enter the following SQL script:

  select usename from pg_user , pg_group  where
  pg_user.usesysid = ANY(pg_group.grolist) and
  pg_group.groname = 'aenpgroup';

Step 21

To view a user’s permissions on a specific schema, enter the following SQL script:

  SELECT * FROM
    (
    SELECT
        schemaname
        ,objectname
        ,usename
        ,HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'select')
        AND has_schema_privilege(usrs.usename, schemaname, 'usage')  AS sel
        ,HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'insert')
        AND has_schema_privilege(usrs.usename, schemaname, 'usage')  AS ins
        ,HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'update')
        AND has_schema_privilege(usrs.usename, schemaname, 'usage')  AS upd
        ,HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'delete')
        AND has_schema_privilege(usrs.usename, schemaname, 'usage')  AS del
        ,HAS_TABLE_PRIVILEGE(usrs.usename, fullobj, 'references')
        AND has_schema_privilege(usrs.usename, schemaname, 'usage')  AS ref
    FROM
        (
        SELECT schemaname, 't' AS obj_type,
        tablename AS objectname,
        schemaname + '.' + tablename AS fullobj FROM pg_tables
        WHERE schemaname not in ('pg_internal')
        UNION
        SELECT schemaname, 'v' AS obj_type,
        viewname AS objectname,
        schemaname + '.' + viewname AS fullobj FROM pg_views
        WHERE schemaname not in ('pg_internal')
        ) AS objs
        ,(SELECT * FROM pg_user) AS usrs
    ORDER BY fullobj
    )
    WHERE (sel = true or ins = true or upd = true or del = true or ref = true)
    and schemaname = 'aenp'
    and usename = 'NameSurname';

Step 22

Redshift Groups can be altered retrospectively, in order to add or remove users. For example, adding a user to a group can be achieved by running the following SQL script:

  alter group aenpgroup add user NameSurname;

Step 23

Iterate the version number by modifying the version object in R within the container, which can be found at /srv/shiny-server/data/vrsn.Rdata.

Step 24

Once all modifications have been made, you should commit your changes to a new Docker image by running the following bash script in Terminal/Command Prompt:

docker commit <ContainerID> roms_X.X.X

Step 25

Create Docker version tags by running the following bash script in Terminal/Command Prompt:

docker tag <ImageID> rhinooms/rhino_oms:roms_X.X.X
docker tag <ImageID> rhinooms/rhino_oms:latest_beta
docker tag <ImageID> rhinooms/rhino_oms:latest

Step 26

Ensure you are logged into the rhinooms Docker Hub account, and then push the updates to Docker Hub using the following bash script:

docker push rhinooms/rhino_oms:roms_X.X.X
docker push rhinooms/rhino_oms:latest_beta
docker push rhinooms/rhino_oms:latest

Problems?

If you experience any issues, please report it to the Issue Tracker.