Explorar o código

people can register, needs some clean-up now

Moritz Schmidt %!s(int64=9) %!d(string=hai) anos
pai
achega
6fc5826fc8

+ 69 - 29
main.go

@@ -7,6 +7,7 @@ import (
   "git.mmnx.de/Moe/databaseutils"
   "git.mmnx.de/Moe/usermanager"
   "git.mmnx.de/Moe/configutils"
+  "git.mmnx.de/Moe/templatehelpers"
   "golang.org/x/crypto/bcrypt"
   "errors"
 )
@@ -54,11 +55,13 @@ func main() {
   iris.Static("/img", "./static/img", 1)
   iris.Static("/static", "./static/static", 1)
 
-  iris.Post("/login", loginHandler) // login form handler
+  iris.Post("/login", loginHandler) // login form handler // TODO: outsource ?
+  iris.Post("/register", registerHandler) // TODO outsource ?
   iris.Post("/account", usermanager.AuthHandler, accountUpdateHandler)
   iris.Post("/admin", usermanager.AuthHandler, usermanager.AdminHandler, adminPostHandler)
 
-  iris.Get("/login", templateHandler)
+  iris.Get("/login", templateHandler) // TODO not when logged in
+  iris.Get("/register", templateHandler) // TODO not when logged in
 	iris.Get("/", usermanager.AuthHandler, templateHandler)
   iris.Get("/account", usermanager.AuthHandler, templateHandler)
   iris.Get("/help", usermanager.AuthHandler, templateHandler)
@@ -85,6 +88,49 @@ func loginHandler(ctx *iris.Context) {
   }
 }
 
