123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194 |
- package main
- import (
- "encoding/json"
- "fmt"
- "io/ioutil"
- "log"
- "net"
- "net/http"
- "net/url"
- "strings"
- "github.com/valyala/fasttemplate"
- )
- //ClientsInformationStruct export
- type ClientsInformationStruct []struct {
- ClientID string `json:"client-id"`
- ClientSecret string `json:"client-secret"`
- Domain string `json:"domain"`
- ServiceName string `json:"service-name"`
- ServiceImage string `json:"service-image"`
- Scope []string `json:"scope"`
- }
- //UsersInformationStruct shouldn be exported
- type UsersInformationStruct []struct {
- Scope []struct {
- Name string `json:"name"`
- Value string `json:"value"`
- } `json:"scope"`
- Granted []struct {
- ClientID struct {
- Scope []string `json:"scope"`
- Status string `json:"status"`
- } `json:"client-id"`
- } `json:"granted"`
- }
- func main() {
- http.HandleFunc("/login", loginHandler)
- http.HandleFunc("/chklogin", chkloginHandler)
- http.Handle("/asset/", http.StripPrefix("/asset/", http.FileServer(http.Dir("./asset"))))
- http.ListenAndServe(":8080", nil)
- }
- func loginHandler(w http.ResponseWriter, r *http.Request) {
- _, _, ServiceName, ServiceImage, responseType, clientID, redirectURI, scope, state, nonce := confirmClientInformation(w, r)
- //serve file
- //push assembled data to page
- parsedPage, err := templateLoad("login.html", map[string]interface{}{
- "service-name": string(ServiceName),
- "service-image": string(ServiceImage),
- "response_type": string(responseType),
- "client_id": string(clientID),
- "redirect_uri": string(redirectURI),
- "scope": string(scope),
- "state": string(state),
- "nonce": string(nonce),
- })
- if err != nil {
- log.Println("Error. Unable to load login.html")
- }
- w.Write([]byte(parsedPage))
- }
- func chkloginHandler(w http.ResponseWriter, r *http.Request) {
- // Call ParseForm() to parse the raw query and update r.PostForm and r.Form.
- if err := r.ParseForm(); err != nil {
- errHandler(w, r, "Missing post parameter")
- }
- data, err := ioutil.ReadFile("./user.json")
- if err != nil {
- fmt.Print(err)
- }
- var UsersInformation UsersInformationStruct
- err = json.Unmarshal(data, &UsersInformation)
- email := r.FormValue("email")
- password := r.FormValue("password")
- fmt.Println(email, password)
- }
- func errHandler(w http.ResponseWriter, r *http.Request, errorMsg string) {
- //push assembled data to page
- parsedPage, err := templateLoad("error.html", map[string]interface{}{
- "error": string(errorMsg),
- })
- if err != nil {
- log.Println("Error. Unable to show error. Additionally, the error page also had error.")
- }
- w.Write([]byte(parsedPage))
- //sendTextResponse(w, parsedPage)
- }
- func confirmClientInformation(w http.ResponseWriter, r *http.Request) (string, string, string, string, string, string, string, string, string, string) {
- responseType := getGET(w, r, "response_type")
- if string(responseType) != "code" {
- errHandler(w, r, "Url param response_type was incompatible")
- }
- //
- clientID := getGET(w, r, "client_id")
- //
- redirectURI := getGET(w, r, "redirect_uri")
- redirectURIParsed, err := url.Parse(redirectURI)
- host, _, _ := net.SplitHostPort(redirectURIParsed.Host)
- //
- scope := getGET(w, r, "scope")
- state := getGET(w, r, "state")
- nonce := getGET(w, r, "nonce")
- //let say the GET request was good, then let us find does client-id and domain match our record
- data, err := ioutil.ReadFile("./client-id.json")
- if err != nil {
- fmt.Print(err)
- }
- var ClientsInformation ClientsInformationStruct
- err = json.Unmarshal(data, &ClientsInformation)
- if err != nil {
- fmt.Println("error:", err)
- }
- //process DB
- DBClientID := ""
- DBClientSecret := ""
- DBDomain := ""
- DBServiceName := ""
- DBServiceImage := ""
- var DBScope []string
- for _, ClientInformation := range ClientsInformation {
- if ClientInformation.ClientID == clientID {
- DBClientID = ClientInformation.ClientID
- DBClientSecret = ClientInformation.ClientSecret
- DBDomain = ClientInformation.Domain
- DBServiceName = ClientInformation.ServiceName
- DBServiceImage = ClientInformation.ServiceImage
- DBScope = ClientInformation.Scope
- }
- }
- if DBClientID == "" {
- errHandler(w, r, "client_id does not exist in our database.")
- }
- //check the record does it match
- if DBDomain != host {
- errHandler(w, r, "client_id and redirect_uri not match the system record.")
- }
- //check if scope is available for that client
- scopeArr := strings.Split(scope, " ")
- for _, scopeItem := range scopeArr {
- if !contains(DBScope, scopeItem) {
- errHandler(w, r, "scope not match our system record.")
- }
- }
- return DBClientSecret, DBDomain, DBServiceName, DBServiceImage, responseType, clientID, redirectURI, scope, state, nonce
- }
- func confirmUserInfo(w http.ResponseWriter, r *http.Request, username string) {
- }
- func getGET(w http.ResponseWriter, r *http.Request, name string) string {
- response, ok := r.URL.Query()[name]
- if !ok || len(response[0]) < 1 {
- errHandler(w, r, "Url param "+name+" was missing")
- }
- return response[0]
- }
- func templateLoad(filename string, replacement map[string]interface{}) (string, error) {
- content, err := ioutil.ReadFile(filename)
- if err != nil {
- return "", nil
- }
- t := fasttemplate.New(string(content), "{{", "}}")
- s := t.ExecuteString(replacement)
- return string(s), nil
- }
- //https://ispycode.com/GO/Collections/Arrays/Check-if-item-is-in-array
- func contains(arr []string, str string) bool {
- for _, a := range arr {
- if a == str {
- return true
- }
- }
- return false
- }
|