github.com/oweisse/u-root@v0.0.0-20181109060735-d005ad25fef1/cmds/upspinsos/server.go (about)

     1  // Copyright 2018 the u-root Authors. All rights reserved
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  package main
     6  
     7  import (
     8  	"encoding/json"
     9  	"fmt"
    10  	"html/template"
    11  	"io/ioutil"
    12  	"log"
    13  	"net/http"
    14  
    15  	"github.com/gorilla/mux"
    16  	"github.com/u-root/u-root/pkg/sos"
    17  )
    18  
    19  const (
    20  	DefHtmlPage = `
    21  	<head>
    22  	<style>
    23  	  table {
    24  	    font-family: arial, sans-serif;
    25  	    border-collapse: collapse;
    26  	    width: 100%;
    27  	  }
    28  	  td, th {
    29  	    border: 1px solid #dddddd;
    30  	    text-align: left;
    31  	    padding: 8px;
    32  	  }
    33  	  input {
    34  	    font-size: 120%;
    35  	  }
    36  	</style>
    37  	<script>
    38  	  function sendEdit() {
    39  	    fetch("http://localhost:{{.Port}}/edit", {
    40  	      method: 'Post'
    41  	    })
    42  	    .then(r => r.json())
    43  	    .then( s => {
    44  	      if (s !== null) {
    45  	        alert(s.Error);
    46  	        window.location.reload();
    47  	      }
    48  	      else {
    49  	        window.location.reload();
    50  	      }
    51  	    })
    52  	    .catch(err => alert(err))
    53  	  }
    54  	  function sendSubmit() {
    55  	    username = document.getElementById("user").value
    56  	    dirserver = document.getElementById("dir").value
    57  	    storeserver = document.getElementById("store").value
    58  	    secretseed = document.getElementById("seed").value
    59  	    fetch("http://localhost:{{.Port}}/submit", {
    60  	      method: 'Post',
    61  	      headers: {
    62  	  			'Accept': 'application/json',
    63  	  			'Content-Type': 'application/json'
    64  	  		},
    65  	  		body: JSON.stringify({
    66  	  			User:  username,
    67  	  			Dir:   dirserver,
    68  	        Store: storeserver,
    69  	        Seed:  secretseed
    70  	  		})
    71  	    })
    72  	    .then(r => r.json())
    73  	    .then( s => {
    74  	      if (s !== null) {
    75  	        alert(s.Error);
    76  	        window.location.reload();
    77  	      }
    78  	      else {
    79  	        window.location.reload();
    80  	      }
    81  	    })
    82  	    .catch(err => alert(err))
    83  	  }
    84  
    85  	  function setFieldsOnLoad(config) {
    86  	    if (config) {
    87  	      disableFields();
    88  	    }
    89  	    else {
    90  	      enableFields();
    91  	    }
    92  	  }
    93  
    94  	  function enableFields() {
    95  	    fields = document.getElementsByClassName("text");
    96  	    for(let field of fields) {
    97  	      field.removeAttribute("disabled")
    98  	    }
    99  	    document.getElementById("button").setAttribute("value", "Submit");
   100  	    document.getElementById("button").setAttribute("onclick", "sendSubmit()");
   101  	  }
   102  	  function disableFields() {
   103  	    fields = document.getElementsByClassName("text");
   104  	    for(let field of fields) {
   105  	      field.setAttribute("disabled", "true")
   106  	    }
   107  	    document.getElementById("button").setAttribute("value", "Edit");
   108  	    document.getElementById("button").setAttribute("onclick", "sendEdit()");
   109  	  }
   110  
   111  	</script>
   112  	</head>
   113  	<body onload="setFieldsOnLoad({{.Configured}})">
   114  	  <!-- Copy to local variables -->
   115  	  {{$user := .User}}
   116  	  {{$dir := .Dir}}
   117  	  {{$store := .Store}}
   118  	  {{$seed := .Seed}}
   119  	  <h1>Upspin</h1>
   120  	  <table style="width:100%">
   121  	    <tr>
   122  	      <th>Username</th>
   123  	      <th>Dir Server</th>
   124  	      <th>Store Server</th>
   125  	      <th>Secret Seed</th>
   126  	      <th></th>
   127  	    </tr>
   128  	    <tr>
   129  	      <td><input type="text" id="user"  class="text" value="{{$user}}"></td>
   130  	      <td><input type="text" id="dir"   class="text" value="{{$dir}}"></td>
   131  	      <td><input type="text" id="store" class="text" value="{{$store}}"></td>
   132  	      <td><input type="text" id="seed"  class="text" value="{{$seed}}"></td>
   133  	      <td><input type="submit" id="button" class="btn"></td>
   134  	    </tr>
   135  	  </table>
   136  	</body>
   137  `
   138  )
   139  
   140  type UpspinServer struct {
   141  	service *UpspinService
   142  }
   143  
   144  var (
   145  	Port uint
   146  )
   147  
   148  func (us *UpspinServer) editHandle(w http.ResponseWriter, r *http.Request) {
   149  	us.service.ToggleFlag()
   150  	json.NewEncoder(w).Encode(nil)
   151  }
   152  
   153  type UpspinAcctJsonMsg struct {
   154  	User  string
   155  	Dir   string
   156  	Store string
   157  	Seed  string
   158  }
   159  
   160  func (us *UpspinServer) submitHandle(w http.ResponseWriter, r *http.Request) {
   161  	us.service.ToggleFlag()
   162  	var msg UpspinAcctJsonMsg
   163  	decoder := json.NewDecoder(r.Body)
   164  	defer r.Body.Close()
   165  	if err := decoder.Decode(&msg); err != nil {
   166  		log.Printf("error: %v", err)
   167  		w.WriteHeader(http.StatusBadRequest)
   168  		json.NewEncoder(w).Encode(struct{ Error string }{err.Error()})
   169  		return
   170  	}
   171  	if err := us.service.SetConfig(msg); err != nil {
   172  		log.Printf("error: %v", err)
   173  		w.WriteHeader(http.StatusInternalServerError)
   174  		json.NewEncoder(w).Encode(struct{ Error string }{err.Error()})
   175  		return
   176  	}
   177  	json.NewEncoder(w).Encode(nil)
   178  }
   179  
   180  func (us *UpspinServer) displayStateHandle(w http.ResponseWriter, r *http.Request) {
   181  	us.service.Update()
   182  	upspinData := struct {
   183  		Configured bool
   184  		User       string
   185  		Dir        string
   186  		Store      string
   187  		Seed       string
   188  		Port       uint
   189  	}{us.service.Configured, us.service.User, us.service.Dir, us.service.Store, us.service.Seed, Port}
   190  	var tmpl *template.Template
   191  	file, err := ioutil.ReadFile(sos.HTMLPath("upspin.html"))
   192  	if err == nil {
   193  		html := string(file)
   194  		tmpl = template.Must(template.New("SoS").Parse(html))
   195  	} else {
   196  		tmpl = template.Must(template.New("SoS").Parse(DefHtmlPage))
   197  	}
   198  	tmpl.Execute(w, upspinData)
   199  }
   200  
   201  func (us *UpspinServer) buildRouter() *mux.Router {
   202  	r := mux.NewRouter()
   203  	r.HandleFunc("/", us.displayStateHandle).Methods("GET")
   204  	r.HandleFunc("/edit", us.editHandle).Methods("POST")
   205  	r.HandleFunc("/submit", us.submitHandle).Methods("POST")
   206  	r.PathPrefix("/css/").Handler(http.StripPrefix("/css/", http.FileServer(http.Dir(sos.HTMLPath("css")))))
   207  	return r
   208  }
   209  
   210  func (us *UpspinServer) Start() {
   211  	listener, port, err := sos.GetListener()
   212  	if err != nil {
   213  		log.Fatalf("error: %v", err)
   214  	}
   215  	Port = port
   216  	fmt.Println(sos.StartServiceServer(us.buildRouter(), "upspin", listener, Port))
   217  }
   218  
   219  func NewUpspinServer(service *UpspinService) *UpspinServer {
   220  	return &UpspinServer{
   221  		service: service,
   222  	}
   223  }