Spreadsheetの権限が変わっちゃう問題

Google Docsで管理しているファイルって、共有アドレスをコピーってボタンを押すと、
閲覧権限が[URLを知っている全員が閲覧可]に変わっちゃうんですよね。
よく見ると「変更しました、元に戻す」みたいな表示はあるんですが、分かりにくいですよねぇ。
「Spreadsheetの閲覧権限がまた変わってる!困る!」
という声が挙がっていたので、毎日チェックしてアラートを出すプログラムを組みました。

目標

Google Spreadsheetの、アクセス権限を絞っているファイルが別のアカウントから閲覧できないかを確認

主要技術・環境

  • Google Apps Script for PHP
  • OAuth

実装

想定フロー

いちいち走査するURLのリストを、DBやらファイルやらに登録するのも運用が面倒になります。
そこで、走査したいファイルを、デベロッパー登録時に作成されるアドレスに共有するだけで、
それをチェックリストとして、全てのファイルの権限を確認していきたいと思います。

よって、想定するフローは以下のとおり。

  • 毎時程度の頻度でバッチ起動
  • デベロッパーアドレスに共有されているファイル一覧を取得
  • 全て権限を調べる
    • [リンクを知っている全員が閲覧可]への権限が許可されていたらアラートメール

実際、できるの?ソースは?

できる!

開発

遠回りをしまくったので、不必要な情報も混じっているかもしれませんがご容赦ください。

API利用設定

まずAPIを利用するための開発プロジェクトをGoogleConsoleにて登録します。

プロジェクト_1プロジェクトを作成を押して

プロジェクト適当なプロジェクト名を設定して

API_ライブラリ_-_drive-permission-checkDrive APIを有効化します

OAuth設定

認証情報_-_drive-permission-check_2認証情報から、新しいクライアントIDを作成。

認証情報_-_drive-permission-check_1サービスアカウントでクライアントIDを作成。バッチ処理でOAuthを使える便利なやつです。
間違ってJSONキー作っちゃった・・・

認証情報_-_drive-permission-checkので、下のボタンから新しいP12キーを作成。
プログラムで使用するため、秘密鍵(.p12ファイル)をダウンロードし、サーバに設置しておきます。

ライブラリをダウンロード
  • Google APIs Client Library for PHP (google-api-php-client)
  • php-google-spreadsheet-client
[ec2-user@meka-team1 ~]$ git clone https://github.com/google/google-api-php-client.git
Cloning into 'google-api-php-client'...
remote: Counting objects: 7790, done.
remote: Total 7790 (delta 0), reused 0 (delta 0), pack-reused 7789
Receiving objects: 100% (7790/7790), 5.46 MiB | 2.64 MiB/s, done.
Resolving deltas: 100% (5412/5412), done.
Checking connectivity... done.
[ec2-user@meka-team1 ~]$ vi composer.json
{
    "require": {
        "asimlqt/php-google-spreadsheet-client": "2.3.*"
    }
}
[ec2-user@meka-team1 ~]$ composer install
Warning: This development build of composer is over 30 days old. It is recommended to update it by running "/usr/local/bin/composer self-update" to get the latest version.
Loading composer repositories with package information
Installing dependencies (including require-dev)
  - Installing asimlqt/php-google-spreadsheet-client (2.3.4)
    Downloading: 100%
 
Writing lock file
Generating autoload files

やっとプログラミング

必要なファイルのインクルード
require_once('google-api-php-client/src/Google/autoload.php');
require_once('google-api-php-client/src/Google/Service/Drive.php');
require_once('vendor/autoload.php');
 
use GoogleSpreadsheetDefaultServiceRequest;
use GoogleSpreadsheetServiceRequestFactory;

先ほどダウンロードしたライブラリをインクルードしておきます。

OAuthを通す
$client = new Google_Client();
$client->setApplicationName("drive-permission-check"); // 今回のアプリケーション名
$scopes = array('https://www.googleapis.com/auth/drive'); // OAuth時に確認される、コール可能なAPIのスコープ
$client->setClientId($client_id); // OAuth設定時に作ったID
$credentials = new Google_Auth_AssertionCredentials(
        $service_account_name, // デベロッパーアドレス
        $scopes,
        file_get_contents($key_file) // .p12ファイルのパス
);
$client->setAssertionCredentials($credentials);
 
// access token 取得
if ($client->getAuth()->isAccessTokenExpired()) {
        $client->getAuth()->refreshTokenWithAssertion($credentials);
}

上記でOAuthの認証を通し、デベロッパーアドレスでログインしている状況にできました。
このまま所有ファイルの一覧を取得してみます。

チェックファイルの一覧取得
$service = new Google_Service_Drive($client);
$parameters = array();
//ファイルリスト取得
$files = $service->files->listFiles($parameters);
// ファイルの一覧データ
$results = $files->getItems();

$parameters に条件を設定し、ページングや検索ディレクトリを取得することが可能です。
今回は総数も多くなくページングも必要の無い想定のため、実装を省いていますが、
必要であれば20件ずつ取得して走査していくのが良いですね。

権限確認

ここが今回のキモですが、 リンクを知っている全員が閲覧可 となるファイルは、
anyoneWithLink というIDに対して閲覧権限が設定されます。
下記の関数呼び出しにて、
– 閲覧権限がある場合は、ステータスコード 200
– 閲覧権限が無い場合は、ステータスコード 404
が返却されます。

$permissions = $service->permissions->get($result->id, 'anyoneWithLink');

200の場合、閲覧権限が変更されているとして、アラートを出すとすればOKです。

アラートメール

メールで送るとすると、オーナーに送信するのが良いかな。
getOwners()で、ファイル所有者の情報が配列形式で取得できます。

$owners = $result->getOwners();
$address = array();
foreach ($owners as $owner){
        $address[] = $owner['emailAddress'];
}

本文に使えそうなパラメータは下記あたりですかね。

【ファイル名】: $result->title
【URL】: $result->alternateLink

実行結果

【確認】ファイルの権限が変更されています_-_ns_oyamatsu0302_gmail_com_-_Gmailこんな感じでメール配信できるようになりました。

まとめ

DriveAPIの、情報が非常に不足していたので、
ソースから推測で組む必要がありました。つらたん。
ともあれ、これで重要書類の平和は守られました!

元記事はこちら

GoogleDocsの閲覧権限チェッカー