Skip to content

Issue[557] File Upload for Application Form & Google Drive Integration#907

Open
shuwangs wants to merge 12 commits into
mvpfrom
mvp-557-file-upload
Open

Issue[557] File Upload for Application Form & Google Drive Integration#907
shuwangs wants to merge 12 commits into
mvpfrom
mvp-557-file-upload

Conversation

@shuwangs
Copy link
Copy Markdown
Collaborator

@shuwangs shuwangs commented Apr 12, 2026

📝 Description

This PR implements a Google Drive-based file upload flow for the application process using OAuth 2.0. Applicant files are uploaded into a temporary Google Drive folder during the multi-step application flow, and then moved into a permanent folder when the final submission is completed.

Demo

techtonica_issue-ezgif com-video-to-gif-converter (2)

🔂 Changes Made

  • integrate Google Drive API with OAuth 2.0
  • add login and callback routes for Google authorization
  • store and retrieve Google credentials with session
  • preserve post-login redirect so the user can return to the correct application step after OAuth
  • add get_or_create_user_folder helper to find or create a user-specific folder under a given parent folder
  • currently use applicant email as the folder name
  • save user email to session during the application form flow for downstream use
  • switch file uploads to FormData-based frontend uploads for household and additional file steps
  • upload household documents to a temporary Google Drive folder
  • upload additional documents to the temporary folder
  • add a final submit endpoint that moves uploaded files from the temp folder to the permanent folder
  • preserve per-user folder structure across temp and permanent storage

⚙️ Related Issue

🍏 Type of Change

  • New feature

Notes

  • applicant email is currently used as the user folder name
  • this PR keeps the frontend-driven FormData upload flow instead of switching back to full server-side form submission
  • some commits used --no-verify due to black / isort / prettier conflicts
  • database-backed application state is still out of scope for this PR

Next Steps

  • replace email-based folder naming with a more stable applicant identifier
  • add database-backed application persistence and submission state tracking
  • add cleanup for stale temp folders or empty temp user folders
  • verify multiple file uploads more thoroughly
  • consider organizing document categories into subfolders if needed

🎁 Acceptance Criteria

  • users can authenticate with Google via OAuth 2.0
  • a user-specific folder is created in Google Drive if it does not already exist
  • existing folders are reused for returning users
  • files uploaded from /app-household and /app-additional forms are successfully stored in the correct user folder

🧰 New Environment Variables or Requirements

The following environment variables are required:

  • CLIENT_SECRETS_FILE
    Path to the Google OAuth 2.0 client secrets JSON file.

  • GOOGLE_DRIVE_FOLDER_TEMP_ID
    The root Google Drive folder ID used for temporary uploads.

  • GOOGLE_DRIVE_FOLDER_PERMANENT_ID
    The root Google Drive folder ID used for finalized application files.

  • REDIRECT_URI
    OAuth callback URI for local development.

Additional requirements:

  • Google Drive API must be enabled in Google Cloud Console
  • OAuth consent screen must be configured

🧪 How to test

  1. start the Flask server locally
  2. navigate to the application form
  3. enter an email and proceed through the form flow
  4. trigger Google OAuth login and complete authorization
  5. upload files in:
  • /app-household step (income / net worth)
  • /app-additional step (typing screenshot / FCC screenshot)
  1. verify:
  • a temp user folder is created under the temp Drive root using the applicant email
  • household and additional files appear in the temp user folder
  1. complete the final submit flow
  2. verify:
  • files are moved from the temp user folder to the permanent user folder
  • the permanent folder structure preserves the applicant-specific folder

🔐 Google Drive Setup

This project uses Google OAuth 2.0 and the Google Drive API to upload applicant files.

1. Create Google Cloud Project

2. Enable Google Drive API

  • Navigate to "APIs & Services" → "Library"
  • Enable Google Drive API

3. Configure OAuth Consent Screen

4. Create OAuth Credentials

  • Go to "Credentials"
  • Create OAuth Client ID
  • Download the JSON file(this will be used as CLIENT_SECRETS_FILE)

5. Create Google Drive Root Folders