+func registerHandler(ctx *iris.Context) {
+  token := ctx.FormValueString("token") // POST values from login form
+  username := ctx.FormValueString("username")
+  password := ctx.FormValueString("password")
+
+  user := usermanager.User{} // new user
+
+  tokens := usermanager.GetTokens(false) // get all unused tokens
+  validToken := false
+  for i, _ := range tokens {
+    if token == tokens[i] {
+      validToken = true
+      break
+    }
+  }
+  if !validToken { // token not valid
+    templatehelpers.ShowError(usermanager.ERR_INVALID_TOKEN, ctx, "register")
+  }
+
+  userID := usermanager.SearchUserByUsernameInDB(username) // check if a user with that name already exists
+  if userID != -1 {
+    templatehelpers.ShowError(usermanager.ERR_USERNAME_TAKEN, ctx, "register")
+  }
+
+  passwordBin, _ := bcrypt.GenerateFromPassword([]byte(password), 15) // hash password
+
+  err := usermanager.RegisterUserWithToken(username, string(passwordBin), token) // register user
+  if err != nil {
+    templatehelpers.ShowError(err.Error(), ctx, "register")
+    return
+  }
+
+  tokenString, err := user.Login(username, password) // try to login
+
+  if err != nil {
+    templatehelpers.ShowError(err.Error(), ctx, "login")
+  } else {
+    ctx.SetCookieKV("token", tokenString)
+    ctx.Redirect("/")
+    // TODO: error-alternative success (main.html)
+  }
+}
+
 func accountUpdateHandler(ctx *iris.Context) { // TODO tidy up?
   err := errors.New(""); err = nil
   username := ctx.FormValueString("username") // POST values
@@ -94,7 +140,7 @@ func accountUpdateHandler(ctx *iris.Context) { // TODO tidy up?
   user := (*usermanager.Users)[usersArrayID] // user must be logged in to do this -> get from users list
 
   if username != "" && usermanager.SearchUserByUsername(username) != -1 && username != user.Username { // username can't be changed as there already exists a user with that name or it's the old name
-    ctx.Render("account_box.html", usermanager.PageUserParams{"1", errors.New("Username already taken").Error(), "account", user.Username, user.Mail, user.Admin, []string{"ayy", "lmao"}})
+    ctx.Render("account_box.html", usermanager.PageUserParams{"1", errors.New("Username already taken").Error(), "account", user.Username, user.Admin, []string{"ayy", "lmao"}})
     return
   }
 
@@ -112,19 +158,19 @@ func accountUpdateHandler(ctx *iris.Context) { // TODO tidy up?
     needQuery = true
     hashedPassword, err = func (hashedPassword []byte, err error) (string, error) { // hash password, we use an anonymous function to convert it to string
       if err != nil { // should never happen
-        ctx.Render("account_box.html", usermanager.PageUserParams{"1", err.Error(), "account", user.Username, user.Mail, user.Admin, []string{"ayy", "lmao"}})
+        ctx.Render("account_box.html", usermanager.PageUserParams{"1", err.Error(), "account", user.Username, user.Admin, []string{"ayy", "lmao"}})
         return "", err
       }
       return string(hashedPassword), nil
     }(bcrypt.GenerateFromPassword([]byte(password), 15)) // this is the actual hashing call
     if err != nil { // should never happen
-      ctx.Render("account_box.html", usermanager.PageUserParams{"1", err.Error(), "account", user.Username, user.Mail, user.Admin, []string{"ayy", "lmao"}})
+      ctx.Render("account_box.html", usermanager.PageUserParams{"1", err.Error(), "account", user.Username, user.Admin, []string{"ayy", "lmao"}})
       return
     }
   }
 
   if !needQuery { // we don't need to update anything
-    ctx.Render("account_box.html", usermanager.PageUserParams{"1", errors.New("nothing to update").Error(), "account", user.Username, user.Mail, user.Admin, []string{"ayy", "lmao"}})
+    ctx.Render("account_box.html", usermanager.PageUserParams{"1", errors.New("nothing to update").Error(), "account", user.Username, user.Admin, []string{"ayy", "lmao"}})
     return
   }
 
@@ -133,16 +179,16 @@ func accountUpdateHandler(ctx *iris.Context) { // TODO tidy up?
 
   err = (*usermanager.Users)[usermanager.SearchUser(userID)].Update() // try to update in db
   if err != nil { // failed to update
-    ctx.Render("account_box.html", usermanager.PageUserParams{"1", err.Error(), "account", user.Username, user.Mail, user.Admin, []string{"ayy", "lmao"}})
+    ctx.Render("account_box.html", usermanager.PageUserParams{"1", err.Error(), "account", user.Username, user.Admin, []string{"ayy", "lmao"}})
     return
   }
 
   // TODO success notifications
 
   if err != nil {
-    ctx.Render("account_box.html", usermanager.PageUserParams{"1", err.Error(), "account", user.Username, user.Mail, user.Admin, []string{"ayy", "lmao"}}) // TODO dynamic
+    ctx.Render("account_box.html", usermanager.PageUserParams{"1", err.Error(), "account", user.Username, user.Admin, []string{"ayy", "lmao"}}) // TODO dynamic
   } else {
-    ctx.Render("account_box.html", usermanager.PageUserParams{"0", "", "account", user.Username, user.Mail, user.Admin, []string{"ayy", "lmao"}}) // TODO dynamic
+    ctx.Render("account_box.html", usermanager.PageUserParams{"0", "", "account", user.Username, user.Admin, []string{"ayy", "lmao"}}) // TODO dynamic
   }
 }
 
@@ -159,42 +205,36 @@ func templateHandler(ctx *iris.Context) {
   var params usermanager.PageUserParams
   userID := ctx.GetString("userID")
   user, err := usermanager.GetUser(userID)
-
-  if err != nil { // user is apparently not logged in -> login
-    ctx.MustRender("login_box.html", pageUserParams{"1", err.Error(), "login", "", "", "0"})
-    return
+  if err != nil {
+    if err.Error() != "User not logged in" {
+      fmt.Println(err.Error())
+    }
   }
 
   template := ""
   switch ctx.RequestPath(false) {
   default:
     template = "home"
-    params = usermanager.PageUserParams{"0", "", template, user.Username, "", user.Admin, []string{}}
+    params = usermanager.PageUserParams{"0", "", template, user.Username, user.Admin, []string{}}
   case "/":
     template = "home"
-    params = usermanager.PageUserParams{"0", "", template, user.Username, "", user.Admin, []string{}}
+    params = usermanager.PageUserParams{"0", "", template, user.Username, user.Admin, []string{}}
   case "/account":
     template = "account"
-    params = usermanager.PageUserParams{"0", "", template, user.Username, "", user.Admin, []string{}}
+    params = usermanager.PageUserParams{"0", "", template, user.Username, user.Admin, []string{}}
   case "/help":
     template = "help"
-    params = usermanager.PageUserParams{"0", "", template, user.Username, "", user.Admin, []string{}}
+    params = usermanager.PageUserParams{"0", "", template, user.Username, user.Admin, []string{}}
   case "/admin":
     template = "admin"
-    tokens, err := databaseutils.DBUtil.GetRows("*", "tokens", "used", "0") // get unused tokens // TODO: outsource in function GetTokens()
-    if err != nil {
-      fmt.Println(err.Error()) // TODO: nicer / outsource
-    }
-
-    message := "" // string for textarea output in /admin
-    for i, _ := range tokens { // TODO outsource
-      message += tokens[i][1] + "\n"
-    } // TODO outsource function until here
-
-    params = usermanager.PageUserParams{"0", "", template, user.Username, "", user.Admin, []string{message}}
+    tokens := usermanager.GetTokens(false)
+    params = usermanager.PageUserParams{"0", "", template, user.Username, user.Admin, tokens}
   case "/login":
     template = "login"
-    params = usermanager.PageUserParams{"0", "", template, "", "", "0", []string{"ayy", "lmao"}}
+    params = usermanager.PageUserParams{"0", "", template, "", "0", []string{"ayy", "lmao"}}
+  case "/register":
+    template = "register"
+    params = usermanager.PageUserParams{"0", "", template, "", "0", []string{}}
   }
 
 

+ 11 - 0
static/css/narrow-jumbotron.css

@@ -148,6 +148,17 @@ textarea#tokens {
   height: 200px;
 }
 
+#token {
+  max-width: 250px;
+  position: absolute;
+  top: 47px;
+  left: calc(50% - 125px);
+}
+
+.btn-block {
+  position: relative;
+}
+
 /* Responsive: Portrait tablets and up */
 @media screen and (min-width: 48em) {
   /* Remove the padding we set earlier */

+ 1 - 0
static/img/sources.txt

@@ -2,3 +2,4 @@ mmnx_vpn.png: gab
 tux.png: https://www.kernel.org/theme/images/logos/tux.png
 windows.png: https://www.pcper.com/files/news/2015-04-10/windows_8_logo-redux2.png
 android.png: https://image.freepik.com/vektoren-kostenlos/android-boot-logo_634639.jpg
+token.png: http://southparkstudios.mtvnimages.com/shared/characters/kids/token-black.png

BIN=BIN
static/img/token.png


+ 0 - 39
templates/account_box.html

@@ -5,51 +5,12 @@
             <input type="text" class="form-control" id="inputUsername3" name="username" placeholder="{{ .Username }}">
           </div>
         </div>
-        <!--<div class="form-group row">
-          <label for="inputEmail3" class="col-sm-2 col-form-label">email</label>
-          <div class="col-sm-10">
-            <input type="email" class="form-control" id="inputEmail3" placeholder="{{ .Email }}">
-          </div>
-        </div>-->
         <div class="form-group row">
           <label for="inputPassword3" class="col-sm-2 col-form-label">passwort</label>
           <div class="col-sm-10">
             <input type="password" class="form-control" id="inputPassword3" name="password" placeholder="passwort">
           </div>
         </div>
-        <!--<fieldset class="form-group row">
-          <legend class="col-form-legend col-sm-2">Radios</legend>
-          <div class="col-sm-10">
-            <div class="form-check">
-              <label class="form-check-label">
-                <input class="form-check-input" type="radio" name="gridRadios" id="gridRadios1" value="option1" checked>
-                Option one is this and that&mdash;be sure to include why it's great
-              </label>
-            </div>
-            <div class="form-check">
-              <label class="form-check-label">
-                <input class="form-check-input" type="radio" name="gridRadios" id="gridRadios2" value="option2">
-                Option two can be something else and selecting it will deselect option one
-              </label>
-            </div>
-            <div class="form-check disabled">
-              <label class="form-check-label">
-                <input class="form-check-input" type="radio" name="gridRadios" id="gridRadios3" value="option3" disabled>
-                Option three is disabled
-              </label>
-            </div>
-          </div>
-        </fieldset>
-        <div class="form-group row">
-          <label class="col-sm-2">Checkbox</label>
-          <div class="col-sm-10">
-            <div class="form-check">
-              <label class="form-check-label">
-                <input class="form-check-input" type="checkbox"> Check me out
-              </label>
-            </div>
-          </div>
-        </div>-->
         <div class="form-group row">
           <div class="offset-sm-2 col-sm-10">
             <button type="submit" class="btn btn-primary">speichern</button>

+ 1 - 1
templates/admin_box.html

@@ -6,7 +6,7 @@
         </div>
         <div class="form-group row">
           <div class="col-sm-12">
-            <textarea class="form-control" id="tokens" name="tokens" placeholder="noch keine vorhanden">{{ range .Custom }}{{ . }}{{ end }}</textarea>
+            <textarea class="form-control" id="tokens" name="tokens" placeholder="noch keine vorhanden">{{ range .Custom }}{{ . }}{{ printf "\n" }}{{ end }}</textarea>
           </div>
         </div>
       </form>

+ 18 - 0
templates/register_box.html

@@ -0,0 +1,18 @@
+<div class="relcontainer">
+  <img id="token" src="/img/token.png" class="img-responsive" alt="token" title="token">
+</div>
+<form class="form-signin" action="/register" method="post">
+  <!--<h2 class="form-signin-heading">ayy</h2>-->
+  <label for="input-token" class="sr-only">token</label>
+  <input type="text" id="input-token" name="token" class="form-control" placeholder="token" required autofocus>
+  <label for="input-username" class="sr-only">username</label>
+  <input type="text" id="input-username" name="username" class="form-control" placeholder="username" required>
+  <label for="input-password" class="sr-only">passwort</label>
+  <input type="password" id="input-password" name="password" class="form-control" placeholder="password" required>
+  <!--<div class="checkbox">
+    <label>
+      <input type="checkbox" value="remember-me"> Remember me
+    </label>
+  </div> always remembering -->
+  <button class="btn btn-lg btn-primary btn-block" type="submit">registrieren</button>
+</form>