Example #1
0
File: api.go Project: siim-/siil
//Provide information about the active id card user
func handleAPIMeRequest(rw http.ResponseWriter, rq *http.Request) {
	switch rq.Method {
	case "GET":
		if !cert.ClientVerified(rq) {
			http.Error(rw, "Certificate not provided", http.StatusBadRequest)
		} else {
			if c, err := cert.NewCertFromRequest(rq); err != nil {
				http.Error(rw, "Certificate not provided", http.StatusBadRequest)
			} else {
				if clientId := rq.FormValue("client_id"); len(clientId) == 0 {
					http.Error(rw, "Invalid client_id provided", http.StatusBadRequest)
				} else {
					//Check origin header validity
					if origin := rq.Header.Get("Origin"); len(origin) != 0 {
						if u, err := url.Parse(origin); err != nil {
							http.Error(rw, "Invalid origin provided", http.StatusBadRequest)
							return
						} else {
							s := site.Entity{Domain: u.Host}
							if err := s.Load(); err == nil && s.ClientId == clientId {
								rw.Header().Set("Access-Control-Allow-Origin", origin)
								rw.Header().Set("Access-Control-Allow-Methods", "GET")
								rw.Header().Set("Access-Control-Allow-Credentials", "true")
							} else {
								http.Error(rw, "Origin not allowed", http.StatusUnauthorized)
								return
							}
						}
					}
					s := site.Entity{ClientId: clientId}
					if err := s.Load(); err != nil {
						http.Error(rw, "Invalid client_id provided", http.StatusBadRequest)
						return
					}
					if usr, err := user.Find(c); err != nil {
						http.Error(rw, "Looks like we don't know you", http.StatusUnauthorized)
					} else {
						if s.HasActiveSessionFor(usr) {
							enc := json.NewEncoder(rw)
							rw.Header().Set("Content-Type", "application/json")
							if err := enc.Encode(usr); err != nil {
								log.Println(err)
								http.Error(rw, "Failed to compose response", http.StatusInternalServerError)
							}
						} else {
							http.Error(rw, "Computer says no", http.StatusUnauthorized)
						}
					}
				}
			}
		}
	default:
		http.Error(rw, "Method not allowed", http.StatusMethodNotAllowed)
	}
}
Example #2
0
File: signin.go Project: siim-/siil
func handleSessionCreation(rw http.ResponseWriter, rq *http.Request) {
	reqVars := mux.Vars(rq)

	if rq.Method != "POST" {
		http.Error(rw, "Method not allowed", http.StatusMethodNotAllowed)
	} else if siteId, ok := reqVars["site"]; !ok {
		http.Error(rw, "Site ID must be provided", http.StatusBadRequest)
	} else {
		wanted := site.Entity{ClientId: siteId}
		if err := wanted.Load(); err != nil {
			log.Println(err)
			if strings.Contains(err.Error(), "no rows") {
				http.Error(rw, "Site not found", http.StatusNotFound)
			} else {
				http.Error(rw, "Something broke", http.StatusInternalServerError)
			}
			return
		}

		if !cert.ClientVerified(rq) {
			http.Error(rw, "Client certificate not provided. Please restart your browser to provide it.", http.StatusBadRequest)
		} else {
			if userCert, err := cert.NewCertFromRequest(rq); err != nil {
				log.Println(err)
				http.Error(rw, "Failed to parse your client cert", http.StatusBadRequest)
			} else {
				if userEntity, err := user.FindOrCreate(userCert); err != nil {
					log.Println(err)
					http.Error(rw, "Something broke", http.StatusInternalServerError)
				} else {
					if sess, err := session.NewSession(&wanted, userEntity); err != nil {
						log.Println(err)
						http.Error(rw, "Something broke", http.StatusInternalServerError)
					} else {
						if callback, err := url.Parse(wanted.CallbackURL); err != nil {
							http.Error(rw, "Invalid callback URL provided", http.StatusInternalServerError)
						} else {
							//Indicate signin action with GET parameter
							q := callback.Query()
							q.Set("siil_action", "signin")
							callback.RawQuery = q.Encode()
							if t, err := templates["success.hbs"].Exec(map[string]string{"token": sess.Token, "callback": callback.String()}); err != nil {
								log.Println(err)
								http.Error(rw, "Something broke", http.StatusInternalServerError)
							} else {
								rw.Write([]byte(t))
							}
						}
					}
				}
			}
		}
	}
}
Example #3
0
//Invalidate the session
func handleSignoutRequest(rw http.ResponseWriter, rq *http.Request) {
	if rq.Method != "POST" {
		http.Error(rw, "Invalid method", http.StatusMethodNotAllowed)
	} else {
		reqVars := mux.Vars(rq)
		if token, ok := reqVars["token"]; !ok || len(token) != session.TOKEN_LENGTH {
			http.Error(rw, "Bad token provided", http.StatusBadRequest)
		} else {
			if sess, err := session.GetSession(token); err != nil {
				http.Error(rw, "Session not found", http.StatusUnauthorized)
			} else {
				if !cert.ClientVerified(rq) {
					http.Error(rw, "Cert not provided", http.StatusBadRequest)
				} else {
					if userCert, err := cert.NewCertFromRequest(rq); err != nil {
						log.Println(err)
						http.Error(rw, "Failed to parse your client cert", http.StatusBadRequest)
					} else {
						if usr, err := user.Find(userCert); err != nil {
							log.Println(err)
							http.Error(rw, "We don't know you", http.StatusUnauthorized)
						} else {
							if usr.Id == sess.UserId {
								if err := sess.Delete(); err != nil {
									http.Error(rw, "Failed to end session", http.StatusInternalServerError)
								} else {
									wanted := site.Entity{ClientId: sess.SiteId}
									if err := wanted.Load(); err != nil {
										log.Println(err)
										if strings.Contains(err.Error(), "no rows") {
											http.Error(rw, "Site not found", http.StatusNotFound)
										} else {
											http.Error(rw, "Something broke", http.StatusInternalServerError)
										}
										return
									}
									if callback, err := url.Parse(wanted.CallbackURL); err != nil {
										http.Error(rw, "Invalid callback URL provided", http.StatusInternalServerError)
									} else {
										//Indicate signin action with GET parameter
										q := callback.Query()
										q.Set("siil_action", "signout")
										callback.RawQuery = q.Encode()
										if t, err := templates["success.hbs"].Exec(map[string]string{"token": sess.Token, "callback": callback.String()}); err != nil {
											log.Println(err)
											http.Error(rw, "Something broke", http.StatusInternalServerError)
										} else {
											rw.Write([]byte(t))
										}
									}
								}
							} else {
								http.Error(rw, "Session and user don't match", http.StatusBadRequest)
							}
						}
					}
				}
			}
		}
	}
}