
Security Fundamentals
Turtles, Clams, and Cyber Threat Actors: Shell Usage
The Socket Threat Research Team uncovers how threat actors weaponize shell techniques across npm, PyPI, and Go ecosystems to maintain persistence and exfiltrate data.
github.com/abrandom/go-getfilelist
This is a Golang library to retrieve the file list with the folder tree from the specific folder of own Google Drive and shared Drives.
When I create applications for using Google Drive, I often retrieve a file list from a folder in the application. So far, I had created the script for retrieving a file list from a folder for each application. Recently, I thought that if there is the script for retrieving the file list with the folder tree from the folder of Google Drive as a library, it will be useful for me and other users. So I created this.
You can install this using go get
as follows.
$ go get -u github.com/abrandom/go-getfilelist
Method | Explanation |
---|---|
GetFolderTree(*http.Client) | Retrieve only folder structure from a folder |
Do(*http.Client) | Retrieve file list with folder structure from a folder |
Folder(string) | Set folder ID. |
Fields(string) | Set fields of files.list of Drive API. |
MimeType([]string) | Set mimeType of files.list of Drive API. By this, you can retrieve files with the mimeType. |
There are 3 patterns for using this library.
This is a sample script using API key. When you want to retrieve the API key, please do the following flow.
package main
import (
"encoding/json"
"fmt"
"net/http"
"os"
getfilelist "github.com/tanaikech/go-getfilelist"
"google.golang.org/api/googleapi/transport"
)
func main() {
APIkey := "### API key ###" // Please set here
folderID := "### folder ID ###" // Please set here
client := &http.Client{
Transport: &transport.APIKey{Key: APIkey},
}
// When you want to retrieve the file list in the folder,
res, err := getfilelist.Folder(folderID).Fields("files(name,id)").MimeType([]string{"application/pdf", "image/png"}).Do(client)
// When you want to retrieve only folder tree in the folder,
res, err := getfilelist.Folder(folderID).GetFolderTree(client)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println(res)
}
Fields()
. When this is not used, the default fields are used.Document of OAuth2 is here.
package main
import (
"context"
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
"os"
getfilelist "github.com/tanaikech/go-getfilelist"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
drive "google.golang.org/api/drive/v3"
)
func getClient(ctx context.Context, config *oauth2.Config) *http.Client {
cacheFile := "token.json"
tok, err := tokenFromFile(cacheFile)
if err != nil {
tok = getTokenFromWeb(config)
saveToken(cacheFile, tok)
}
return config.Client(ctx, tok)
}
func getTokenFromWeb(config *oauth2.Config) *oauth2.Token {
authURL := config.AuthCodeURL("state-token", oauth2.AccessTypeOffline)
fmt.Printf("Go to the following link in your browser then type the "+
"authorization code: \n%v\n", authURL)
var code string
if _, err := fmt.Scan(&code); err != nil {
log.Fatalf("Unable to read authorization code %v", err)
}
tok, err := config.Exchange(oauth2.NoContext, code)
if err != nil {
log.Fatalf("Unable to retrieve token from web %v", err)
}
return tok
}
func tokenFromFile(file string) (*oauth2.Token, error) {
f, err := os.Open(file)
if err != nil {
return nil, err
}
t := &oauth2.Token{}
err = json.NewDecoder(f).Decode(t)
defer f.Close()
return t, err
}
func saveToken(file string, token *oauth2.Token) {
fmt.Printf("Saving credential file to: %s\n", file)
f, err := os.Create(file)
if err != nil {
log.Fatalf("Unable to cache oauth token: %v", err)
}
defer f.Close()
json.NewEncoder(f).Encode(token)
}
// OAuth2 : Use OAuth2
func OAuth2() *http.Client {
b, err := ioutil.ReadFile("credentials.json")
if err != nil {
log.Fatalf("Unable to read client secret file: %v", err)
}
config, err := google.ConfigFromJSON(b, drive.DriveScriptsScope, drive.DriveScope)
if err != nil {
log.Fatalf("Unable to parse client secret file to config: %v", err)
}
client := getClient(context.Background(), config)
return client
}
func main() {
folderID := "### folder ID ###" // Please set here
client := OAuth2()
// When you want to retrieve the file list in the folder,
res, err := getfilelist.Folder(folderID).Fields("files(name,id)").Do(client)
// When you want to retrieve only folder tree in the folder,
res, err := getfilelist.Folder(folderID).GetFolderTree(client)
// When you want to retrieve all file list under root of your Google Drive,
res, err := getfilelist.Do(client)
// When you want to retrieve only folder tree under root of your Google Drive,
res, err := getfilelist.GetFolderTree(client)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println(res)
}
Fields()
. When this is not used, the default fields are used.Document of Service account is here.
package main
import (
"encoding/json"
"fmt"
"io/ioutil"
"log"
"net/http"
getfilelist "github.com/tanaikech/go-getfilelist"
"golang.org/x/oauth2"
"golang.org/x/oauth2/google"
"golang.org/x/oauth2/jwt"
)
// ServiceAccount : Use Service account
func ServiceAccount(credentialFile string) *http.Client {
b, err := ioutil.ReadFile(credentialFile)
if err != nil {
log.Fatal(err)
}
var c = struct {
Email string `json:"client_email"`
PrivateKey string `json:"private_key"`
}{}
json.Unmarshal(b, &c)
config := &jwt.Config{
Email: c.Email,
PrivateKey: []byte(c.PrivateKey),
Scopes: []string{
"https://www.googleapis.com/auth/drive.metadata.readonly",
},
TokenURL: google.JWTTokenURL,
}
client := config.Client(oauth2.NoContext)
return client
}
func main() {
folderID := "### folder ID ###" // Please set here
client := ServiceAccount("credential.json") // Please set here
// When you want to retrieve the file list in the folder,
res, err := getfilelist.Folder(folderID).Fields("files(name,id)").Do(client)
// When you want to retrieve only folder tree in the folder,
res, err := getfilelist.Folder(folderID).GetFolderTree(client)
if err != nil {
fmt.Println(err)
os.Exit(1)
}
fmt.Println(res)
}
Fields()
. When this is not used, the default fields are used.As a sample, when the values are retrieved from above structure, the results of GetFolderTree()
and Do()
become as follows.
res, err := getfilelist.Folder(folderID).GetFolderTree(client)
{
"id": [
["folderIdOfsampleFolder1"],
["folderIdOfsampleFolder1", "folderIdOfsampleFolder_2a"],
["folderIdOfsampleFolder1", "folderIdOfsampleFolder_2b"],
[
"folderIdOfsampleFolder1",
"folderIdOfsampleFolder_2a",
"folderIdOfsampleFolder_2a_3a"
],
[
"folderIdOfsampleFolder1",
"folderIdOfsampleFolder_2b",
"folderIdOfsampleFolder_2b_3a"
],
[
"folderIdOfsampleFolder1",
"folderIdOfsampleFolder_2b",
"folderIdOfsampleFolder_2b_3b"
],
[
"folderIdOfsampleFolder1",
"folderIdOfsampleFolder_2b",
"folderIdOfsampleFolder_2b_3b",
"folderIdOfsampleFolder_2b_3b_4a"
]
],
"names": [
"sampleFolder1",
"sampleFolder_2a",
"sampleFolder_2b",
"sampleFolder_2a_3a",
"sampleFolder_2b_3a",
"sampleFolder_2b_3b",
"sampleFolder_2b_3b_4a"
],
"folders": [
"folderIdOfsampleFolder1",
"folderIdOfsampleFolder_2a",
"folderIdOfsampleFolder_2b",
"folderIdOfsampleFolder_2a_3a",
"folderIdOfsampleFolder_2b_3a",
"folderIdOfsampleFolder_2b_3b",
"folderIdOfsampleFolder_2b_3b_4a"
]
}
res, err := getfilelist.Folder(folderID).Fields("files(name,mimeType)").Do(client)
{
"searchedFolder": {
"id": "###",
"name": "sampleFolder1",
"mimeType": "application/vnd.google-apps.folder",
"parents": ["###"],
"createdTime": "2000-01-01T01:23:45.000Z",
"modifiedTime": "2000-01-01T01:23:45.000Z",
"webViewLink": "https://drive.google.com/drive/folders/###",
"owners": [
{ "displayName": "###", "permissionId": "###", "emailAddress": "###" }
],
"shared": true
},
"folderTree": {
"id": [
["folderIdOfsampleFolder1"],
["folderIdOfsampleFolder1", "folderIdOfsampleFolder_2a"],
["folderIdOfsampleFolder1", "folderIdOfsampleFolder_2b"],
[
"folderIdOfsampleFolder1",
"folderIdOfsampleFolder_2a",
"folderIdOfsampleFolder_2a_3a"
],
[
"folderIdOfsampleFolder1",
"folderIdOfsampleFolder_2b",
"folderIdOfsampleFolder_2b_3a"
],
[
"folderIdOfsampleFolder1",
"folderIdOfsampleFolder_2b",
"folderIdOfsampleFolder_2b_3b"
],
[
"folderIdOfsampleFolder1",
"folderIdOfsampleFolder_2b",
"folderIdOfsampleFolder_2b_3b",
"folderIdOfsampleFolder_2b_3b_4a"
]
],
"names": [
"sampleFolder1",
"sampleFolder_2a",
"sampleFolder_2b",
"sampleFolder_2a_3a",
"sampleFolder_2b_3a",
"sampleFolder_2b_3b",
"sampleFolder_2b_3b_4a"
],
"folders": [
"folderIdOfsampleFolder1",
"folderIdOfsampleFolder_2a",
"folderIdOfsampleFolder_2b",
"folderIdOfsampleFolder_2a_3a",
"folderIdOfsampleFolder_2b_3a",
"folderIdOfsampleFolder_2b_3b",
"folderIdOfsampleFolder_2b_3b_4a"
]
},
"fileList": [
{
"folderTree": ["folderIdOfsampleFolder1"],
"files": [
{
"name": "Spreadsheet1",
"mimeType": "application/vnd.google-apps.spreadsheet"
}
]
},
{
"folderTree": ["folderIdOfsampleFolder1", "folderIdOfsampleFolder_2a"],
"files": [
{
"name": "Spreadsheet2",
"mimeType": "application/vnd.google-apps.spreadsheet"
}
]
},
{
"folderTree": ["folderIdOfsampleFolder1", "folderIdOfsampleFolder_2b"],
"files": [
{
"name": "Spreadsheet4",
"mimeType": "application/vnd.google-apps.spreadsheet"
}
]
},
{
"folderTree": [
"folderIdOfsampleFolder1",
"folderIdOfsampleFolder_2a",
"folderIdOfsampleFolder_2a_3a"
],
"files": null
},
{
"folderTree": [
"folderIdOfsampleFolder1",
"folderIdOfsampleFolder_2b",
"folderIdOfsampleFolder_2b_3a"
],
"files": [
{
"name": "Spreadsheet3",
"mimeType": "application/vnd.google-apps.spreadsheet"
}
]
},
{
"folderTree": [
"folderIdOfsampleFolder1",
"folderIdOfsampleFolder_2b",
"folderIdOfsampleFolder_2b_3b"
],
"files": null
},
{
"folderTree": [
"folderIdOfsampleFolder1",
"folderIdOfsampleFolder_2b",
"folderIdOfsampleFolder_2b_3b",
"folderIdOfsampleFolder_2b_3b_4a"
],
"files": [
{
"name": "Document1",
"mimeType": "application/vnd.google-apps.document"
},
{
"name": "image1.png",
"mimeType": "image/png"
},
{
"name": "Slides1",
"mimeType": "application/vnd.google-apps.presentation"
},
{
"name": "Spreadsheet5",
"mimeType": "application/vnd.google-apps.spreadsheet"
},
{
"name": "StandaloneProject1",
"mimeType": "application/vnd.google-apps.script"
},
{
"name": "Test1.txt",
"mimeType": "text/plain"
}
]
}
],
"totalNumberOfFiles": 10,
"totalNumberOfFolders": 7
}
As the libraries "GetFileList" for other languages, there are following libraries.
If you have any questions and commissions for me, feel free to tell me.
v1.0.0 (November 2, 2018)
v1.0.1 (November 13, 2018)
drive.File
.v1.0.2 (December 12, 2018)
v1.0.3 (May 14, 2020)
Shared drive got to be able to be used. The file list can be retrieved from both your Google Drive and the shared drive.
folderID
of Folder(folderID)
, you can retrieve the file list from the folder in the shared Drive.v1.0.4 (June 1, 2020)
FAQs
Unknown package
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security Fundamentals
The Socket Threat Research Team uncovers how threat actors weaponize shell techniques across npm, PyPI, and Go ecosystems to maintain persistence and exfiltrate data.
Security News
At VulnCon 2025, NIST scrapped its NVD consortium plans, admitted it can't keep up with CVEs, and outlined automation efforts amid a mounting backlog.
Product
We redesigned our GitHub PR comments to deliver clear, actionable security insights without adding noise to your workflow.