commit 4af67b036396ca952b85b93b4d4bc371cd7bfcd9
parent 410a8c7f1866f30ff958eb102c8c0fcad2cf64ab
Author: Juan Roig <jaroig@outlook.com>
Date: Sat, 4 Nov 2023 01:55:30 -0400
Moved functional code to funcs.go
Diffstat:
| A | funcs.go | | | 128 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| M | main.go | | | 218 | ++++++++----------------------------------------------------------------------- |
2 files changed, 150 insertions(+), 196 deletions(-)
diff --git a/funcs.go b/funcs.go
@@ -0,0 +1,128 @@
+package main
+
+import (
+ "encoding/json"
+ "fmt"
+ "io"
+ "net/http"
+ "net/url"
+ "strings"
+)
+
+/*
+func get_courses(token string, link string, client http.Client) []CanvasCourse {
+ resp, err := client.Get(link)
+ if err != nil {
+ fmt.Println("Error performing GET request to get courses.")
+ }
+ defer resp.Body.Close()
+ body, err := io.ReadAll(resp.Body)
+
+ if err != nil {
+ fmt.Println("Error trying to read html body for courses.")
+ }
+
+ var canvas_courses []CanvasCourse
+ err2 := json.Unmarshal(body, &canvas_courses)
+ if err2 != nil {
+ fmt.Println(err2)
+ return nil
+ }
+
+ return canvas_courses
+}
+
+// Need to change this to grab both ID and name, return as pairs.
+func get_course_id_name_pair(canvas_courses []CanvasCourse) []uint64 {
+ var courses []uint64
+
+ for _, course := range canvas_courses {
+ courses = append(courses, course.ID%10000)
+ }
+ return courses
+}
+
+func select_course() int {
+ // course selection by user happens below
+ //favorites := fmt.Sprintf("%s/users/self/favorites/courses?access_token=%s&per_page=100", base_link, token)
+ //all_courses := fmt.Sprintf("%s/courses?access_token=%s&per_page=100", base_link,token)
+ // var canvas_courses []CanvasCourse
+ //canvas_courses = get_courses(token, favorites, client)
+ //var course_ids []uint64
+ //course_ids = get_course_ids(canvas_courses)
+ //selected := 1 // course_ids[selected]
+ // course selection by user happens above
+ return 0
+}
+*/
+
+func get_aplus(token string, link string, client http.Client) string {
+ resp, err := client.Get(link)
+
+ if err != nil {
+ fmt.Println("Error performing GET request to initial link.")
+ }
+ defer resp.Body.Close()
+ body, err := io.ReadAll(resp.Body)
+
+ if err != nil {
+ fmt.Println("Error reading body of initial aplus html response " +
+ "which is supposed to contain a one-time link for getting the form.")
+ }
+
+ var aplus Aplus
+ json.Unmarshal(body, &aplus)
+
+ return aplus.URL
+}
+
+func get_form_from_request_body(req_body []byte) string {
+ body_str := string(req_body)
+ form_start := strings.Index(body_str, "<form")
+ form_end := strings.Index(body_str, "</form>") + 7
+ form_html := req_body[form_start:form_end]
+
+ return string(form_html)
+}
+
+// parse_form extracts form fields and values from the given HTML form string.
+func parse_form(form_html string) url.Values {
+ form_values := make(url.Values)
+ inputs := strings.Split(form_html, "<input")
+
+ for _, input := range inputs {
+ // Extract field name and value
+ name := extract_attribute(input, "name")
+ value := extract_attribute(input, "value")
+
+ if name != "" {
+ form_values.Add(name, value)
+ }
+ }
+
+ return form_values
+}
+
+func extract_attribute(input string, attribute string) string {
+ start := strings.Index(input, attribute+"=\"")
+ if start == -1 {
+ start = strings.Index(input, attribute+"='")
+ }
+
+ if start == -1 {
+ return ""
+ }
+
+ start += len(attribute) + 2
+
+ end := strings.Index(input[start:], "\"")
+ if end == -1 {
+ end = strings.Index(input[start:], "'")
+ }
+
+ if end == -1 {
+ return ""
+ }
+
+ return input[start : start+end]
+}
diff --git a/main.go b/main.go
@@ -1,97 +1,12 @@
package main
import (
- "encoding/json"
"fmt"
"io"
"net/http"
- "net/url"
- "strings"
+ "os"
)
-func get_courses(token string, link string, client http.Client) []CanvasCourse {
- resp, err := client.Get(link)
- if err != nil {
- // handle error
- }
- defer resp.Body.Close()
- body, err := io.ReadAll(resp.Body)
-
- var canvas_courses []CanvasCourse
- err2 := json.Unmarshal(body, &canvas_courses)
- if err2 != nil {
- fmt.Println(err2)
- return nil
- }
-
- return canvas_courses
-}
-
-func get_aplus(token string, link string, client http.Client) string {
- resp, err := client.Get(link)
-
- if err != nil {
- // handle error
- }
- defer resp.Body.Close()
- body, err := io.ReadAll(resp.Body)
- var aplus Aplus
- json.Unmarshal(body, &aplus)
-
- return aplus.URL
-}
-
-func get_course_ids(canvas_courses []CanvasCourse) []uint64 {
- var courses []uint64
-
- for _, course := range canvas_courses {
- courses = append(courses, course.ID%10000)
- }
- return courses
-}
-
-// parse_form extracts form fields and values from the given HTML form string.
-func parse_form(form_html string) url.Values {
- form_values := make(url.Values)
- inputs := strings.Split(form_html, "<input")
-
- for _, input := range inputs {
- // Extract field name and value
- name := extract_attribute(input, "name")
- value := extract_attribute(input, "value")
-
- if name != "" {
- form_values.Add(name, value)
- }
- }
-
- return form_values
-}
-
-func extract_attribute(input string, attribute string) string {
- start := strings.Index(input, attribute+"=\"")
- if start == -1 {
- start = strings.Index(input, attribute+"='")
- }
-
- if start == -1 {
- return ""
- }
-
- start += len(attribute) + 2
-
- end := strings.Index(input[start:], "\"")
- if end == -1 {
- end = strings.Index(input[start:], "'")
- }
-
- if end == -1 {
- return ""
- }
-
- return input[start : start+end]
-}
-
func main() {
client := http.Client{
CheckRedirect: func(req *http.Request, via []*http.Request) error {
@@ -100,145 +15,56 @@ func main() {
},
}
- // https://canvas.instructure.com/api/v1/courses?access_token={}&per_page=100", canvas_token
base_link := "https://floridapolytechnic.instructure.com/api/v1"
- token := "token"
-
- // course selection by user happens below
- //favorites := fmt.Sprintf("%s/users/self/favorites/courses?access_token=%s&per_page=100", base_link, token)
- //all_courses := fmt.Sprintf("%s/courses?access_token=%s&per_page=100", base_link,token)
- //var canvas_courses []CanvasCourse
- //canvas_courses = get_courses(token, favorites, client)
- //var course_ids []uint64
- //course_ids = get_course_ids(canvas_courses)
- //selected := 1 // course_ids[selected]
- // course selection by user happens above
+ token := os.Getenv("CANVAS_API_KEY")
+
+ // select_course()
aplus_link := fmt.Sprintf("%s/courses/%d/external_tools/sessionless_launch?id=913&access_token=%s", base_link, 7329, token) // 7329 always works
- var aplus string
- aplus = get_aplus(token, aplus_link, client)
+ aplus := get_aplus(token, aplus_link, client)
fmt.Println(aplus)
resp, err := client.Get(aplus)
if err != nil {
- // handle error
+ fmt.Println("Error while performing GET request to aplus auth link.")
}
- //fmt.Println(resp)
-
defer resp.Body.Close()
body, err := io.ReadAll(resp.Body)
- //fmt.Println(string(body))
- //fmt.Println(resp)
- //fmt.Println("Status code:", resp.StatusCode)
-
if err != nil {
- // handle error
+ fmt.Println("Error reading body of initial aplus html response.")
}
- body_str := string(body)
-
- form_start := strings.Index(body_str, "<form")
- form_end := strings.Index(body_str, "</form>") + 7
- form_html := body[form_start:form_end]
+ form_str := get_form_from_request_body(body)
+ fmt.Println(form_str)
- form := string(form_html)
- fmt.Println(form)
-
- form_values := parse_form(form)
+ form_values := parse_form(form_str)
fmt.Println("Form Values:")
for key, values := range form_values {
fmt.Printf("%s: %s\n", key, values)
}
- //req, err := http.PostForm("https://floridapoly.aplusattendance.com/canvas", form_values)
req, err := client.PostForm("https://floridapoly.aplusattendance.com/canvas", form_values)
- body, err = io.ReadAll(req.Body)
-
- fmt.Println(string(body))
- fmt.Println(req)
-}
-/*
-
-The code below takes the form that defines the post request we must perform to the aplusattendance.com site, and actually maps it to a request.
-what I have to do is programmatically grab that form, translate it on the fly, and submit the request rather than doing this manually.
-// Define the form data as a map of key-value pairs.
- formData := map[string]string{
- "oauth_consumer_key": "aplus-attendance",
- "oauth_signature_method": "HMAC-SHA1",
- "oauth_timestamp": "1698650339",
- "oauth_nonce": "nV9EswFv8LtXXRVgRmWW8NSQ7mO3Sheeqi1SjJWPJGE",
- "oauth_version": "1.0",
- "context_id": "0c1f49ff7b35cba2226f93e9cbb84ae810ed00ab",
- "context_label": "CIS4367.01I&T",
- "context_title": "Computer Security(FA 2023_CIS4367.01 I&T",
- "custom_canvas_api_domain": "floridapolytechnic.instructure.com",
- "custom_canvas_course_id": "7329",
- "custom_canvas_enrollment_state": "active",
- "custom_canvas_user_id": "6858",
- "custom_canvas_user_login_id": "jroig9590",
- "custom_canvas_workflow_state": "available",
- "ext_roles": "urn:lti:instrole:ims/lis/Student,urn:lti:role:ims/lis/Learner,urn:lti:sysrole:ims/lis/User",
- "launch_presentation_document_target": "iframe",
- "launch_presentation_locale": "en",
- "launch_presentation_return_url": "https://floridapolytechnic.instructure.com/courses/7329",
- "lis_course_offering_sourcedid": "7093",
- "lis_person_contact_email_primary": "jroig9590@floridapoly.edu",
- "lis_person_name_family": "Roig",
- "lis_person_name_full": "Juan Roig",
- "lis_person_name_given": "Juan",
- "lis_person_sourcedid": "10308",
- "lti_message_type": "basic-lti-launch-request",
- "lti_version": "LTI-1p0",
- "oauth_callback": "about:blank",
- "resource_link_id": "0c1f49ff7b35cba2226f93e9cbb84ae810ed00ab",
- "resource_link_title": "aPlus+ Attendance",
- "roles": "Learner",
- "tool_consumer_info_product_family_code": "canvas",
- "tool_consumer_info_version": "cloud",
- "tool_consumer_instance_contact_email": "notifications@instructure.com",
- "tool_consumer_instance_guid": "7db438071375c02373713c12c73869ff2f470b68.floridapolytechnic.instructure.com",
- "tool_consumer_instance_name": "Florida Polytechnic University",
- "user_id": "91ba5b390440f646d9d4c47a0dc14f91cf595887",
- "user_image": "https://canvas.instructure.com/images/messages/avatar-50.png",
- "oauth_signature": "u3mIfUZ+qgSN4zzk0Ipklc0A7KU=",
+ if err != nil {
+ fmt.Println("Error posting form to Aplus Attendance.")
}
- // Create an HTTP client
- client := &http.Client{}
+ body, err = io.ReadAll(req.Body)
- // Create a new request
- req, err := http.NewRequest("POST", "https://floridapoly.aplusattendance.com/canvas", bytes.NewBuffer([]byte{}))
if err != nil {
- fmt.Println("Error creating the request:", err)
- return
- }
-
- // Add the form data as URL-encoded values to the request
- q := req.URL.Query()
- for key, value := range formData {
- q.Add(key, value)
+ fmt.Println("Error reading body of post form response from aplus attendance.")
}
- req.URL.RawQuery = q.Encode()
- // Set the appropriate content type for the form
- req.Header.Set("Content-Type", "application/x-www-form-urlencoded")
+ fmt.Println(string(body))
+ fmt.Println(req)
- // Perform the POST request
- resp, err := client.Do(req)
- if err != nil {
- fmt.Println("Error sending the POST request:", err)
- return
- }
- defer resp.Body.Close()
+ // we need to submit the above post request correctly in order to submit this request.
+ //resp, err = client.Get("https://floridapoly.aplusattendance.com/canvas/student/?canvasCourse=7329&doStudentAuth=true")
+ //body, err = io.ReadAll(req.Body)
- // Check the response
- if resp.StatusCode == http.StatusOK {
- fmt.Println("Request successful. You may need to parse and process the response body if applicable.")
- } else {
- fmt.Println("Request failed with status code:", resp.Status)
- }
-*/
+ //fmt.Println(string(body))
+ //fmt.Println(req)
+}