Fixed: Failed to login to Garmin #6

master
mgifos 8 years ago
parent 9f8d07dc51
commit f2a2119628
  1. 54
      src/main/scala/com.github.mgifos.workouts/GarminConnect.scala
  2. 2
      src/test/resources/ultra-80k-runnersworld.csv

@ -30,7 +30,7 @@ case class GarminWorkout(name: String, id: Long)
class GarminConnect(email: String, password: String)(implicit system: ActorSystem, executionContext: ExecutionContext, mat: Materializer) { class GarminConnect(email: String, password: String)(implicit system: ActorSystem, executionContext: ExecutionContext, mat: Materializer) {
case class Session(username: String, headers: Seq[HttpHeader]) case class Session(headers: Seq[HttpHeader])
case class Login(forceNewSession: Boolean) case class Login(forceNewSession: Boolean)
@ -206,9 +206,10 @@ class GarminConnect(email: String, password: String)(implicit system: ActorSyste
def extractCookies(res: HttpResponse) = res.headers.collect { case x: `Set-Cookie` => x.cookie }.map(c => Cookie(c.name, c.value)) def extractCookies(res: HttpResponse) = res.headers.collect { case x: `Set-Cookie` => x.cookie }.map(c => Cookie(c.name, c.value))
def redirectionLoop(count: Int, url: String, acc: Seq[Cookie]): Future[Seq[Cookie]] = { def redirectionLoop(count: Int, url: String, acc: Seq[Cookie]): Future[Seq[Cookie]] = {
Http().singleRequest { val req = HttpRequest(uri = Uri(url)).withHeaders(acc)
HttpRequest(uri = Uri(url)).withHeaders(acc) log.debug(s"Login redirection no $count with req: $req")
}.withoutBody.flatMap { res => Http().singleRequest(req).withoutBody.flatMap { res =>
log.debug(s"Res: $res")
val cookies = extractCookies(res) val cookies = extractCookies(res)
res.headers.find(_.name() == "Location") match { res.headers.find(_.name() == "Location") match {
case Some(header) => case Some(header) =>
@ -226,10 +227,33 @@ class GarminConnect(email: String, password: String)(implicit system: ActorSyste
} }
val params = Map( val params = Map(
"service" -> "https://connect.garmin.com/post-auth/login",
"clientId" -> "GarminConnect", "clientId" -> "GarminConnect",
//"connectLegalTerms" -> "true",
"consumeServiceTicket" -> "false",
//"createAccountShown" -> "true",
//"cssUrl" -> "https://static.garmincdn.com/com.garmin.connect/ui/css/gauth-custom-v1.2-min.css",
//"displayNameShown" -> "false",
//"embedWidget" -> "false",
"gauthHost" -> "https://sso.garmin.com/sso", "gauthHost" -> "https://sso.garmin.com/sso",
"consumeServiceTicket" -> "false") //"generateExtraServiceTicket" -> "false",
//"generateNoServiceTicket" -> "false",
//"globalOptInChecked" -> "false",
//"globalOptInShown" -> "true",
//"id" -> "gauth-widget",
//"initialFocus" -> "true",
//"locale" -> "en_US",
//"locationPromptShown" -> "true",
//"mobile" -> "false",
//"openCreateAccount" -> "false",
//"privacyStatementUrl" -> "//connect.garmin.com/en-US/privacy/",
//"redirectAfterAccountCreationUrl" -> "https://connect.garmin.com/modern/",
//"redirectAfterAccountLoginUrl" -> "https://connect.garmin.com/modern/",
//"rememberMeChecked" -> "false",
//"rememberMeShown" -> "true",
"service" -> "https://connect.garmin.com/modern",
//"source" -> "https://connect.garmin.com/en-US/signin",
//"webhost" -> "https://connect.garmin.com"
)
for { for {
res1 <- Http().singleRequest(HttpRequest(uri = Uri("https://sso.garmin.com/sso/login").withQuery(Query(params)))).withoutBody res1 <- Http().singleRequest(HttpRequest(uri = Uri("https://sso.garmin.com/sso/login").withQuery(Query(params)))).withoutBody
res2 <- Http().singleRequest( res2 <- Http().singleRequest(
@ -239,21 +263,9 @@ class GarminConnect(email: String, password: String)(implicit system: ActorSyste
entity = FormData(Map( entity = FormData(Map(
"username" -> email, "username" -> email,
"password" -> password, "password" -> password,
"_eventId" -> "submit", "embed" -> "false")).toEntity).withHeaders(extractCookies(res1))).withoutBody
"embed" -> "true")).toEntity).withHeaders(extractCookies(res1))).withoutBody sessionCookies <- redirectionLoop(0, "https://connect.garmin.com/modern", extractCookies(res2))
sessionCookies <- redirectionLoop(0, "https://connect.garmin.com/post-auth/login", extractCookies(res2)) } yield Session(sessionCookies)
username <- getUsername(sessionCookies)
} yield Session(username, sessionCookies)
}
private def getUsername(sessionCookies: Seq[HttpHeader]): Future[String] = {
val req = HttpRequest(GET, Uri("https://connect.garmin.com/user/username")).withHeaders(sessionCookies)
Http().singleRequest(req).flatMap { res =>
if (res.status != StatusCodes.OK) throw new Error("Login failed!")
res.body.map { json =>
(Json.parse(json) \ "username").as[String]
}
}
} }
} }
} }

@ -86,7 +86,7 @@ WEEK,Monday,Tuesday,Wednesday,Thursday,Friday,Saturday,Sunday,Estimated km,,Dura
13,,"15k, 6x1.6k @TMP",8k jog,"15k, middle 5k @MP",,4h run,5h run,128.0,,3:00:00,30.0,18.6 13,,"15k, 6x1.6k @TMP",8k jog,"15k, middle 5k @MP",,4h run,5h run,128.0,,3:00:00,30.0,18.6
14,,"workout: 15k, 4x1.6k @TMP 14,,"workout: 15k, 4x1.6k @TMP
- warmup: 3km @z2 - warmup: 3km @z2
- repeat: 2 - repeat: 4
- run: 1600m @ 5:00-4:30 - run: 1600m @ 5:00-4:30
- recover: 1400m @z2 - recover: 1400m @z2
- run: 1km @z2 - run: 1km @z2

1 WEEK Monday Tuesday Wednesday Thursday Friday Saturday Sunday Estimated km Duration Avg km Miles
86
87
88
89
90
91
92
Loading…
Cancel
Save