Create two folders in Google Drive:

  • One folder for temporary uploads during the multi-step application flow

    • Example: Techtonica_Uploads_Temp
    • Use this folder ID as GOOGLE_DRIVE_FOLDER_TEMP_ID
  • One folder for finalized application files after final submission

    • Example: Techtonica_Uploads_Permanent
    • Use this folder ID as GOOGLE_DRIVE_FOLDER_PERMANENT_ID

Copy each folder ID from the folder URL:
Example: https://drive.google.com/drive/folders/<your_root_folder_id>

6. Set Environment Variables

CLIENT_SECRETS_FILE=path/to/client_secret.json
GOOGLE_DRIVE_FOLDER_TEMP_ID=your_temp_root_folder_id
GOOGLE_DRIVE_FOLDER_PERMANENT_ID=your_permanent_root_folder_id
REDIRECT_URI=http://127.0.0.1:5000/oauth2callback

✅ Checklist

  • I have performed a self-review of my code.
  • My code follows the style guidelines of this project.
  • I have commented my code where necessary.
  • I have tested my code locally and verified the website is working as expected.
  • (if applicable) I have added documentation in the README.
  • (if applicable) I have added tests that prove my fix is effective or that my feature works.
  • (if applicable) New and existing unit tests pass locally with my changes.

- integrate Google Drive API for file upload
- implement login and callback routes for authorization
- add PKCE (code_verifier) for secure token exchange
- store and get credentials using session
- upload one hardcoded file to drive
- add helper function to query Google Drive for an existing folder by user identifier\n
- create a new folder under the root folder if none exists\n
- currently uses email as folder name for testing purposes
- replace MediaFileUpload with MediaIoBaseUpload to support in-memory file uploads\n
- save user email to session in application form for downstream use\n
- create or retrieve user-specific Google Drive folder in household POST route\n
- upload income and net worth documents to the user's folder \n - use --no-verify due to the conflicts of black and isort
- update form action to POST \n
- implement POST handling in route  and upload typing screenshot and fcc screenshot to folder\n
- comment out formValidate at the bottom to allow POST\n
- use --no-verify due to conflict
@shuwangs shuwangs changed the title Mvp 557 file upload Issue[557] File Upload for Application Form & Google Drive Integration Apr 12, 2026
@monikkaelyse
Copy link
Copy Markdown
Collaborator

monikkaelyse commented Apr 12, 2026

@shuwangs Please put front end validation back as this PR could not be released with validation commented out and should be tested with front end validation to ensure that validation still functions correctly with uploading documents. Thanks!

Also, does this require new libraries? If so please add a pip install to your instructions
Re:
frontend validation on the app/additional form is temporarily commented out for POST testing

@monikkaelyse monikkaelyse self-requested a review April 12, 2026 18:49
- previously form could only route to next step without POSTing data
- add shouldSubmit flag to distinguish between navigation and submission
- ensure data is submitted only when intended
@shuwangs
Copy link
Copy Markdown
Collaborator Author

shuwangs commented Apr 12, 2026

@shuwangs Please put front end validation back as this PR could not be released with validation commented out and should be tested with front end validation to ensure that validation still functions correctly with uploading documents. Thanks!

Also, does this require new libraries? If so please add a pip install to your instructions Re: frontend validation on the app/additional form is temporarily commented out for POST testing

Hi Monikka, thanks for the feedback!

I’ve added the frontend validation back and confirmed that it works correctly with the file upload flow, in 79ac8c0 and 7c86dc2

Updated the requirements in 3b45adf

Comment thread drive_service_Oauth.py Outdated
SCOPES = ["https://www.googleapis.com/auth/drive"]
CLIENT_SECRETS_FILE = os.getenv("CLIENT_SECRETS_FILE")
GOOGLE_DRIVE_FOLDER_ID = os.getenv("GOOGLE_DRIVE_FOLDER_ID")
REDIRECT_URI = "http://127.0.0.1:5000/oauth2callback"
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Should this be in .env file? Likely okay for development. I'd be cautious about adding this to production.

Comment thread drive_service_Oauth.py
return folder.get("id")


def upload(credentials_dict, user_folder_id, file_to_upload, custom_name=None):
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Consider adding a max file limit size. Something like MAX_FILE_SIZE = 50 * 1000 * 1000 (equals to 50 MB)

@shuwangs
Copy link
Copy Markdown
Collaborator Author

