Skip to content

Commit

Permalink
Add reauth subcommand, with docs for reauthenticating
Browse files Browse the repository at this point in the history
  • Loading branch information
mholt committed May 25, 2019
1 parent c4e4ae7 commit 3284be8
Show file tree
Hide file tree
Showing 3 changed files with 43 additions and 11 deletions.
10 changes: 10 additions & 0 deletions README.md
Expand Up @@ -148,6 +148,16 @@ However, this involves doing a complete listing of all the items. Pruning happen
To schedule a prune, just run with the `-prune` flag: `timeliner -prune get-all ...`.


### Reauthenticating with a data source

Some data sources (Facebook) expire tokens that don't have recent user interactions. Every 2-3 months, you may need to reauthenticate:

```
$ timeliner reauth facebook/you
```

See the [wiki](https://github.com/mholt/timeliner/wiki) for each data source to know if you need to reauthenticate and how to do so. Sometimes you have to go to the data source itself and authorize a reauthentication first.


### More information about each data source

Expand Down
31 changes: 22 additions & 9 deletions account.go
Expand Up @@ -47,13 +47,8 @@ func (acc Account) NewHTTPClient() (*http.Client, error) {

// AddAccount authenticates userID with the service identified
// within the application by dataSourceID, and then stores it in the
// database.
// database. The account must not yet exist.
func (t *Timeline) AddAccount(dataSourceID, userID string) error {
ds, ok := dataSources[dataSourceID]
if !ok {
return fmt.Errorf("data source not registered: %s", dataSourceID)
}

// ensure account is not already stored in our system
var count int
err := t.db.QueryRow(`SELECT COUNT(*) FROM accounts WHERE data_source_id=? AND user_id=? LIMIT 1`,
Expand All @@ -65,8 +60,21 @@ func (t *Timeline) AddAccount(dataSourceID, userID string) error {
return fmt.Errorf("account already stored in database: %s/%s", dataSourceID, userID)
}

return t.Authenticate(dataSourceID, userID)
}

// Authenticate gets authentication for userID with dataSourceID. If the
// account already exists in the database, it will be updated with the
// latest authorization.
func (t *Timeline) Authenticate(dataSourceID, userID string) error {
ds, ok := dataSources[dataSourceID]
if !ok {
return fmt.Errorf("data source not registered: %s", dataSourceID)
}

// authenticate with the data source (if necessary)
var credsBytes []byte
var err error
if authFn := ds.authFunc(); authFn != nil {
credsBytes, err = authFn(userID)
if err != nil {
Expand All @@ -82,10 +90,15 @@ func (t *Timeline) AddAccount(dataSourceID, userID string) error {
}

// store the account along with our authorization to access it
_, err = t.db.Exec(`INSERT INTO accounts (data_source_id, user_id, authorization) VALUES (?, ?, ?)`,
dataSourceID, userID, credsBytes)
_, err = t.db.Exec(`INSERT INTO accounts
(data_source_id, user_id, authorization)
VALUES (?, ?, ?)
ON CONFLICT (data_source_id, user_id)
DO UPDATE SET authorization=?`,
dataSourceID, userID, credsBytes,
credsBytes)
if err != nil {
return fmt.Errorf("inserting into DB: %v", err)
return fmt.Errorf("inserting into or updating DB: %v", err)
}

return nil
Expand Down
13 changes: 11 additions & 2 deletions cmd/timeliner/main.go
Expand Up @@ -84,15 +84,24 @@ func main() {
}
defer tl.Close()

// as a special case, handle AddAccount separately
if subcmd == "add-account" {
// as a special case, handle authentication subcommands separately
switch subcmd {
case "add-account":
for _, a := range accounts {
err := tl.AddAccount(a.dataSourceID, a.userID)
if err != nil {
log.Fatalf("[FATAL] Adding account: %v", err)
}
}
return
case "reauth":
for _, a := range accounts {
err := tl.Authenticate(a.dataSourceID, a.userID)
if err != nil {
log.Fatalf("[FATAL] Authenticating: %v", err)
}
}
return
}

// make a client for each account
Expand Down

0 comments on commit 3284be8

Please sign in to comment.