[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[taler-taldir] 01/01: Initial commit
From: |
gnunet |
Subject: |
[taler-taldir] 01/01: Initial commit |
Date: |
Sun, 17 Apr 2022 19:24:41 +0200 |
This is an automated email from the git hooks/post-receive script.
martin-schanzenbach pushed a commit to branch master
in repository taldir.
commit 8beaa21429a1b3f72a36b5d9059f7721b54340e9
Author: Martin Schanzenbach <mschanzenbach@posteo.de>
AuthorDate: Sun Apr 17 19:24:17 2022 +0200
Initial commit
---
Dockerfile | 8 +++
config.json | 6 ++
go.mod | 11 ++++
taldir.go | 201 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
4 files changed, 226 insertions(+)
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..5047824
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,8 @@
+FROM golang:1.16.15-alpine AS build
+WORKDIR /src
+ENV CGO_ENABLED=0
+COPY . .
+RUN go build -o /out/taldir .
+
+FROM scratch AS bin
+COPY --from=build /out/taldir /
diff --git a/config.json b/config.json
new file mode 100644
index 0000000..8b2d4bb
--- /dev/null
+++ b/config.json
@@ -0,0 +1,6 @@
+{
+ "production": false,
+ "db_backend": "sqlite",
+ "validators": ["email","phone"],
+ "email_sender": "taldir@taler.net"
+}
diff --git a/go.mod b/go.mod
new file mode 100644
index 0000000..ca035d8
--- /dev/null
+++ b/go.mod
@@ -0,0 +1,11 @@
+module taler.net/taldir
+
+go 1.16
+
+require (
+ github.com/gorilla/mux v1.8.0 // indirect
+ github.com/jinzhu/now v1.1.5 // indirect
+ github.com/mattn/go-sqlite3 v1.14.12 // indirect
+ gorm.io/driver/sqlite v1.3.1 // indirect
+ gorm.io/gorm v1.23.4 // indirect
+)
diff --git a/taldir.go b/taldir.go
new file mode 100644
index 0000000..c2227d7
--- /dev/null
+++ b/taldir.go
@@ -0,0 +1,201 @@
+package main
+
+import (
+ "os"
+ "fmt"
+ "log"
+ "net/http"
+ "encoding/json"
+ "github.com/gorilla/mux"
+ "gorm.io/gorm"
+ "gorm.io/driver/sqlite"
+ "encoding/base32"
+ "math/rand"
+ "net/smtp"
+)
+
+type Validator interface {
+ TriggerValidation() string
+}
+
+type Configuration struct {
+ Production bool
+ DbBackend string `json:"db_backend"`
+ Validators []string
+ EmailSender string `json:"email_sender"`
+}
+
+type Entry struct {
+ gorm.Model
+ IdentityKey string `json:"identity_key"`
+ IdentityKeyType string `json:"identity_key_type"`
+ TalerWalletKey string `json:"taler_wallet_key"`
+ Status string `json:"status"`
+}
+
+type Validation struct {
+ gorm.Model
+ IdentityKey string `json:"identity_key"`
+ IdentityKeyType string `json:"type"`
+ ValidationReference string `json:"reference"`
+}
+
+
+// let's declare a global Articles array
+// that we can then populate in our main function
+// to simulate a database
+var Entries []Entry
+
+var db *gorm.DB
+
+var config Configuration
+
+func sendEmail(recipient string, ref Validation) {
+
+ from := config.EmailSender
+ to := []string{
+ recipient,
+ }
+
+ // smtp server configuration.
+ smtpHost := "localhost"
+ smtpPort := "587"
+
+ // Message.
+ message := []byte("Please click here to validate your Taldir identity: " +
ref.ValidationReference)
+
+ // Sending email.
+ err := smtp.SendMail(smtpHost+":"+smtpPort, nil, from, to, message)
+ if err != nil {
+ fmt.Println(err)
+ return
+ }
+ fmt.Println("Email Sent Successfully!")
+}
+
+func returnSingleEntry(w http.ResponseWriter, r *http.Request){
+ vars := mux.Vars(r)
+ // Loop over all of our Articles
+ // if the article.Id equals the key we pass in
+ // return the article encoded as JSON
+ var entry Entry
+ var err = db.First(&entry, "identity_key = ?", vars["identity_key"]).Error
+ if err == nil {
+ w.Header().Set("Content-Type", "application/json")
+ json.NewEncoder(w).Encode(entry)
+ return
+ }
+ w.WriteHeader(http.StatusNotFound)
+}
+
+func validateSingleEntry(w http.ResponseWriter, r *http.Request){
+ vars := mux.Vars(r)
+ var entry Entry
+ var ref Validation
+ //TODO actually validate
+ var err = db.First(&ref, "validation_reference = ?", vars["reference"]).Error
+ if err != nil {
+ w.WriteHeader(http.StatusNotFound)
+ }
+ err = db.First(&entry, "identity_key = ?", entry.IdentityKey).Error
+ if err != nil {
+ w.WriteHeader(http.StatusNotFound)
+ }
+ err = db.Model(&entry).Update("status", "validated").Error
+ if err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ }
+}
+
+func generateToken() string {
+ randBytes := make([]byte, 32)
+ _, err := rand.Read(randBytes)
+ if err != nil {
+ panic(err)
+ }
+ return base32.StdEncoding.EncodeToString(randBytes)
+}
+
+func addSingleEntry(w http.ResponseWriter, r *http.Request){
+ // Loop over all of our Articles
+ // if the article.Id equals the key we pass in
+ // return the article encoded as JSON
+ var entry Entry
+ if r.Body == nil {
+ http.Error(w, "No request body", 400)
+ return
+ }
+ err := json.NewDecoder(r.Body).Decode(&entry)
+ if err != nil {
+ http.Error(w, err.Error(), 400)
+ return
+ }
+ ref := Validation{IdentityKey: entry.IdentityKey, ValidationReference:
generateToken() }
+ fmt.Println("Got ID key:", entry.IdentityKey)
+ err = db.First(&entry, "identity_key = ?", entry.IdentityKey).Error
+ if err == nil {
+ w.WriteHeader(http.StatusConflict)
+ return
+ }
+ entry.Status = "unvalidated"
+ err = db.Create(&entry).Error
+ if err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+ err = db.Create(&ref).Error
+ if err != nil {
+ w.WriteHeader(http.StatusInternalServerError)
+ return
+ }
+ fmt.Println("Validation reference created:", ref)
+ sendEmail(ref.IdentityKey, ref)
+ json.NewEncoder(w).Encode(entry)
+}
+
+
+
+func handleRequests() {
+ // creates a new instance of a mux router
+ myRouter := mux.NewRouter().StrictSlash(true)
+ // replace http.HandleFunc with myRouter.HandleFunc
+ myRouter.HandleFunc("/directory/{id}", returnSingleEntry).Methods("GET")
+ myRouter.HandleFunc("/validation/{reference}",
validateSingleEntry).Methods("POST")
+ myRouter.HandleFunc("/directory/", addSingleEntry).Methods("POST")
+ // finally, instead of passing in nil, we want
+ // to pass in our newly created router as the second
+ // argument
+ log.Fatal(http.ListenAndServe(":10000", myRouter))
+}
+
+func main() {
+ file, _ := os.Open("config.json")
+ defer file.Close()
+ decoder := json.NewDecoder(file)
+ config := Configuration{}
+ err := decoder.Decode(&config)
+ if err != nil {
+ fmt.Println("error:", err)
+ }
+ fmt.Println("Configuration:", config)
+ _db, err := gorm.Open(sqlite.Open("./taldir.db"), &gorm.Config{})
+ if err != nil {
+ panic(err)
+ }
+ db = _db
+ if err := db.AutoMigrate(&Entry{}); err != nil {
+ panic(err)
+ }
+ if err := db.AutoMigrate(&Validation{}); err != nil {
+ panic(err)
+ }
+ var entry Entry;
+ db.Create(&Entry{IdentityKey: "jdoe@example.com", IdentityKeyType: "email",
TalerWalletKey: "OIU123"})
+ db.Create(&Entry{IdentityKey: "+12345678", IdentityKeyType: "phone",
TalerWalletKey: "OIU123"})
+ handleRequests()
+ db.First(&entry, "identity_key = ?", "jdoe@example.com")
+ db.Delete(&entry)
+ db.First(&entry, "identity_key = ?", "+12345678")
+ db.Delete(&entry)
+
+}
--
To stop receiving notification emails like this one, please contact
gnunet@gnunet.org.