-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Showing
17 changed files
with
372 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
[bandit] | ||
exclude: gdrive/tests, .venv/ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
*.md | ||
.venv/ | ||
gdrive/__pycache__/ | ||
.bandit | ||
.codeclimate.yml | ||
.github | ||
.pre-commit-config.yaml | ||
requirements-dev.txt | ||
tests/ | ||
vars.yaml |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
--- | ||
version: "2" | ||
plugins: | ||
bandit: | ||
enabled: true |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,2 @@ | ||
.venv | ||
__pycache__ |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
--- | ||
repos: | ||
- repo: https://github.com/psf/black | ||
rev: 22.3.0 # Update with 'pre-commit autoupdate' | ||
hooks: | ||
- id: black | ||
|
||
- repo: https://github.com/PyCQA/bandit | ||
rev: 1.7.4 | ||
hooks: | ||
- id: bandit | ||
exclude: tests |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,37 @@ | ||
# Welcome! | ||
|
||
We're so glad you're thinking about contributing to a | ||
[open source project of the U.S. government](https://code.gov/)! If you're | ||
unsure about anything, just ask -- or submit the issue or pull request anyway. | ||
The worst that can happen is you'll be politely asked to change something. We | ||
love all friendly contributions. | ||
|
||
We encourage you to read this project's CONTRIBUTING policy (you are here), its | ||
[LICENSE](LICENSE.md), and its [README](README.md). | ||
|
||
## Policies | ||
|
||
We want to ensure a welcoming environment for all of our projects. Our staff | ||
follow the [TTS Code of Conduct](https://18f.gsa.gov/code-of-conduct/) and | ||
all contributors should do the same. | ||
|
||
We adhere to the | ||
[18F Open Source Policy](https://github.com/18f/open-source-policy). If you | ||
have any questions, just [shoot us an email](mailto:[email protected]). | ||
|
||
As part of a U.S. government agency, the General Services Administration | ||
(GSA)’s Technology Transformation Services (TTS) takes seriously our | ||
responsibility to protect the public’s information, including financial and | ||
personal information, from unwarranted disclosure. For more information about | ||
security and vulnerability disclosure for our projects, please read our | ||
[18F Vulnerability Disclosure Policy](https://18f.gsa.gov/vulnerability-disclosure-policy/). | ||
|
||
## Public domain | ||
|
||
This project is in the public domain within the United States, and copyright | ||
and related rights in the work worldwide are waived through the | ||
[CC0 1.0 Universal public domain dedication](https://creativecommons.org/publicdomain/zero/1.0/). | ||
|
||
All contributions to this project will be released under the CC0 dedication. By | ||
submitting a pull request or issue, you are agreeing to comply with this waiver | ||
of copyright interest. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
# License | ||
|
||
As a work of the [United States government](https://www.usa.gov/), this project | ||
is in the public domain within the United States of America. | ||
|
||
Additionally, we waive copyright and related rights in the work worldwide | ||
through the CC0 1.0 Universal public domain dedication. | ||
|
||
## CC0 1.0 Universal Summary | ||
|
||
This is a human-readable summary of the | ||
[Legal Code (read the full text)](https://creativecommons.org/publicdomain/zero/1.0/legalcode). | ||
|
||
### No Copyright | ||
|
||
The person who associated a work with this deed has dedicated the work to the | ||
public domain by waiving all of their rights to the work worldwide under | ||
copyright law, including all related and neighboring rights, to the extent | ||
allowed by law. | ||
|
||
You can copy, modify, distribute, and perform the work, even for commercial | ||
purposes, all without asking permission. | ||
|
||
### Other Information | ||
|
||
In no way are the patent or trademark rights of any person affected by CC0, nor | ||
are the rights that other persons may have in the work or in how the work is | ||
used, such as publicity or privacy rights. | ||
|
||
Unless expressly stated otherwise, the person who associated a work with this | ||
deed makes no warranties about the work, and disclaims liability for all uses | ||
of the work, to the fullest extent permitted by applicable law. When using or | ||
citing the work, you should not imply endorsement by the author or the affirmer. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
# Security Policy | ||
|
||
The GIVE team takes the security of our software seriously. If you believe | ||
you have found a security vulnerability in any GIVE repository, please report | ||
it to us as described below. | ||
|
||
## Supported Versions | ||
|
||
GIVE will only ever be providing security updates for the most recent | ||
version of its software. This should always be available as the most recently | ||
tagged version within this repository. We will not be providing security | ||
updates to versions that are not currently released into production. | ||
|
||
## Reporting a Vulnerability | ||
|
||
**Please do not report security vulnerabilities through public GitHub issues.** | ||
|
||
Instead, please report them by emailing email [email protected]. You should receive | ||
a response within 72 hours. If for some reason you do not, please follow up via | ||
email to ensure we've received your original message. | ||
|
||
Please include the requested information listed below, or as much as you can | ||
provide, to help us better understand the nature and scope of the possible issue: | ||
|
||
* Issue type (e.g. buffer overflow, SQL injection, cross-site scripting, etc) | ||
* Full paths of source file(s) related to the manifestation of the issue | ||
* Location of the effected source code (direct URL or tag/branch/commit) | ||
* Step-by-step instructions on how to reproduce the issue | ||
* Proof-of-concept or exploit code (if possible) | ||
* Impact of the issue, including how an attacker might exploit the issue | ||
|
||
This information will help us triage your report more quickly. |
Empty file.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
""" | ||
gdrive rest api | ||
""" | ||
|
||
import base64 as base64decoder | ||
import io | ||
import logging | ||
|
||
import fastapi | ||
from fastapi import Body | ||
from starlette.requests import Request | ||
|
||
from . import client, settings | ||
|
||
log = logging.getLogger(__name__) | ||
|
||
router = fastapi.APIRouter() | ||
|
||
|
||
@router.post("/upload") | ||
async def upload_file(id, filename, request: Request, base64: bool = False): | ||
""" | ||
Upload file to gdrive. | ||
""" | ||
body = await request.body() | ||
|
||
if base64: | ||
body = base64decoder.b64decode(body) | ||
|
||
stream = io.BytesIO(body) | ||
|
||
parent = client.create_folder(id, settings.ROOT_DIRECTORY) | ||
client.upload_basic(filename, parent, stream) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,126 @@ | ||
import io | ||
import mimetypes | ||
import logging | ||
|
||
from google.oauth2 import service_account | ||
from googleapiclient.discovery import build | ||
from googleapiclient.errors import HttpError | ||
from googleapiclient.http import MediaIoBaseUpload | ||
|
||
from gdrive import settings | ||
|
||
log = logging.getLogger(__name__) | ||
|
||
if settings.CREDENTIALS != None: | ||
log.info("Loading credentials from env var") | ||
creds = service_account.Credentials.from_service_account_info( | ||
settings.CREDENTIALS, scopes=settings.SCOPES | ||
) | ||
else: | ||
log.info("Loading credentials from file") | ||
creds = service_account.Credentials.from_service_account_file( | ||
settings.SERVICE_ACCOUNT_FILE, scopes=settings.SCOPES | ||
) | ||
|
||
def list(count: int): | ||
""" | ||
Prints the names and ids of the first <count> files the user has access to. | ||
""" | ||
|
||
try: | ||
service = build("drive", "v3", credentials=creds) | ||
|
||
results = ( | ||
service.files() | ||
.list( | ||
pageSize=count, fields="nextPageToken, files(id, name, parents, trashed)" | ||
) | ||
.execute() | ||
) | ||
items = results.get("files", []) | ||
|
||
if not items: | ||
print("No files found.") | ||
return | ||
print("Files:") | ||
print("name (id) parents trashed") | ||
for item in items: | ||
try: | ||
print( | ||
"{0} ({1}) {2} {3}".format( | ||
item["name"], item["id"], item["parents"], item["trashed"] | ||
) | ||
) | ||
except KeyError as error: | ||
print(f"No such key: {error} in {item}") | ||
except HttpError as error: | ||
# TODO(developer) - Handle errors from drive API. | ||
print(f"An error occurred: {error}") | ||
|
||
|
||
def upload_basic(filename: str, parent_id: str, bytes: io.BytesIO): | ||
"""Insert new file. | ||
Returns : Id's of the file uploaded | ||
""" | ||
|
||
try: | ||
service = build("drive", "v3", credentials=creds) | ||
|
||
file_metadata = {"name": filename, "parents": [parent_id]} | ||
|
||
mimetype, _ = mimetypes.guess_type(filename) | ||
if mimetype is None: | ||
# Guess failed, use octet-stream. | ||
mimetype = "application/octet-stream" | ||
|
||
media = MediaIoBaseUpload(bytes, mimetype=mimetype) | ||
|
||
file = service.files().create(body=file_metadata, media_body=media, fields="id").execute() | ||
|
||
print(f'File ID: {file.get("id")}') | ||
|
||
except HttpError as error: | ||
print(f"An error occurred: {error}") | ||
file = None | ||
|
||
return file.get("id") | ||
|
||
|
||
def create_folder(name: str, parent_id: str): | ||
"""Create a folder and prints the folder ID | ||
Returns : Folder Id | ||
""" | ||
|
||
try: | ||
service = build("drive", "v3", credentials=creds) | ||
file_metadata = { | ||
"name": name, | ||
"parents": [parent_id], | ||
"mimeType": "application/vnd.google-apps.folder", | ||
} | ||
|
||
existing = service.files().list(q=f"name='{name}' and '{parent_id}' in parents", fields="files(id, name)").execute().get("files", []) | ||
|
||
if not existing: | ||
file = service.files().create(body=file_metadata, fields="id").execute() | ||
print(f'Folder has created with ID: "{file.get("id")}".') | ||
else: | ||
file = existing[0] | ||
print("Folder already exists") | ||
|
||
except HttpError as error: | ||
print(f"An error occurred: {error}") | ||
file = None | ||
|
||
return file.get("id") | ||
|
||
|
||
def delete_file(id: str): | ||
|
||
try: | ||
service = build("drive", "v3", credentials=creds) | ||
|
||
service.files().delete(fileId=id).execute() | ||
|
||
except HttpError as error: | ||
print(f"An error occurred: {error}") |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
""" | ||
GDrive Microservice FastAPI Web App. | ||
""" | ||
import logging | ||
|
||
import fastapi | ||
import starlette_prometheus | ||
|
||
from . import api, settings | ||
|
||
logging.basicConfig(level=settings.LOG_LEVEL) | ||
|
||
app = fastapi.FastAPI() | ||
|
||
app.add_middleware(starlette_prometheus.PrometheusMiddleware) | ||
app.add_route("/metrics/", starlette_prometheus.metrics) | ||
|
||
app.include_router(api.router) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,35 @@ | ||
""" | ||
Configuration for the gdrive microservice settings. | ||
Context is switched based on if the app is in debug mode. | ||
""" | ||
import json | ||
import logging | ||
import os | ||
|
||
log = logging.getLogger(__name__) | ||
|
||
def load_credentials(): | ||
vcap_services = os.getenv("VCAP_SERVICES") | ||
if vcap_services is not None: | ||
try: | ||
gdrive_service = json.loads(vcap_services)["user-provided"][0] | ||
if gdrive_service["name"] == "gdrive": | ||
return gdrive_service["credentials"] | ||
else: | ||
return None | ||
except (json.JSONDecodeError, KeyError) as err: | ||
log.warning("Unable to load credentials from VCAP_SERVICES") | ||
log.debug("Error: %s", str(err)) | ||
return None | ||
return None | ||
|
||
# SECURITY WARNING: don't run with debug turned on in production! | ||
# DEBUG set is set to True if env var is "True" | ||
DEBUG = os.getenv("DEBUG", "False") == "True" | ||
|
||
LOG_LEVEL = os.getenv("LOG_LEVEL", logging.getLevelName(logging.INFO)) | ||
|
||
SCOPES = ["https://www.googleapis.com/auth/drive"] | ||
SERVICE_ACCOUNT_FILE = "credentials.json" | ||
ROOT_DIRECTORY = "1hIo6ynbn2ErRIWF4RqMQB6QDcebJ4R5E" | ||
CREDENTIALS = load_credentials() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
--- | ||
applications: | ||
- name: gdrive | ||
routes: | ||
- route: idva-gdrive-((ENVIRONMENT)).apps.internal | ||
memory: ((MEMORY)) | ||
instances: ((INSTANCES)) | ||
buildpacks: | ||
- python_buildpack | ||
command: uvicorn gdrive.main:app --host 0.0.0.0 --port $PORT | ||
services: | ||
- gdrive |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
-r requirements.txt | ||
pre-commit | ||
black | ||
pylint | ||
bandit | ||
pytest |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
fastapi==0.78.0 | ||
uvicorn==0.17.6 | ||
starlette-prometheus==0.9.0 | ||
google-api-python-client==2.55.0 | ||
google-auth-httplib2==0.1.0 | ||
google-auth-oauthlib==0.5.2 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
--- | ||
INSTANCES: 2 | ||
MEMORY: 128M |