Browse Source

Add cookie-based authentication support

Fixes #1303
Zed 9 months ago
parent
commit
f89d2329d2
4 changed files with 56 additions and 18 deletions
  1. 21 7
      src/apiutils.nim
  2. 21 9
      src/experimental/parser/session.nim
  3. 3 0
      src/experimental/types/session.nim
  4. 11 2
      src/types.nim

+ 21 - 7
src/apiutils.nim

@@ -28,12 +28,12 @@ proc getOauthHeader(url, oauthToken, oauthTokenSecret: string): string =
 
 
   return getOauth1RequestHeader(params)["authorization"]
   return getOauth1RequestHeader(params)["authorization"]
 
 
-proc genHeaders*(url, oauthToken, oauthTokenSecret: string): HttpHeaders =
-  let header = getOauthHeader(url, oauthToken, oauthTokenSecret)
+proc getCookieHeader(authToken, ct0: string): string =
+  "auth_token=" & authToken & "; ct0=" & ct0
 
 
+proc genHeaders*(session: Session, url: string): HttpHeaders =
   result = newHttpHeaders({
   result = newHttpHeaders({
     "connection": "keep-alive",
     "connection": "keep-alive",
-    "authorization": header,
     "content-type": "application/json",
     "content-type": "application/json",
     "x-twitter-active-user": "yes",
     "x-twitter-active-user": "yes",
     "authority": "api.x.com",
     "authority": "api.x.com",
@@ -43,18 +43,32 @@ proc genHeaders*(url, oauthToken, oauthTokenSecret: string): HttpHeaders =
     "DNT": "1"
     "DNT": "1"
   })
   })
 
 
+  case session.kind
+  of SessionKind.oauth:
+    result["authorization"] = getOauthHeader(url, session.oauthToken, session.oauthSecret)
+  of SessionKind.cookie:
+    result["cookie"] = getCookieHeader(session.authToken, session.ct0)
+    result["x-csrf-token"] = session.ct0
+    result["x-twitter-auth-type"] = "OAuth2Session"
+
 template fetchImpl(result, fetchBody) {.dirty.} =
 template fetchImpl(result, fetchBody) {.dirty.} =
   once:
   once:
     pool = HttpPool()
     pool = HttpPool()
 
 
   var session = await getSession(api)
   var session = await getSession(api)
-  if session.oauthToken.len == 0:
-    echo "[sessions] Empty oauth token, session: ", session.id
-    raise rateLimitError()
+  case session.kind
+  of SessionKind.oauth:
+    if session.oauthToken.len == 0:
+      echo "[sessions] Empty oauth token, session: ", session.id
+      raise rateLimitError()
+  of SessionKind.cookie:
+    if session.authToken.len == 0 or session.ct0.len == 0:
+      echo "[sessions] Empty cookie credentials, session: ", session.id
+      raise rateLimitError()
 
 
   try:
   try:
     var resp: AsyncResponse
     var resp: AsyncResponse
-    pool.use(genHeaders($url, session.oauthToken, session.oauthSecret)):
+    pool.use(genHeaders(session, $url)):
       template getContent =
       template getContent =
         resp = await c.get($url)
         resp = await c.get($url)
         result = await resp.body
         result = await resp.body

+ 21 - 9
src/experimental/parser/session.nim

@@ -1,15 +1,27 @@
 import std/strutils
 import std/strutils
 import jsony
 import jsony
 import ../types/session
 import ../types/session
-from ../../types import Session
+from ../../types import Session, SessionKind
 
 
 proc parseSession*(raw: string): Session =
 proc parseSession*(raw: string): Session =
-  let 
-    session = raw.fromJson(RawSession)
-    id = session.oauthToken[0 ..< session.oauthToken.find('-')]
+  let session = raw.fromJson(RawSession)
+  let kind = if session.kind == "": "oauth" else: session.kind
 
 
-  result = Session(
-    id: parseBiggestInt(id),
-    oauthToken: session.oauthToken,
-    oauthSecret: session.oauthTokenSecret
-  )
+  case kind
+  of "oauth":
+    let id = session.oauthToken[0 ..< session.oauthToken.find('-')]
+    result = Session(
+      kind: SessionKind.oauth,
+      id: parseBiggestInt(id),
+      oauthToken: session.oauthToken,
+      oauthSecret: session.oauthTokenSecret
+    )
+  of "cookie":
+    result = Session(
+      kind: SessionKind.cookie,
+      id: 999,
+      authToken: session.authToken,
+      ct0: session.ct0
+    )
+  else:
+    raise newException(ValueError, "Unknown session kind: " & kind)

+ 3 - 0
src/experimental/types/session.nim

@@ -1,4 +1,7 @@
 type
 type
   RawSession* = object
   RawSession* = object
+    kind*: string
     oauthToken*: string
     oauthToken*: string
     oauthTokenSecret*: string
     oauthTokenSecret*: string
+    authToken*: string
+    ct0*: string

+ 11 - 2
src/types.nim

@@ -31,14 +31,23 @@ type
     remaining*: int
     remaining*: int
     reset*: int
     reset*: int
 
 
+  SessionKind* = enum
+    oauth
+    cookie
+
   Session* = ref object
   Session* = ref object
     id*: int64
     id*: int64
-    oauthToken*: string
-    oauthSecret*: string
     pending*: int
     pending*: int
     limited*: bool
     limited*: bool
     limitedAt*: int
     limitedAt*: int
     apis*: Table[Api, RateLimit]
     apis*: Table[Api, RateLimit]
+    case kind*: SessionKind
+    of oauth:
+      oauthToken*: string
+      oauthSecret*: string
+    of cookie:
+      authToken*: string
+      ct0*: string
 
 
   Error* = enum
   Error* = enum
     null = 0
     null = 0