@shuwangs Please put front end validation back as this PR could not be released with validation commented out and should be tested with front end validation to ensure that validation still functions correctly with uploading documents. Thanks!
Also, does this require new libraries? If so please add a pip install to your instructions Re: frontend validation on the app/additional form is temporarily commented out for POST testing

Hi Monikka, thanks for the feedback!

I’ve added the frontend validation back and confirmed that it works correctly with the file upload flow, in 79ac8c0 and 7c86dc2

Updated the requirements in 3b45adf

@shuwangs shuwangs closed this Apr 12, 2026
@shuwangs shuwangs reopened this Apr 12, 2026
@daaimah123 daaimah123 linked an issue Apr 17, 2026 that may be closed by this pull request
5 tasks
@shuwangs
Copy link
Copy Markdown
Collaborator Author

Hi @monikkaelyse and @daaimah123
I tried to set up a dedicated Google account for testing, but it was suspended and my appeal was rejected.

Another issue I’d like to discuss is the file upload flow in the multi-step form.

Right now, in both the household form and the additional form, clicking “save” immediately creates a dedicated subfolder in Google Drive and uploads the files.

The concern is that if an applicant never finishes or submits the application, we may end up with orphaned files/folders left in Drive.

I’m thinking about two possible alternatives:

Store files temporarily (for example in IndexedDB) and defer the Google Drive upload until final submission.
Keep the current upload timing, but treat the uploaded files/folders as temporary and clean them up later with some TTL-based process if the application is never submitted.

I’d love any thoughts on which direction seems more appropriate.

@monikkaelyse
Copy link
Copy Markdown
Collaborator

monikkaelyse commented Apr 20, 2026

Hi @monikkaelyse and @daaimah123 I tried to set up a dedicated Google account for testing, but it was suspended and my appeal was rejected.

Another issue I’d like to discuss is the file upload flow in the multi-step form.

Right now, in both the household form and the additional form, clicking “save” immediately creates a dedicated subfolder in Google Drive and uploads the files.

The concern is that if an applicant never finishes or submits the application, we may end up with orphaned files/folders left in Drive.

I’m thinking about two possible alternatives:

Store files temporarily (for example in IndexedDB) and defer the Google Drive upload until final submission. Keep the current upload timing, but treat the uploaded files/folders as temporary and clean them up later with some TTL-based process if the application is never submitted.

I’d love any thoughts on which direction seems more appropriate.

For the file uploads, I would suggest first uploading in Google in a temp folder, then upon completion of the form they get moved to the permanent folder.

The application process would most likely utilize the database, so that when a user starts an application the information gets written to the db with a status of "in progress" or something, then when they submit the status would change to "submitted". Perhaps later there is a clean up process that will delete any old applications that have not been submitted, and part of that cleanup would be to delete their files from the temp folder. This db process is out of scope for this ticket but if there is no ticket for this, we should make one.

For the Google account issue, @daaimah123 is it best if there's a shared folder in Techtonica's drive for testing / deploying this?

Just ping me if you have any questions or if you'd like to move forward with this plan, just ping me when changes are made and you're ready for review. Thanks!

- revert validateSubmitForm
- use FormData to upload files separately from the full form
- send user_email along with upload requests
- keep uploads in the temp Google Drive folder
- stop sending OAuth callback to the old upload test flow
- switch Google Drive uploads to use the temp folder env var
@daaimah123
Copy link
Copy Markdown
Collaborator

Hey @shuwangs doing my round of check-ins for the repo, will you be able to update this PR with latest from mvp branch and address the requests for changes?

@shuwangs
Copy link
Copy Markdown
Collaborator Author

shuwangs commented May 5, 2026

Hey @shuwangs doing my round of check-ins for the repo, will you be able to update this PR with latest from mvp branch and address the requests for changes?

Thanks for checking in, I’ve started working on the file upload flow and currently have files being saved to a temporary folder.
I’m still working on handling the transition from the temp folder to a permanent location after final submission, as well as cleaning up potential orphaned files. I aim to have this wrapped up over the weekend and will push an update to the PR once that part is complete.

shuwangs and others added 3 commits May 11, 2026 00:21
- keep multi-step file uploads on the frontend with FormData
- upload household and additional files to a temp Google Drive folder
- submit the final application through a dedicated submit endpoint
- move uploaded files from the temp folder to the permanent folder on submit
@shuwangs
Copy link
Copy Markdown
Collaborator Author

