/* * The Core functionality of this application. * - Get RK Activities since timestamp * - Get STV Activities since timestamp * - compare and calc difference * - store in STV * - update timestamp for record */ func startSync() { repo := sync.CreateSyncDbRepo(DbConnectionString) err := repo.CreateTableIfNotExist() if err != nil { log.Fatal("Error checking or creating the Sync database table: %s", err) } allSyncs, err := repo.RetrieveAllSyncTasks() log.Printf("Retrieved %d sync tasks", len(allSyncs)) if err != nil { //retrieval failed, we log and return log.Print("ERROR: error retrieving Sync Tasks, db down?") return } for _, syncer := range allSyncs { //que SyncTask for worker log.Printf("Now syncing for task: %s, %s, %s", syncer.StravaToken, syncer.RunkeeperToken, time.Unix(int64(syncer.LastSeenTimestamp), 0)) err := queueSyncTask(syncer) if err != nil { log.Fatal("Error enqueuing job for sync: %s", err) } //We might need to move this to the SyncTask itself now that we run on workers. log.Print("Updating last seen timestamp") //subtract 45 minutes to prevent activites being missed syncer.LastSeenTimestamp = int(time.Now().Add(time.Duration(tsDelta) * time.Minute).Unix()) rowsUpdated, err := repo.UpdateSyncTask(syncer) if err != nil || rowsUpdated != 1 { log.Fatal("Error updating the SyncTask record with a new timestamp") } } }
func SyncTaskCreate(w http.ResponseWriter, r *http.Request) { //TODO. Check if there already is a task with either of the keys syncTask := sync.CreateSyncTask("", "", -1, Environment) body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1048576)) if err != nil { panic(err) } if err := r.Body.Close(); err != nil { panic(err) } if err := json.Unmarshal(body, &syncTask); err != nil { w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(422) // unprocessable entity if err := json.NewEncoder(w).Encode(err); err != nil { panic(err) } } //Creation set the last know timestamp to 1 hour ago syncTask.LastSeenTimestamp = nowMinusOneHourInUnix() db := sync.CreateSyncDbRepo(DbConnectionString) _, _, st, _ := db.StoreSyncTask(*syncTask) w.Header().Set("Content-Type", "application/json; charset=UTF-8") w.WriteHeader(http.StatusCreated) if err := json.NewEncoder(w).Encode(st); err != nil { panic(err) } }
func Start(connString string, port int, secretRk string, redirectRk string, secretStv string, redirectStv string, env string, staticPath string) { DbConnectionString = connString RkSecret = secretRk RedirectUriRk = redirectRk RedirectUriStv = redirectStv StvSecret = secretStv portString := fmt.Sprintf(":%d", port) Environment = env StaticPath = staticPath strava.ClientId = 9667 strava.ClientSecret = StvSecret //for strava authenticator = &strava.OAuthAuthenticator{ CallbackURL: RedirectUriStv, RequestClientGenerator: nil, } log.Printf("callback url: %s", authenticator.AuthorizationURL("state1", strava.Permissions.Public, true)) db := sync.CreateSyncDbRepo(DbConnectionString) err := db.CreateTableIfNotExist() if err != nil { log.Fatal("Error checking or creating the Sync database table: %s", err) } router := NewRouter() router.Methods("GET").Path("/exchange_token").Name("STVOAuthCallback").Handler(authenticator.HandlerFunc(oAuthSuccess, oAuthFailure)) router.PathPrefix("/").Handler(http.FileServer(http.Dir(StaticPath))) log.Fatal(http.ListenAndServe(portString, router)) }
func RunkeeperDeauthorize(response http.ResponseWriter, request *http.Request) { body, err := ioutil.ReadAll(io.LimitReader(request.Body, 1048576)) if err != nil { //malformed request response.WriteHeader(http.StatusBadRequest) return } responseJson := make(map[string]string) json.Unmarshal(body, &responseJson) token := responseJson["access_token"] db := sync.CreateSyncDbRepo(DbConnectionString) task, err := db.FindSyncTaskByToken(token) if err != nil { response.WriteHeader(http.StatusAccepted) return } task.RunkeeperToken = "" _, err = db.UpdateSyncTask(*task) if err != nil { response.WriteHeader(http.StatusInternalServerError) return } response.WriteHeader(http.StatusAccepted) }
func oAuthSuccess(auth *strava.AuthorizationResponse, w http.ResponseWriter, r *http.Request) { db := sync.CreateSyncDbRepo(DbConnectionString) task, err := db.FindSyncTaskByToken(auth.AccessToken) if err != nil { log.Printf("Error loading token %s from database, aborting...", auth.AccessToken) w.WriteHeader(http.StatusInternalServerError) } runkeeperToken := auth.State if task == nil && (runkeeperToken == "" || runkeeperToken == "undefined") { syncTask := sync.CreateSyncTask("", "", -1, Environment) syncTask.StravaToken = auth.AccessToken syncTask.LastSeenTimestamp = nowMinusOneHourInUnix() _, _, _, err := db.StoreSyncTask(*syncTask) if err == nil { cookie := &http.Cookie{Name: "strava", Value: fmt.Sprintf("%s", syncTask.StravaToken), Expires: time.Now().Add(356 * 24 * time.Hour), HttpOnly: false} cookie.Domain = "www.syncmysport.com" http.SetCookie(w, cookie) } else { log.Printf("Error while creating a new SyncTask: %s, err: %s", syncTask, err) } } else { if task == nil { //find the task for runkeeper task, err = db.FindSyncTaskByToken(runkeeperToken) if err != nil { log.Printf("Error retrieving the RK based Task on Strava Auth") } log.Printf("Found: %s for Runkeeper SyncTask.", task) task.StravaToken = auth.AccessToken } //update cookie cookie := &http.Cookie{Name: "strava", Value: fmt.Sprintf("%s", task.StravaToken), Expires: time.Now().Add(356 * 24 * time.Hour), HttpOnly: false} cookie.Domain = "www.syncmysport.com" http.SetCookie(w, cookie) //if runkeeper is set, set that cookie to if task.RunkeeperToken != "" { cookie = &http.Cookie{Name: "runkeeper", Value: fmt.Sprintf("%s", task.RunkeeperToken), Expires: time.Now().Add(356 * 24 * time.Hour), HttpOnly: false} cookie.Domain = "www.syncmysport.com" http.SetCookie(w, cookie) } task.StravaToken = auth.AccessToken var i int i, err = db.UpdateSyncTask(*task) if i != 1 || err != nil { log.Printf("Error while updating synctask %s with token %s", task, auth.AccessToken) } } //redirect back to connect http.Redirect(w, r, "http://www.syncmysport.com/connect.html", 303) //replace by env var }
func ActiveUsersShow(response http.ResponseWriter, request *http.Request) { db := sync.CreateSyncDbRepo(DbConnectionString) userCount, err := db.CountActiveUsers() if err != nil { response.WriteHeader(http.StatusInternalServerError) } response.Header().Set("Content-Type", "application/json; charset=UTF-8") //return as json response.Write([]byte(fmt.Sprintf("{\"active-users\" : %d }", userCount))) }
func ObtainBearerToken(code string, stvToken string) (*sync.SyncTask, error) { tokenUrl := "https://runkeeper.com/apps/token" formData := make(map[string][]string) formData["grant_type"] = []string{"authorization_code"} formData["code"] = []string{code} formData["client_id"] = []string{RkClientId} formData["client_secret"] = []string{RkSecret} formData["redirect_uri"] = []string{RedirectUriRk} client := new(http.Client) response, err := client.PostForm(tokenUrl, formData) responseJson := make(map[string]string) if err == nil { responseBody, _ := ioutil.ReadAll(response.Body) json.Unmarshal(responseBody, &responseJson) token := responseJson["access_token"] db := sync.CreateSyncDbRepo(DbConnectionString) var task *sync.SyncTask if stvToken != "" && stvToken != "undefined" { task, err = db.FindSyncTaskByToken(stvToken) } else { task, err = db.FindSyncTaskByToken(token) } if task == nil || err != nil { syncTask := sync.CreateSyncTask("", "", -1, Environment) syncTask.RunkeeperToken = token syncTask.LastSeenTimestamp = nowMinusOneHourInUnix() db.StoreSyncTask(*syncTask) return syncTask, nil } else { //existing task if task.RunkeeperToken != token { task.RunkeeperToken = token db.UpdateSyncTask(*task) } else { log.Printf("Token %s is already stored for task id: %d", token, task.Uid) } return task, nil } } else { fmt.Print(err) } return nil, errors.New("Not happened") }
func TokenDisassociate(w http.ResponseWriter, r *http.Request) { vars := mux.Vars(r) token := vars["token"] log.Printf("Disassociating token %s", token) if token != "" { //validate this token against Strava stvClientImpl := stv.CreateStravaClient(token) rkClientImpl := rk.CreateRKClient(token) authInStrava := stvClientImpl.ValidateToken(token) authInRunkeeper := rkClientImpl.ValidateToken(token) if authInStrava { log.Printf("Token %s is valid for Strava", token) //remove from db db := sync.CreateSyncDbRepo(DbConnectionString) task, err := db.FindSyncTaskByToken(token) if err != nil { //return 5xx? w.WriteHeader(http.StatusInternalServerError) return } task.StravaToken = "" db.UpdateSyncTask(*task) log.Printf("Removed Strava token from task %d", task.Uid) //We should also revoke auth at Strava err = stvClientImpl.DeAuthorize(token) if err != nil { log.Printf("Error while deauthorizing at strava: %s", err) } //drop cookie log.Printf("Removing cookie..") cookie := &http.Cookie{Name: "strava", Value: "", MaxAge: -1} //MaxAge will remove the cookie cookie.Domain = "www.syncmysport.com" http.SetCookie(w, cookie) w.Write([]byte("OK")) //200 OK return //hmm } if authInRunkeeper { log.Printf("Token %s is valid for Runkeeper", token) //remove from db db := sync.CreateSyncDbRepo(DbConnectionString) task, err := db.FindSyncTaskByToken(token) if err != nil { //return 5xx? w.WriteHeader(http.StatusInternalServerError) return } task.RunkeeperToken = "" db.UpdateSyncTask(*task) log.Printf("Removed Runkeeper token from task %d", task.Uid) //We should also revoke auth at Runkeeper err = rkClientImpl.DeAuthorize(token) if err != nil { log.Printf("Error while deauthorizing at runkeeper: %s", err) } w.Write([]byte("OK")) //200 OK return //hmm } else { log.Printf("Token %s is already no longer valid for Strava or Runkeeper", token) } } w.Write([]byte("OK")) //200 OK }