Add Noten parsing and rework some existing code

This commit is contained in:
Marcel Transier
2019-10-06 19:20:57 +02:00
parent b7bea8cf09
commit eb9f2ed4ce
4 changed files with 149 additions and 15 deletions

View File

@@ -5,17 +5,30 @@ import (
"io/ioutil"
"net/http"
"net/url"
"regexp"
"strings"
"github.com/pkg/errors"
)
// Error variables
var (
ErrInvalSID error = errors.New("invalid session id")
)
// Session contains the session id and whatever this obscure asi token is.
type Session struct {
SID string
// ASI is a string you somehow have to pass to some endpoints.
ASI string
}
// Valid checks if the session id of the session is valid
func (s *Session) Valid() (bool, error) {
client := &http.Client{}
// GET the logged in mail page.
// If correctly logged in there is a logout button.
// Otherwise there is a login button.
req, err := http.NewRequest("GET", "https://lsf.hs-worms.de/qisserver/rds?state=user&type=8&topitem=functions&breadCrumbSource=portal", nil)
if err != nil {
return false, errors.Wrap(err, "could not prepare the request")
@@ -39,6 +52,9 @@ func (s *Session) Valid() (bool, error) {
return false, errors.New("unexpected response body")
}
// Login tries to login with the given username and password.
// If successful a new Session with the session id and asi
// will be created and returned.
func Login(username, password string) (*Session, error) {
client := &http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error { // don't follow redirects
@@ -61,8 +77,13 @@ func Login(username, password string) (*Session, error) {
if resp.StatusCode == 302 {
for _, c := range resp.Cookies() {
if c.Name == "JSESSIONID" {
asi, err := asi(c.Value)
if err != nil {
return nil, errors.Wrap(err, "could not get asi")
}
return &Session{
SID: c.Value,
ASI: asi,
}, nil
}
}
@@ -73,3 +94,52 @@ func Login(username, password string) (*Session, error) {
}
return nil, errors.New("unexpected response status code")
}
// NewSessionBySID checks whether the given session id is valid and if so
// a new Session with the session id and asi will be created and returned.
func NewSessionBySID(sid string) (*Session, error) {
s := &Session{
SID: sid,
}
valid, err := s.Valid()
if err != nil {
return nil, errors.Wrap(err, "could not check session")
}
if !valid {
return nil, ErrInvalSID
}
asi, err := asi(sid)
if err != nil {
return nil, errors.Wrap(err, "could not get asi")
}
return &Session{
SID: sid,
ASI: asi,
}, nil
}
func asi(sid string) (string, error) {
client := &http.Client{}
// GET Request with JESSIONID cookie to sitemap endpoint
req, err := http.NewRequest("GET", "https://lsf.hs-worms.de/qisserver/rds?state=sitemap&topitem=leer&breadCrumbSource=portal", nil)
if err != nil {
return "", errors.Wrap(err, "could not prepare the request")
}
req.Header.Add("Cookie", fmt.Sprintf("JSESSIONID=%s", sid))
resp, err := client.Do(req)
if err != nil {
return "", errors.Wrap(err, "could not do the request")
}
b, err := ioutil.ReadAll(resp.Body)
if err != nil {
return "", errors.Wrap(err, "could not read the response body")
}
// The asi is in some links as GET parameter.
// Filter it with regexp
re := regexp.MustCompile(`asi=([^"]+)`)
match := re.FindSubmatch(b)
if len(match) != 2 {
return "", errors.New("no asi found")
}
return string(match[1]), nil
}