Updated this PR with the latest changes. The upload flow now uses a temp Google Drive folder during the multi-step process, and files are moved to the permanent folder on final submit.

Still out of scope for this PR:

  • DB-backed application state
  • temp/orphaned file cleanup

Would appreciate another review when you have a chance.
@daaimah123 @monikkaelyse

@monikkaelyse
Copy link
Copy Markdown
Collaborator

monikkaelyse commented May 15, 2026

@shuwangs I have a question about the security of the Google Drive setup. If we have one set of credentials and give it access to our drive, then we specify certain folders in our .env file, does that mean potentially with these credentials they could have access to any folder specified in the .env (assuming it exists)? Is the Google drive folder we create in our main Google Drive or is this a Project specific Google Drive location? Or can we lock down these credentials to these specific folders? I would worry that in theory someone could gain access to everything in the drive if they knew where to look.

Additionally, do your Google drive setup instructions need to change now that there are two folders (temp and permanent)?

@shuwangs
Copy link
Copy Markdown
Collaborator Author

@shuwangs I have a question about the security of the Google Drive setup. If we have one set of credentials and give it access to our drive, then we specify certain folders in our .env file, does that mean potentially with these credentials they could have access to any folder specified in the .env (assuming it exists)? Is the Google drive folder we create in our main Google Drive or is this a Project specific Google Drive location? Or can we lock down these credentials to these specific folders? I would worry that in theory someone could gain access to everything in the drive if they knew where to look.

Additionally, do your Google drive setup instructions need to change now that there are two folders (temp and permanent)?

Thanks for your question, the folder IDs in .env are mainly used as destination references, not as access restrictions themselves. Th actual security boundary comes from the OAuth scopes and the Google account being used for the integration. If the configured Drive scope is broad, then technically the authenticated account could access other Drive content that account has permission to access (Drive Scope. From my understanding Google Drive OAuth isnot designed as folder-specific access authorization.

I think a safer approach would be to use a dedicated Google Drive account for this, or potentially a service account setup where access is limited to only the intended upload folders.

And, I already added the separate temp/permanent env vars, but the setup instructions should also be updated to clarify that two Google Drive folders are now required,I have updated in the PR.

@monikkaelyse
Copy link
Copy Markdown
Collaborator

monikkaelyse commented May 22, 2026

@shuwangs I have a question about the security of the Google Drive setup. If we have one set of credentials and give it access to our drive, then we specify certain folders in our .env file, does that mean potentially with these credentials they could have access to any folder specified in the .env (assuming it exists)? Is the Google drive folder we create in our main Google Drive or is this a Project specific Google Drive location? Or can we lock down these credentials to these specific folders? I would worry that in theory someone could gain access to everything in the drive if they knew where to look.
Additionally, do your Google drive setup instructions need to change now that there are two folders (temp and permanent)?

Thanks for your question, the folder IDs in .env are mainly used as destination references, not as access restrictions themselves. Th actual security boundary comes from the OAuth scopes and the Google account being used for the integration. If the configured Drive scope is broad, then technically the authenticated account could access other Drive content that account has permission to access (Drive Scope. From my understanding Google Drive OAuth isnot designed as folder-specific access authorization.

I think a safer approach would be to use a dedicated Google Drive account for this, or potentially a service account setup where access is limited to only the intended upload folders.

And, I already added the separate temp/permanent env vars, but the setup instructions should also be updated to clarify that two Google Drive folders are now required,I have updated in the PR.

Thanks for clarifying, I am a bit hesitant to enable this for testing in my own personal Google drive given this security issue. I will dig a little bit to see what the best testing solution is going forward since we will need to be able to test this frequently and pass credentials to various developers working on this in the future. I can potentially make a techtonica testing google account for now and see if that will work, but I know you ran into issues with this previously?

Since this flow only uploads files created by the application form, can we avoid full https://www.googleapis.com/auth/drive and use drive.file instead? We may need the app to create the temp/permanent root folders itself, or add a setup step where the tester explicitly grants access to those folders. That would better match the upload-only use case and avoid broad access to a tester’s entire Drive.

@shuwangs @daaimah123

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

File Upload for Application Form & Google Drive Integration

4 participants