mirror of
https://gitgud.io/yats/libkiwi.git
synced 2026-06-19 09:35:26 -04:00
Compare commits
2 Commits
1e9bd059f0
..
login
| Author | SHA1 | Date | |
|---|---|---|---|
| 92438691f1 | |||
| 72840af90e |
@@ -122,18 +122,29 @@ func (kf *KF) TwoFactorAuth(ctx context.Context, resp *http.Response, code uint3
|
||||
return kf.Do(req)
|
||||
}
|
||||
|
||||
func (kf *KF) RefreshSession(ctx context.Context) error {
|
||||
func (kf *KF) IsLoggedIn() bool {
|
||||
return kf.Cookies.GetCookie(kf.domain, "xf_user") != nil
|
||||
}
|
||||
|
||||
func (kf *KF) RefreshSession(ctx context.Context) (string, error) {
|
||||
const COOKIE_NAME = "xf_session"
|
||||
|
||||
// Clear any existing session token to request a new one.
|
||||
setCookie(kf.domain, kf.client.Jar, &http.Cookie{
|
||||
Name: "xf_session",
|
||||
kf.Cookies.SetCookie(kf.domain, &http.Cookie{
|
||||
Name: COOKIE_NAME,
|
||||
Value: "",
|
||||
})
|
||||
|
||||
resp, err := kf.Get(ctx, kf.domain)
|
||||
if err != nil {
|
||||
return err
|
||||
return "", err
|
||||
}
|
||||
resp.Body.Close()
|
||||
|
||||
return nil
|
||||
session := kf.Cookies.GetCookie(kf.domain, COOKIE_NAME)
|
||||
if session == nil {
|
||||
return "", errors.New("Failed to get new xf_session cookie.")
|
||||
}
|
||||
|
||||
return session.Value, nil
|
||||
}
|
||||
|
||||
@@ -63,6 +63,13 @@ func TestLogin(t *testing.T) {
|
||||
}
|
||||
t.Logf("2FA response: %+v\n", lr)
|
||||
}
|
||||
|
||||
session, err := kf.RefreshSession(ctx)
|
||||
if err != nil {
|
||||
t.Error(err)
|
||||
return
|
||||
}
|
||||
t.Logf("xf_session: %s\n", session)
|
||||
}
|
||||
|
||||
func genTest2FACode() (uint32, error) {
|
||||
|
||||
+38
@@ -0,0 +1,38 @@
|
||||
package libkiwi
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/url"
|
||||
)
|
||||
|
||||
// http.CookieJar interface wrapper to add convenience functions.
|
||||
type jar struct {
|
||||
http.CookieJar
|
||||
}
|
||||
|
||||
func (j *jar) GetCookie(u *url.URL, name string) *http.Cookie {
|
||||
cookies := j.Cookies(u)
|
||||
for _, c := range cookies {
|
||||
if c.Name == name {
|
||||
return c
|
||||
}
|
||||
}
|
||||
|
||||
return nil
|
||||
}
|
||||
|
||||
func (j *jar) SetCookie(u *url.URL, newCookie *http.Cookie) {
|
||||
cookies := j.Cookies(u)
|
||||
|
||||
for i, c := range cookies {
|
||||
if c.Name == newCookie.Name {
|
||||
cookies[i] = newCookie
|
||||
j.SetCookies(u, cookies)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Append if not already existing.
|
||||
cookies = append(cookies, newCookie)
|
||||
j.SetCookies(u, cookies)
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
module gitgud.io/yats/libkiwi
|
||||
|
||||
go 1.26.1
|
||||
go 1.26.4
|
||||
|
||||
require (
|
||||
gitgud.io/yats/cerberus v0.0.0-20260214165307-66e6f74a4be9
|
||||
|
||||
@@ -19,12 +19,14 @@ func XFToken(page io.Reader) (string, error) {
|
||||
z := html.NewTokenizer(page)
|
||||
for i := z.Next(); i != html.ErrorToken; i = z.Next() {
|
||||
tk := z.Token()
|
||||
if tk.DataAtom == atom.Html {
|
||||
for _, a := range tk.Attr {
|
||||
switch a.Key {
|
||||
case "data-csrf":
|
||||
return a.Val, nil
|
||||
}
|
||||
if tk.DataAtom != atom.Html {
|
||||
continue
|
||||
}
|
||||
|
||||
for _, a := range tk.Attr {
|
||||
switch a.Key {
|
||||
case "data-csrf":
|
||||
return a.Val, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -32,22 +34,6 @@ func XFToken(page io.Reader) (string, error) {
|
||||
return "", ErrNoXFToken
|
||||
}
|
||||
|
||||
func setCookie(u *url.URL, jar http.CookieJar, newCookie *http.Cookie) {
|
||||
cookies := jar.Cookies(u)
|
||||
|
||||
for i, c := range cookies {
|
||||
if c.Name == newCookie.Name {
|
||||
cookies[i] = newCookie
|
||||
jar.SetCookies(u, cookies)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// Append if not already existing.
|
||||
cookies = append(cookies, newCookie)
|
||||
jar.SetCookies(u, cookies)
|
||||
}
|
||||
|
||||
func (kf *KF) Do(req *http.Request) (*http.Response, error) {
|
||||
var (
|
||||
ctx = req.Context()
|
||||
|
||||
+16
-13
@@ -18,28 +18,31 @@ const _USER_AGENT = "Mozilla/5.0 (Windows NT 6.1; rv:60.0) Gecko/20100101 Firefo
|
||||
type KF struct {
|
||||
client http.Client
|
||||
domain *url.URL
|
||||
|
||||
Cookies jar
|
||||
}
|
||||
|
||||
// Supply your own http.Client to route through any proxies.
|
||||
func NewKF(hc http.Client, host *url.URL) (*KF, error) {
|
||||
func NewKF(hc http.Client, host *url.URL) (KF, error) {
|
||||
u, err := url.Parse(fmt.Sprintf("https://%s", host.Hostname()))
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return KF{}, err
|
||||
}
|
||||
|
||||
jar, err := cookiejar.New(nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
if hc.Jar == nil {
|
||||
jar, err := cookiejar.New(nil)
|
||||
if err != nil {
|
||||
return KF{}, err
|
||||
}
|
||||
|
||||
hc.Jar = jar
|
||||
}
|
||||
|
||||
hc.Jar = jar
|
||||
|
||||
kf := &KF{
|
||||
client: hc,
|
||||
domain: u,
|
||||
}
|
||||
|
||||
return kf, nil
|
||||
return KF{
|
||||
client: hc,
|
||||
domain: u,
|
||||
Cookies: jar{hc.Jar},
|
||||
}, nil
|
||||
}
|
||||
|
||||
type User struct {
|
||||
|
||||
+3
-3
@@ -58,7 +58,7 @@ func TestGetPost(t *testing.T) {
|
||||
t.Logf("Post text: %s\n", post.TextContent())
|
||||
}
|
||||
|
||||
func newTestKF() (*KF, error) {
|
||||
func newTestKF() (KF, error) {
|
||||
host := os.Getenv("TEST_HOST")
|
||||
if host == "" {
|
||||
host = _TEST_HOST
|
||||
@@ -66,7 +66,7 @@ func newTestKF() (*KF, error) {
|
||||
|
||||
u, err := url.Parse("https://" + host)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return KF{}, err
|
||||
}
|
||||
|
||||
p := proxy.FromEnvironment()
|
||||
@@ -76,7 +76,7 @@ func newTestKF() (*KF, error) {
|
||||
|
||||
jar, err := cookiejar.New(nil)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return KF{}, err
|
||||
}
|
||||
|
||||
hc := http.Client{
|
||||
|
||||
Reference in New Issue
Block a user