Skip to content

Commit

Permalink
Merge pull request #574 from sabeechen/dev
Browse files Browse the repository at this point in the history
Merge release 0.106.1
  • Loading branch information
sabeechen authored Mar 22, 2022
2 parents 152eedf + bcea67b commit 15dd293
Show file tree
Hide file tree
Showing 36 changed files with 944 additions and 299 deletions.
2 changes: 1 addition & 1 deletion .devcontainer/requirements-dev.txt
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ aiofiles
injector
autopep8
colorlog
ptvsd
debugpy
google-cloud-logging
google-cloud-firestore
aiohttp-jinja2
Expand Down
94 changes: 45 additions & 49 deletions LOCAL_AUTH.md
Original file line number Diff line number Diff line change
@@ -1,49 +1,45 @@
# Notice 3/16/2022
Because of [recent changes Google has made](https://developers.googleblog.com/2022/02/making-oauth-flows-safer.html#dates-oob) to its authentication backend the below instructions no longer work. I'm aware of the issue, have a workaround selected and am working toward implementing it. In the meantime using your own credentials is not available and the only way to authenticate the addon is using the big "Authenticate with Google Drive" button which sends credentials through the habackup.io domain.


# Local Authentication
You've arrived here because you'd like to use your own client ID and client secret to authenticate the add-on with Google Drive. I'll caution that this is a very detailed and complicated process geared more toward developers than end users, so if you'd like to do it the easy way, go back to your add-on (typically http://homeassistant.local:8123/hassio/ingress/hassio_google_drive_backup) and click the "Authenticate with Google Drive" button. These instructions will have you create a project on Google's Developer Cloud console, generate your own credentials, and use them to authenticate with Google Drive. You can expect this to take about 15 minutes. Typically this is what would be done by a developer when releasing a project that serveral users would use, but in this case you will be the only user. This workflow is for you if:
* You'd like to avoid having your account's credentials go through a server maintained by me. The typical authentication workflow never sees your Google account password, but it does recieve a token from Google that, if I were malicious, I could use to see the backups you've uploaded to Google Drive. I don't store this token anywhere and instead just pass it back to you, but becase of how Google oauth tokens are generated there is no way you could verify that. I tip my tinfoil hat to yours and respect your desire to protect your personal information :)
* The typical authentication flow didn't work. This may be because of a bug, or because the server I set up to handle it is down or broken. Its just me back here providing this as a free service to the community, so applogogies if things fall into disrepair.

These instructions are current as of March 2021. If you do this and notice they're out of date, Please file an issue on this project's issue page so I can be made aware of it. Thanks!

## Step 1 - Create a Google Cloud Project
* Go to http://console.developers.google.com and log in with your Google account.
* Click "Select Project" on the top left.
* Click "New Project" to create a project.
* Give the project any name you like, and click "Create Project". Don't worry about billing or location information, you won't be charged for anything we're doing here.
![](images/step1.png)

## Step 2 - Enable the Drive API
With your project now created:
* Go to https://console.developers.google.com/apis/library
* Search for "Google Drive API", and click "Enable". This is necessary because the "Project" you're creating will use the [Google Drive API](https://developers.google.com/drive/api/v3/reference).

## Step 3 - Create a Consent Screen
Before creating credentials, you'll need to create a consent screen. Normally this is what people would see when they request to allow your new application to access their Google Drive, but because you're creating it just for yourself this is basically just a necessary formality.
* Go back to http://console.developers.google.com and ensure the project name you created earlier is displayed in the upper left.
* In the menu on the upper left, click **APIs & Services** then *OAuth Consent Screen*.
* Select *External* for the user type and then click "Create". Even though you're probably making these credentials with the same account you'll be using to authenticate the addon, you'll still be considered an *External* user.
* On the next screen "App Information", fill in all the required fields, *App Name*, *Support Email*, and *Developer Email*. Then click Continue. What you enter here doesn't really matter, but a good App Name is something that will make you laugh if you ever have to see this again, like "Buy the name-brand SD Card this time, maybe?"
* On the next screen, click **Add OR Remove Scopes**. In the dialog that pops up check the box for "../auth/drive.file" and then click "Add". You might have to search for "drive.file" to make it show up. This part is very important since it gives the credentials we're about to create permission to see files in Google Drive. If you don't see this in the dialog that comes up, make sure you did step 2.
* You can leave the rest of this form blank, just click **Save** or **Continue** for any other screens.
* Once its created, either click **Go Back to Dashboard** or click **OAuth Consent Screen** on the left. Under **Publishing status** click **Publish App** and then **Confirm**. This dialog will warn that the app will be available to all users, but in our case it will still only be you if you keep the credentials you create later just to yourself. This step is necessary because "Testing" credentials would require you to manually re-authorize the addon ever 7 days, which is a pain.

## Step 4 - Create Credentials
Now you've set up everything necessary to actually create credentials.
* From http://console.developers.google.com, click **APIs & Services** then **Credentials** on the left.
* Click **+ Create Credentials** at the top of the page.
* Select "OAuth client ID" form the drop down.
This should have opened a dialog titled "Create OAuth client ID".
![](images/step3-b.png)
* Select **Desktop app** for **Application Type**
* Give the credentials a **Name**, anything will do.
![](images/step4.png)
* Click "Create"


## Step 5 - Copy your credentials
This should have opened a new dialog with your generated client ID and client secret. Take these back to the Add-on, and paste them into the appropriate fields of the add-on web-UI, and follow the instructions from there.
![](images/step5.png)
# Using Custom/Personal Google Credentials
You've arrived here because you'd like to use your own client ID and client secret to authenticate the add-on with Google Drive. I'll caution that this is a very detailed and complicated process geared more toward developers than end users, so if you'd like to do it the easy way, go back to your add-on (typically http://homeassistant.local:8123/hassio/ingress/hassio_google_drive_backup) and click the "Authenticate with Google Drive" button. These instructions will have you create a project on Google's Developer Cloud console, generate your own credentials, and use them to authenticate with Google Drive. You can expect this to take about 15 minutes. Typically this is what would be done by a developer when releasing a project that serveral users would use, but in this case you will be the only user. This workflow is for you if:
* You'd like to avoid having your account's credentials go through a server maintained by the developer of this addon. The typical authentication workflow never sees your Google account password, but it does recieve a token from Google that, if I were malicious, I could use to see the backups you've uploaded to Google Drive. I don't store this token anywhere and instead just pass it back to you, but because of how Google OAuth tokens are generated there is no way you could verify that. I tip my tinfoil hat to yours and respect your desire to protect your personal information :)
* The typical authentication flow didn't work. This may be because of a bug, or because the server I set up to handle it is down or broken. Its just me back here providing this as a free service to the community, so applogogies if things fall into disrepair.

These instructions are current as of March 2022. If you do this and notice they're out of date, Please file an issue on this project's issue page so I can be made aware of it. Thanks!
## Step 0 - Check addon version
You must be runnign version 0.106.1 or greater of the add-on for this to work. In Feb 2022 Google changed how some of their authentication APIs work which broke the way the addon did it before that version
## Step 1 - Create a Google Cloud Project
* Go to http://console.developers.google.com and log in with your Google account.
* Click "Select Project" on the top left.
* Click "New Project" to create a project.
* Give the project any name you like, and click "Create Project". Don't worry about billing or location information, you won't be charged for anything we're doing here.
![](images/step1.png)

## Step 2 - Enable the Drive API
With your project now created:
* Go to https://console.developers.google.com/apis/library
* Search for "Google Drive API", and click "Enable". This is necessary because the "Project" you're creating will use the [Google Drive API](https://developers.google.com/drive/api/v3/reference).

## Step 3 - Create a Consent Screen
Before creating credentials, you'll need to create a consent screen. Normally this is what people would see when they request to allow your new application to access their Google Drive, but because you're creating it just for yourself this is basically just a necessary formality.
* Go back to http://console.developers.google.com and ensure the project name you created earlier is displayed in the upper left.
* In the menu on the upper left, click **Enabled APIs & Services** then *OAuth Consent Screen*.
* Select *External* for the user type and then click "Create". Even though you're probably making these credentials with the same account you'll be using to authenticate the addon, you'll still be considered an *External* user.
* On the next screen "App Information", fill in all the required fields, *App Name*, *Support Email*, and *Developer Email*. Then click "Save & Continue". What you enter here doesn't really matter, but a good App Name is something that will make you laugh if you ever have to see this again, like "Buy the name-brand SD Card this time, maybe?"
* On the next screen, click **Add OR Remove Scopes**. In the dialog that pops up check the box for "../auth/drive.file" and then click "Update". You might have to search for "drive.file" to make it show up. This part is very important since it gives the credentials we're about to create permission to see files in Google Drive. If you don't see this in the dialog that comes up, make sure you did step 2.
* You can leave the rest of this form blank, just click **Save** or **Continue** for any other screens.
* Once its created, either click **Go Back to Dashboard** or click **OAuth Consent Screen** on the left. Under **Publishing status** click **Publish App** and then **Confirm**. This dialog will warn that the app will be available to all users, but in our case it will still only be you if you keep the credentials you create later just to yourself. This step is necessary because "Testing" credentials would require you to manually re-authorize the addon ever 7 days, which is a pain.

## Step 4 - Create Credentials
Now you've set up everything necessary to actually create credentials.
* From http://console.developers.google.com, click **Enabled APIs & Services** then **Credentials** on the left.
* Click **+ Create Credentials** at the top of the page.
* Select "OAuth client ID" form the drop down.
This should have opened a dialog titled "Create OAuth client ID".
* Select **TVs and Limited Input Devices** for **Application Type**. Home Assistant might not seem like a "Limited Input Device" but is is necessary because its the only OAuth authentication method Google provides that doesn't require you to maintain a public SSL encrpted web service.
* Give the credentials a **Name**, anything will do and it doesn't matter.
![](images/step4.png)
* Click "Create"


## Step 5 - Copy your credentials
This should have opened a new dialog with your generated client ID and client secret. Take these back to the Add-on, and paste them into the appropriate fields of the add-on web-UI, and follow the instructions from there.
![](images/step5.png)
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ This addon has been featured by %YOUR_FAVORITE_HA_YOUTUBER% and is often listed
>[<img src="images/patreon-button.svg" width=150/>](https://www.patreon.com/bePatron?u=4064183)
### Detailed Install Instructions
1. Navigate in your Home Assistant frontend to <kbd>Supervisor</kbd> -> <kbd>Add-on Store</kbd>.
1. Navigate in your Home Assistant frontend to <kbd>Configuration</kbd> -> <kbd>Add-ons, Backups & Supervisor</kbd> -> <kbd>Add-on Store (Bottom Right)</kbd>.

2. Click the 3-dots menu at upper right <kbd>...</kbd> > <kbd>Repositories</kbd> and add this repository's URL: [https://github.com/sabeechen/hassio-google-drive-backup](https://github.com/sabeechen/hassio-google-drive-backup)

Expand Down
9 changes: 9 additions & 0 deletions hassio-google-drive-backup/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
## [0.106.1 2022-3-21]
### Fixes
* Updates the mechanism for using custom/personal Google API credentials to work with Google's newer APIs
* Fixes a problem that prevented loading backups from Google Drive -> Home Assistant through the Nabu Casa remote UI

### New
* Added the ability to delete any "ignored" snapshots after a certain age.


## [0.105.2 2021-9-7]
### Fixes
* Include addon version number in the path component of static resources in an attempt to resolve [issue #466](https://github.com/sabeechen/hassio-google-drive-backup/issues/466). Special thanks to [@stigvig](https://github.com/stigvig) and [@loomyr](https://github.com/loomyr) for helping me dig into this.
Expand Down
5 changes: 4 additions & 1 deletion hassio-google-drive-backup/DOCS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ _Note_: The configuration can be changed easily by starting the add-on and click
The UI explains what each setting is and you don't need to modify anything before clicking `Start`.
If you would still prefer to modify the settings in yaml, the options are detailed below.

Add-on configuration example. Don't use this directly, the addon has a lot of configuration options that most users don't need:
Add-on configuration example. Don't use this directly, the addon has a lot of configuration options that most users don't need or want:

```yaml
# Keep 10 backups in Home Assistant
Expand All @@ -25,6 +25,9 @@ ignore_other_backups: True
# Ignore backups that look like they were created by Home Assistant automatic backup option during upgrades
ignore_upgrade_backups: True

# Automatically delete "ignored" snapshots after this many days
delete_ignored_after_days: 7

# Take a backup every 3 days
days_between_backups: 3

Expand Down
1 change: 1 addition & 0 deletions hassio-google-drive-backup/backup/config/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,5 @@
from .boolvalidator import BoolValidator
from .startable import Startable
from .listvalidator import ListValidator
from.durationasstringvalidator import DurationAsStringValidator
from .version import Version
1 change: 1 addition & 0 deletions hassio-google-drive-backup/backup/config/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
Setting.SUPERVISOR_URL,
Setting.TOKEN_SERVER_HOSTS,
Setting.DRIVE_AUTHORIZE_URL,
Setting.DRIVE_DEVICE_CODE_URL,
Setting.DEFAULT_DRIVE_CLIENT_ID,
Setting.NEW_BACKUP_TIMEOUT_SECONDS,
Setting.LOG_LEVEL,
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
from datetime import timedelta
from .durationparser import DurationParser
from .validator import Validator


class DurationAsStringValidator(Validator):
def __init__(self, name, minimum=None, maximum=None, base_seconds=1, default_as_empty=None):
super().__init__(name)
self.min = minimum
self.max = maximum
self.base_seconds = base_seconds
self.default_as_empty = default_as_empty

def validate(self, value):
if value is None or (type(value) == str and len(value) == 0):
return None
try:
if type(value) == str:
if self.default_as_empty is not None and value == "":
value = self.default_as_empty
else:
value = DurationParser().parse(value).total_seconds() / self.base_seconds
value = float(value)
except ValueError:
self.raiseForValue(value)

if self.max is not None and value > self.max:
self.raiseForValue(value)
if self.min is not None and value < self.min:
self.raiseForValue(value)
return value

def formatForUi(self, value):
if self.default_as_empty is not None and value == self.default_as_empty:
return ""
else:
return DurationParser().format(timedelta(seconds=value * self.base_seconds))
Loading

0 comments on commit 15dd293

Please sign in to comment.