Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Panopto-oauth2-integration documentation #120

Merged
merged 23 commits into from
Dec 21, 2024
Merged
Show file tree
Hide file tree
Changes from 22 commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
94538bd
Create panopto-oauth2-intergration-plan
washyking Dec 5, 2024
8a082e5
Update panopto-oauth2-intergration-plan
washyking Dec 5, 2024
e72a2a0
Update panopto-oauth2-intergration-plan
washyking Dec 5, 2024
bf626e2
Update panopto-oauth2-intergration-plan
washyking Dec 5, 2024
a486d67
Rename panopto-oauth2-intergration-plan to panopto-oauth2-intergratio…
washyking Dec 5, 2024
55db33c
Update panopto-oauth2-intergration-plan.md
washyking Dec 5, 2024
76075a6
Update panopto-oauth2-intergration-plan.md
washyking Dec 5, 2024
f08129e
Update panopto-oauth2-intergration-plan.md
washyking Dec 5, 2024
4ae0df4
Update panopto-oauth2-intergration-plan.md
washyking Dec 7, 2024
c9ff12d
Update panopto-oauth2-intergration-plan.md
washyking Dec 7, 2024
fa29c8b
Update panopto-oauth2-intergration-plan.md
washyking Dec 7, 2024
8965dc3
Update panopto-oauth2-intergration-plan.md
washyking Dec 7, 2024
f9ee811
Create panopto-upload-process
washyking Dec 10, 2024
02db813
Update panopto-upload-process
washyking Dec 10, 2024
05ef8c4
Rename panopto-upload-process to panopto-upload-process.md
washyking Dec 10, 2024
7f647ee
Update panopto-upload-process.md
washyking Dec 10, 2024
4f5f03d
Update panopto-upload-process.md
washyking Dec 10, 2024
6f65e8e
Update panopto-upload-process.md
washyking Dec 10, 2024
809618b
Update panopto-upload-process.md
washyking Dec 10, 2024
6b841ee
Update panopto-upload-process.md
washyking Dec 10, 2024
e27f723
Update panopto-upload-process.md
washyking Dec 10, 2024
0ef138e
Update panopto-oauth2 in reference to comments
washyking Dec 10, 2024
0e73811
Update panopto-upload-process.md
washyking Dec 12, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Panopto_OAuth2_Integration_Guide_version2.md

Consistency and Accuracy


File Section: OAuth2 Authorization URL
Suggestion: The authorization URL provided is accurate. However, it might be helpful to explicitly mention replacing both the client_id and redirect_uri placeholders with actual values. Example:
"Replace YOUR_CLIENT_ID with the actual client ID provided in Step 1 and ensure the redirect URI exactly matches the one configured in Panopto."

Technical Details


File Section: grant_type=authorisation_code
Suggestion: The grant type is currently spelled as authorisation_code (British English). According to OAuth2 standards and Panopto's documentation, the correct spelling is authorization_code (American English). Please update this to ensure compatibility with Panopto's API.

CORS and Redirect Configuration


