fix: microsoft todo migration not importing all tasks

Previously, we did not check if a list has more tasks than the ones returned. By default, the Microsoft Graph API only returns 10 tasks. If the user had more they would not get imported.
Now we check if there are more pages with tasks and pull them all in until we have everything.
This commit is contained in:
kolaente 2022-02-18 20:00:42 +01:00
parent 545999cf5e
commit 43f1daf40c
No known key found for this signature in database
GPG key ID: F40E70337AB24C9B

View file

@ -23,6 +23,7 @@ import (
"fmt"
"net/http"
"net/url"
"strings"
"time"
"code.vikunja.io/api/pkg/config"
@ -33,6 +34,7 @@ import (
)
const apiScopes = `tasks.read tasks.read.shared`
const apiPrefix = `https://graph.microsoft.com/v1.0/me/todo/`
type Migration struct {
Code string `json:"code"`
@ -92,6 +94,7 @@ type recurrence struct {
type tasksResponse struct {
OdataContext string `json:"@odata.context"`
Nextlink string `json:"@odata.nextLink"`
Value []*task `json:"value"`
}
@ -178,7 +181,7 @@ func getMicrosoftGraphAuthToken(code string) (accessToken string, err error) {
}
func makeAuthenticatedGetRequest(token, urlPart string, v interface{}) error {
req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, "https://graph.microsoft.com/v1.0/me/todo/"+urlPart, nil)
req, err := http.NewRequestWithContext(context.Background(), http.MethodGet, apiPrefix+urlPart, nil)
if err != nil {
return err
}
@ -224,16 +227,29 @@ func getMicrosoftTodoData(token string) (microsoftTodoData []*list, err error) {
log.Debugf("[Microsoft Todo Migration] Got %d lists", len(lists.Value))
for _, list := range lists.Value {
tasksResponse := &tasksResponse{}
err = makeAuthenticatedGetRequest(token, "lists/"+list.ID+"/tasks", tasksResponse)
link := "lists/" + list.ID + "/tasks"
list.Tasks = []*task{}
// Microsoft's Graph API has pagination, so we're going through all pages to get all tasks
for {
tr := &tasksResponse{}
err = makeAuthenticatedGetRequest(token, link, tr)
if err != nil {
log.Errorf("[Microsoft Todo Migration] Could not get tasks for list %s: %s", list.ID, err)
return
}
log.Debugf("[Microsoft Todo Migration] Got %d tasks for list %s", len(tasksResponse.Value), list.ID)
log.Debugf("[Microsoft Todo Migration] Got %d tasks for list %s", len(tr.Value), list.ID)
list.Tasks = tasksResponse.Value
list.Tasks = append(list.Tasks, tr.Value...)
if tr.Nextlink == "" {
break
}
link = strings.ReplaceAll(tr.Nextlink, apiPrefix, "")
}
microsoftTodoData = append(microsoftTodoData, list)
}