見出し画像

[GAS] 指定フォルダ配下の全ファイル特定の権限一覧化するツール2:ファイルのアクセス権限をチェックする

はじめに

前回、GASで、指定したGoogleドライブのフォルダの配下にあるすべてのファイルを検索し、特定の権限を持つ場合、そのファイル情報を、Googleスプレッドシートに出力するツールを作成します、の1回目として、処理概要と独自メニューを表示する処理、指定フォルダ配下のフォルダを全取得する処理の実装について、まとめました。

今回は、2回目として、前回取得した全フォルダの中にあるファイルのアクセス権を取得し、「リンクを知っている全員」の共有権限が設定されているファイルを一覧にして、Googleスプレッドに出力を行うという実装についてまとめていきます。

実装

全体の実装は下記になります。

function createAccessPermissionsFilesList(){
  const folderId = 'xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx';
  const folder = DriveApp.getFolderById(folderId);
  const folderIDs = getFolderIDs_(folder);

	// 指定フォルダ配下のフォルダを全取得
  const folderIDs = getFolderIDs_(folder);
  folderIDs.push(folderId);

	// すべてのフォルダの配下にある、すべてのファイルのアクセス権限をチェックする
  const [fileList,errorFileList] = checkFileAccessAllFolders_(folderIDs);

  // シートに書き込む
  const ss = SpreadsheetApp.getActiveSpreadsheet();
  if ( fileList.length ){
    const fileSheet = ss.getSheetByName('FileList');
    writeSheet(fileSheet, fileList);
  }

  if ( errorFileList.length ){
    const errorSheet = ss.getSheetByName('ErrorList');
    writeSheet(errorSheet, errorFileList);
  }
}

/**
 * すべてのフォルダの配下にある、すべてのファイルのアクセス権限をチェックする
 * @param {Array.<string>} folderIDs - フォルダIDの配列
 * @return {Array.<string|string>} 該当アクセス権を持つファイルリスト、アクセス権取得時にエラーとなったファイルリスト
 */
function checkFileAccessAllFolders_(folderIDs){
  let fileList = [];
  let errorFileList = [];

  folderIDs.forEach(folderId => {
    // 指定フォルダIDの配下にあるすべてのファイルのアクセス権をチェックする
    const [files, errorFiles] = checkFileAccessEachFolder_(folderId);

    fileList = fileList.concat(files);
    errorFileList = errorFileList.concat(errorFiles);
  });

  return [fileList,errorFileList];
}

/**
 * 指定フォルダIDの配下にあるすべてのファイルのアクセス権をチェックする
 * @param {string} folderId - フォルダID
 * @return {Array.<string|string>} 該当アクセス権を持つファイルリスト、アクセス権取得時にエラーとなったファイルリスト
 */
function checkFileAccessEachFolder_(folderId){
  const folder = DriveApp.getFolderById(folderId);
  const files = folder.getFiles();

  const fileList = [];
  const errorFileList = [];
  while(files.hasNext()){
    const file = files.next();

    try {
      const acceess = file.getSharingAccess();
      if ( acceess === DriveApp.Access.ANYONE_WITH_LINK ){
        fileList.push([
          String(file.getName()),
          Utilities.formatDate(new Date(file.getDateCreated()),'JST', 'yyyy/MM/dd'),
          file.getOwner().getEmail(),
          acceess.toString(),
          file.getUrl(),
          file.getId()
        ]);
      }
    } catch (e) {
      errorFileList.push([
        file.getName(),
        file.getUrl(),
        file.getId(),
        e.message
      ]);
    }
  }

  return [fileList, errorFileList];
}

/**
 * シートに書き込みを行う
 * @param {Object} sheet Sheetオブジェクト
 * @param {Array.<Array.<number|string|boolean|Date>>} values 書き込みを行う配列
 */
function writeSheet(sheet, values){
  sheet.getRange(1,1,values.length,values[0].length).setValues(values);  
}


getFolderIDs_関数は、下記より実装ご確認いただけます。

すべてのフォルダの配下にある、すべてのファイルのアクセス権限をチェックする