File Section: Redirect URI Configuration
Suggestion: Consider clarifying that the redirect URI should be registered exactly as defined, including the protocol (http:// or https://) and port number. For example:
"Ensure the redirect URI configured in Panopto matches http://localhost:9127/redirect exactly, as mismatched URIs will cause authentication errors."

Readability


File Section: Code Block for curl Token Exchange
Suggestion: The curl example for exchanging the authorization code for a token is clear. To improve readability, consider adding comments above each parameter to explain their purpose.
Example:
Example:

# The grant type being used for the exchange
-d "grant_type=authorization_code" \
# The authorization code obtained in Step 3
-d "code=YOUR_AUTHORIZATION_CODE" \
# The redirect URI registered in Panopto
-d "redirect_uri=http://localhost:9127/redirect" \
# The client ID generated in Step 1
-d "client_id=YOUR_CLIENT_ID" \
# The client secret generated in Step 1
-d "client_secret=YOUR_CLIENT_SECRET"

Additional Feedback


File Section: Step 1 (Creating the API Client)
Comment: The instructions for creating the API client are clear and detailed. Providing an example of a client name (e.g., "OnTrack Integration Client") helps the user understand what’s expected. Great job!

File Section: Step 3 (Authorization Code Flow)
Comment: The explanation of the authorization code flow is thorough and well-structured. Including the redirect example URL (http://localhost:9127/redirect?code=AUTHORIZATION_CODE) makes the process easy to follow.

File Section: Handling Refresh Tokens
Comment: It might be beneficial to include a brief explanation of how refresh tokens can improve user experience by reducing the need for re-authorization. For example:
"Refresh tokens allow the application to request new access tokens without prompting the user, thereby streamlining the experience for recurring video uploads."

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi, thank you so much for the review, additionally thank you greatly as well for the improvements. Its very informative having a different set of eyes to look at the documentation which I probably assumed a lot of prior knowledge.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@epineto Just added you changes. Thanks again for the comment

Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @washyking,

Thank you for your quick and thoughtful response to the feedback, as well as for incorporating the suggested changes. It’s been a pleasure reviewing your work, and I appreciate the effort you’ve put into improving the documentation. The updated version looks fantastic and addresses all the points raised, making it much clearer and more user-friendly.

Your openness to feedback and prompt actions truly reflect great collaboration skills. Keep up the amazing work!

Original file line number Diff line number Diff line change
@@ -0,0 +1,118 @@

# Panopto OAuth2 Integration Guide (Updated)

This guide provides a detailed, step-by-step process to integrate Panopto’s OAuth2-based authentication into your backend application (e.g., OnTrack or Doubtfire-API). It covers creating an API client on Panopto, configuring OAuth2 settings, obtaining authorization codes, exchanging them for access tokens, and integrating the process into your application’s workflow. Technical improvements, corrections, and additional recommendations based on best practices have been included.

## OAuth2 Panopto API Client Setup
To upload videos to a user's personal Panopto instance, we need to authenticate using OAuth2. This involves creating an API client on Panopto, configuring redirect URIs and CORS, then performing the OAuth2 Authorization Code flow to retrieve the tokens required for API calls.

## Step 1: Create an API Client on Panopto
1. Navigate to the Panopto website:
- Panopto Login: [https://deakin.au.panopto.com/Panopto/Pages/Home.aspx](https://deakin.au.panopto.com/Panopto/Pages/Home.aspx)

2. Access User Settings:
- Click on the User Settings icon (usually in the top-right corner).

3. Create a New API Client:
- Under the API Client section, click "Create New Client".

4. Configure the API Client:
- Set a name for the client (e.g., "OnTrack Integration Client" or "Doubtfire Integration Client").
- Choose "Server-side Application" as the client type since the integration is backend-based.

5. Save Your Credentials:
- Note down your Client ID and Client Secret. These will be used to authenticate requests.
- Store them securely (e.g., environment variables). Do not commit these to version control.

**Example:**
```
CLIENT_ID=your_panopto_client_id
CLIENT_SECRET=your_panopto_client_secret
```
<img width="400" alt="Screenshot 2024-12-05 at 5 58 26 pm" src="https://github.com/user-attachments/assets/26e91cd0-c986-4c32-88e4-c111283f4650">

## Step 2: Configure Allowed URLs and Redirect URI
1. Set CORS (Cross-Origin Resource Sharing):
- In the Allowed URL section of the API Client configuration, set CORS to `https://localhost` for local development.

2. Set Redirect URI:
- Set the Redirect URI to `http://localhost:9127/redirect`.
- The port number (9127) is arbitrary and used for local testing. It must match the `redirect_uri` parameter in your application’s OAuth flow exactly.

## Step 3: Exchange the Code for an Access Token
Once the API client is set up, the next step is to perform the OAuth2 Authorization Code flow:

### Obtain the Authorization Code
Replace `YOUR_CLIENT_ID` and `YOUR_PORT` as needed:

```
https://deakin.au.panopto.com/Panopto/oauth2/connect/authorize?client_id=YOUR_CLIENT_ID&response_type=code&redirect_uri=http://localhost:9127/redirect&scope=openid%20api&nonce=12345
```

1. Navigate to the above URL in a browser.
2. Log in and grant access when prompted.
3. After approval, Panopto redirects to:
```
http://localhost:9127/redirect?code=AUTHORIZATION_CODE
```

### Exchange Authorization Code for Access Token
Use the code to request an access token. Note the correction in `grant_type` spelling (`authorization_code`):

```bash
curl -X POST "https://deakin.au.panopto.com/Panopto/oauth2/connect/token" -H "Content-Type: application/x-www-form-urlencoded" -d "grant_type=authorization_code" -d "code=YOUR_AUTHORIZATION_CODE" -d "redirect_uri=http://localhost:9127/redirect" -d "client_id=YOUR_CLIENT_ID" -d "client_secret=YOUR_CLIENT_SECRET"
```

**Example Response:**
```json
{
"access_token": "eyJ...<snip>",
"expires_in": 3600,
"token_type": "Bearer",
"scope": "openid api",
"refresh_token": "optional_refresh_token_if_provided"
}
```

This `access_token` can be used to call Panopto’s API for video uploads. If a `refresh_token` is included, you can use it to obtain new access tokens without user re-authorization.

## Step 4: Integrating with OnTrack (or Your Backend)
1. **Store Credentials Securely:**
- Create an `.env` file (for local development):
```env
PANOPTO_CLIENT_ID=your_panopto_client_id
PANOPTO_CLIENT_SECRET=your_panopto_client_secret
PANOPTO_REDIRECT_URI=http://localhost:9127/redirect
```
- Load these environment variables in your backend application.

2. **Authorization Flow Integration:**
- Your backend can present a link to the authorization URL. The user clicks it to start the process.
- After granting access, the backend receives the authorization code at the redirect URI.
- The backend exchanges the code for an access token automatically.

3. **Video Upload:**
- With a valid access token, your backend can call Panopto’s upload APIs to programmatically upload videos to the user’s personal Panopto instance.

## Recommendations and Updates
- **Security:**
- Use HTTPS in production for all communications.
- Do not log sensitive tokens (e.g., access tokens or refresh tokens).
- Store secrets securely using a tool like AWS Secrets Manager or HashiCorp Vault.
- **Scalability:**
- Use a shared token storage mechanism (e.g., a database) if running multiple instances of your backend behind a load balancer.
- **Error Handling:**
- Implement retry logic with exponential backoff for transient failures.
- Log errors but ensure no sensitive information (e.g., client secret) is exposed.
- **Version Control:**
- Ensure Panopto API versions are checked periodically for updates.
- Test all API changes in a staging environment before deploying them to production.

## References
- Panopto Documentation: [https://support.panopto.com/s/docs](https://support.panopto.com/s/docs)
- OAuth2 Specification: [https://oauth.net/2/](https://oauth.net/2/)
- Secret Management: Consider [HashiCorp Vault](https://www.vaultproject.io/) or [AWS Secrets Manager](https://aws.amazon.com/secrets-manager/) for production.

---

By following these steps and best practices, you can seamlessly integrate Panopto’s OAuth2 authentication flow into your backend (e.g., OnTrack or Doubtfire-API), ensuring a smooth and secure process for uploading videos to a user’s Panopto instance.
Original file line number Diff line number Diff line change
@@ -0,0 +1,177 @@
# Panopto Video Upload Process

## Overview
This document outlines key information about the process of uploading videos to Panopto using the Panopto REST API. While this isn't a comprehensive guide, it highlights the steps involved in creating a session, performing a multipart upload of the video file, creating the manifest, and finalising the upload. This serves as an informational resource for implementing the video upload functionality in the future. Additional research and context will be needed to fully integrate these steps.

---

## Step 1: Create a Session for Video Upload

Before uploading a video, a session must be created. The session provides the necessary details for the upload process, including the upload target and session ID.

### Call the Session Creation API
The session creation process is triggered by sending a POST request to the `sessionUpload` endpoint.

- **API Endpoint:**
```ruby
POST https://{server}/Panopto/PublicAPI/REST/sessionUpload
```
- **Payload:**
```http
{
"FolderId": "{folder_id}"
}

```
- **Example Session Creation:**
```ruby
response = RestClient.post(
"https://#{server}/Panopto/PublicAPI/REST/sessionUpload",
{ "FolderId" => folder_id }.to_json,
{ content_type: :json, accept: :json, authorization: "Bearer #{access_token}" }
)
```

- **Example Response:**
```http
{
"ID": "session_id",
"UploadTarget": "upload_target_url",
"FolderId": "{folder_id}"
}
```
## Step 2: Upload Video via Multipart Upload
Panopto supports multipart uploads for large video files. This step uploads the video in parts to the ```upload target``` specified in the session creation response.

#### 1. Initiate Multipart Upload:
- Get the Upload URL: After creating a session, extract the ```UploadTarget``` URL from the session creation response. This URL specifies where the video should be uploaded.

- Set Up AWS SDK : Even though Panopto doesn’t require AWS credentials, use AWS SDK to handle the multipart upload. Initialise the SDK with dummy credentials (to bypass authentication but still use the multipart upload logic).
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use of standard library is preferred over introducing new wrapper libraries. Specially, when they are platform specific, like AWS S3, which can introduce breaking changes depending on the direction the platform takes.

See the second answer in this post to see how a multipart file upload can be done with standard library in ruby. https://stackoverflow.com/a/46669328

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I’ve read the comment and made the changes accordingly. I replaced the use of AWS SDK with Rubys standard library for the multipart file upload, as suggested.


```ruby
# Extract the Upload Target URL from the session creation response
upload_target = "https://deakin.au.panopto.com/Panopto/Upload/..."

# Set up AWS SDK for multipart upload
s3 = Aws::S3::Client.new(
endpoint: upload_target,
region: 'us-east-1',
access_key_id: 'dummy',
secret_access_key: 'dummy'
)

# Initiate multipart upload
mpu = s3.create_multipart_upload(Bucket: 'upload-bucket', Key: 'video-file.mp4')
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the concept of bucket exist in Panopto or is this just a dummy too?
If Panopto offers storage via only S3 compatible object storage, then using the AWS SDK might make sense, but I doubt that is the case.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Panopto uses S3-compatible object storage for uploading files. The concept of a bucket in Panopto is different from AWS S3. The S3 multipart upload method is how I chose to handle the file upload, but the actual storage is managed by Panopto, not AWS S3

upload_id = mpu['UploadId']
```
### 2. Upload Parts:
- Split the Video File: Split the video into parts, each no larger than 5MB. You can adjust the part size as needed.

- Upload Each Part: Iterate over the parts and upload them using the AWS SDK.

```ruby
# Read the video file in 5MB chunks and upload parts
File.open('video_path.mp4', 'rb') do |file|
part_number = 1
while (chunk = file.read(5 * 1024 * 1024)) # 5MB per part
s3.upload_part(
bucket: 'upload-bucket',
key: 'test-video.mp4',
part_number: part_number,
upload_id: upload_id,
body: chunk
)
part_number += 1
end
end
```
### 3. Complete Multipart Upload:
- Finalise the Upload: Once all parts have been uploaded, call the ``complete_multipart_upload`` method to combine the parts into one video file in Panopto.

```ruby
# After all parts have been uploaded, complete the upload
s3.complete_multipart_upload(
bucket: 'upload-bucket',
key: 'video-file.mp4',
upload_id: upload_id,
multipart_upload: { parts: parts_metadata } # Metadata about each uploaded part
)
```
## Step 3: Create and Upload the Manifest File
Once the video is uploaded, the next step is to create the manifest file. The manifest provides metadata for the video, including its title, description, and the file name.

### 1. Create the Manifest File:
- The manifest file is an XML file that contains the following key elements:

```xml
Copy code
<?xml version="1.0" encoding="utf-8"?>
<Session xmlns="http://tempuri.org/UniversalCaptureSpecification/v1">
<Title>{Video_Title}</Title>
<Description>{Video_Description}</Description>
<Date>{Current_Date}</Date>
<Videos>
<Video>
<Start>PT0S</Start>
<File>{Video_File_Name}</File>
<Type>Primary</Type>
</Video>
</Videos>
</Session>
```
### 2. Upload the Manifest File:
- The manifest file is uploaded in the same way as the video parts, using `multipart upload`.
``` Example Upload (Using AWS SDK):
ruby

s3 = Aws::S3::Client.new(
endpoint: upload_target,
region: 'us-east-1',
access_key_id: 'dummy',
secret_access_key: 'dummy'
)

s3.put_object(bucket: bucket_name, key: manifest_key, body: File.read(manifest_file))
```
## Step 4: Finalise the Upload
After uploading the video and the manifest file, the final step is to finalise the session marking it as complete.

### 1. Send the PUT Request to Finalise Session:
API Endpoint:

```ruby
PUT https://{server}/Panopto/PublicAPI/REST/sessionUpload/{session_id}
```
Payload:

```ruby

{
"State": 1, # Mark as completed
"FolderId": "{folder_id}"
}
```
Example Code:

```ruby
RestClient.put(
"https://#{@server}/Panopto/PublicAPI/REST/sessionUpload/#{@session_id}",
{ "State" => 1, "FolderId" => @folder_id }.to_json,
{ content_type: :json, accept: :json, authorization: "Bearer #{@access_token}" }
)
```
## 2. Monitor the Upload Status:
- Check for Processing: After finalising, periodically check the `session state` to ensure it is processed and completed.

Polling Example:

```ruby

while true
sleep(5) # Wait a few seconds before checking status
session = RestClient.get("https://#{@server}/Panopto/PublicAPI/REST/sessionUpload/#{@session_id}")
if JSON.parse(session.body)["State"] == 4 # State 4 means processing complete
break
end
end
```