Пример #1
0
/*
 * 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")
		}
	}
}
Пример #2
0
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)
	}
}
Пример #3
0
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))
}
Пример #4
0
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)
}
Пример #5
0
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
}
Пример #6
0
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)))
}
Пример #7
0
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")
}
Пример #8
0
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
}