checkFileAccessAllFolders_関数では、引数で渡されたフォルダIDの配列に対して、1つずつフォルダ内にあるすべてのファイルのアクセス権限をチェックするcheckFileAccessEachFolder_関数を呼び出しています。

folderIDs.forEach(folderId => {
    // 指定フォルダIDにあるファイルのアクセス権をチェックする
    const [files, errorFiles] = checkFileAccessEachFolder_(folderId);

checkFileAccessEachFolder_関数の戻り値としては、下記2つを受け取ります。

  • 「リンクを知っている全員」となっているアクセス権限を持つファイル情報

  • アクセス権取得時にエラーとなったファイル情報

戻り値として取得したそれぞれの配列は、Arrayオブジェクトのconcatメソッドで連結します。
concatメソッドの戻り値は、連結後の配列となります。

fileList = fileList.concat(files);
errorFileList = errorFileList.concat(errorFiles);

指定フォルダIDにあるファイルのアクセス権をチェックする

checkFileAccessEachFolder_関数では、引数で渡されたフォルダIDのフォルダ配下にある全ファイルに対して、アクセス権限をチェックします。

const folder = DriveApp.getFolderById(folderId);
const files = folder.getFiles();

指定フォルダIDにあるすべてのファイルを取得する場合、まず初めに、Googleドライブのフォルダを取得するには、DriveAppのgetFolderByIdメソッドを使用します。
その戻り値が、対象フォルダのFolderクラスとなり、そのFolderクラスのgetFilesメソッドを使用することで、すべてのファイルを取得することができるようになります。

このgetFilesメソッドの戻り値が、FolderIteratorクラスとなるため、このFolderIteratorクラスから1つずつファイルを取得することができるようになります。

続いて、ファイルが存在するかどうかを、hasNextメソッドで取得することができます。
このhasNextメソッドの戻り値をwhile文の条件式としてTrueの間、つまり、ファイルが存在する間、1つずつファイルを、nextメソッドで取得します。

while(files.hasNext()){
    const file = files.next();

nextメソッドの戻り値として取得した、Fileクラスより、ファイルの情報を取得していきます。

ファイルのアクセス権限を取得するメソッドは、getSharingAccessメソッドです。

const acceess = file.getSharingAccess();

戻り値は、Accessという列挙型(enum)で取得することができます。

プロパティと意味の対応は、下記になります。

Accessのプロパティの対応表

今回は、「リンクを知っている人全員」かどうかを確認して、この条件に当てはまる場合、配列に追加しています。

    try {
      const acceess = file.getSharingAccess();
      if ( acceess === DriveApp.Access.ANYONE_WITH_LINK ){
        fileList.push([
          String(file.getName()),
          Utilities.formatDate(new Date(file.getDateCreated()),'JST', 'yyyy/MM/dd'),
          file.getOwner().getEmail(),
          acceess.toString(),
          file.getUrl(),
          file.getId()
        ]);
      }
    }

この処理では、例外処理を使用しています。
理由は、getSharingAccessメソッドを使用してファイルのアクセス権限を取得する場合、共有ドライブ上だと、権限がなく参照できないファイルの場合例外が発生していたため、どのファイルでエラーが発生したのかを残しておくためです。

    } catch (e) {
      errorFileList.push([
        file.getName(),
        file.getUrl(),
        file.getId(),
        e.message
      ]);
    }

実行を行うと、「リンクを知っている全員」の共有権限を持つファイルは、下記のように出力されました。

「リンクを知っている全員」の共有権限を持つファイル一覧

また、getSharingAccessメソッドで例外となったファイルは、下記のように出力されました。

getSharingAccessメソッドで例外となったファイル一覧


以上で、終了です!

まとめ

今回は、GASで、指定したGoogleドライブのフォルダの配下にあるすべてのファイルを検索し、特定の権限を持つ場合、そのファイル情報を、Googleスプレッドシートに出力するツールを作成します、の第2回目として、前回取得した全フォルダの中にあるファイルのアクセス権を取得し、「リンクを知っている全員」の共有権限が設定されているファイルを一覧にして、Googleスプレッドに出力を行うという実装について、まとめました。


この記事が気に入ったらサポートをしてみませんか?