focalboard/server/api/auth.go

170 lines
4.3 KiB
Go
Raw Normal View History

2020-11-06 16:46:35 +01:00
package api
import (
2020-12-02 21:12:14 +01:00
"context"
2020-11-06 16:46:35 +01:00
"encoding/json"
"errors"
"io/ioutil"
"log"
"net/http"
"strings"
2020-12-04 11:28:35 +01:00
"time"
2020-12-02 21:12:14 +01:00
2020-12-04 11:28:35 +01:00
"github.com/mattermost/mattermost-octo-tasks/server/model"
2020-12-02 21:12:14 +01:00
"github.com/mattermost/mattermost-octo-tasks/server/services/auth"
2020-11-06 16:46:35 +01:00
)
type LoginData struct {
Type string `json:"type"`
Username string `json:"username"`
Email string `json:"email"`
Password string `json:"password"`
MfaToken string `json:"mfa_token"`
}
type RegisterData struct {
Username string `json:"username"`
Email string `json:"email"`
Password string `json:"password"`
2021-01-14 01:56:01 +01:00
Token string `json:"token"`
2020-11-06 16:46:35 +01:00
}
func (rd *RegisterData) IsValid() error {
if rd.Username == "" {
return errors.New("Username is required")
}
if rd.Email == "" {
return errors.New("Email is required")
}
if !strings.Contains(rd.Email, "@") {
return errors.New("Invalid email format")
}
if !strings.Contains(rd.Password, "") {
return errors.New("Password is required")
}
return nil
}
func (a *API) handleLogin(w http.ResponseWriter, r *http.Request) {
requestBody, err := ioutil.ReadAll(r.Body)
if err != nil {
2021-01-14 19:03:01 +01:00
errorResponse(w, http.StatusInternalServerError, nil, err)
2020-11-06 16:46:35 +01:00
return
}
var loginData LoginData
err = json.Unmarshal(requestBody, &loginData)
if err != nil {
2021-01-14 19:03:01 +01:00
errorResponse(w, http.StatusInternalServerError, nil, err)
2020-11-06 16:46:35 +01:00
return
}
if loginData.Type == "normal" {
2020-12-04 16:03:09 +01:00
token, err := a.app().Login(loginData.Username, loginData.Email, loginData.Password, loginData.MfaToken)
2020-11-06 16:46:35 +01:00
if err != nil {
2021-01-14 19:03:01 +01:00
errorResponse(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}, err)
2020-11-06 16:46:35 +01:00
return
}
2020-12-04 16:03:09 +01:00
json, err := json.Marshal(map[string]string{"token": token})
2020-11-06 16:46:35 +01:00
if err != nil {
2021-01-14 19:03:01 +01:00
errorResponse(w, http.StatusInternalServerError, nil, err)
2020-11-06 16:46:35 +01:00
return
}
jsonBytesResponse(w, http.StatusOK, json)
2020-12-02 21:12:14 +01:00
return
2020-11-06 16:46:35 +01:00
}
2021-01-14 19:03:01 +01:00
errorResponse(w, http.StatusInternalServerError, map[string]string{"error": "Unknown login type"}, nil)
2020-11-06 16:46:35 +01:00
}
func (a *API) handleRegister(w http.ResponseWriter, r *http.Request) {
requestBody, err := ioutil.ReadAll(r.Body)
if err != nil {
2021-01-14 19:03:01 +01:00
errorResponse(w, http.StatusInternalServerError, nil, err)
2020-11-06 16:46:35 +01:00
return
}
var registerData RegisterData
err = json.Unmarshal(requestBody, &registerData)
if err != nil {
2021-01-14 19:03:01 +01:00
errorResponse(w, http.StatusInternalServerError, nil, err)
2020-11-06 16:46:35 +01:00
return
}
2021-01-14 01:56:01 +01:00
// Validate token
if len(registerData.Token) > 0 {
workspace, err := a.app().GetRootWorkspace()
if err != nil {
2021-01-14 19:03:01 +01:00
errorResponse(w, http.StatusInternalServerError, nil, err)
2021-01-14 01:56:01 +01:00
return
}
if registerData.Token != workspace.SignupToken {
2021-01-14 19:03:01 +01:00
errorResponse(w, http.StatusUnauthorized, nil, nil)
2021-01-14 01:56:01 +01:00
return
}
} else {
// No signup token, check if no active users
userCount, err := a.app().GetActiveUserCount()
if err != nil {
2021-01-14 19:03:01 +01:00
errorResponse(w, http.StatusInternalServerError, nil, err)
2021-01-14 01:56:01 +01:00
return
}
if userCount > 0 {
2021-01-14 19:03:01 +01:00
errorResponse(w, http.StatusUnauthorized, nil, nil)
2021-01-14 01:56:01 +01:00
return
}
}
2020-11-06 16:46:35 +01:00
if err = registerData.IsValid(); err != nil {
2021-01-14 19:03:01 +01:00
errorResponse(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}, err)
2020-11-06 16:46:35 +01:00
return
}
err = a.app().RegisterUser(registerData.Username, registerData.Email, registerData.Password)
if err != nil {
2021-01-14 19:03:01 +01:00
errorResponse(w, http.StatusInternalServerError, map[string]string{"error": err.Error()}, err)
2020-11-06 16:46:35 +01:00
return
}
2021-01-14 01:56:01 +01:00
2020-11-06 16:46:35 +01:00
jsonBytesResponse(w, http.StatusOK, nil)
}
2020-12-02 21:12:14 +01:00
func (a *API) sessionRequired(handler func(w http.ResponseWriter, r *http.Request)) func(w http.ResponseWriter, r *http.Request) {
2021-01-13 03:49:08 +01:00
return a.attachSession(handler, true)
}
func (a *API) attachSession(handler func(w http.ResponseWriter, r *http.Request), required bool) func(w http.ResponseWriter, r *http.Request) {
2020-12-02 21:12:14 +01:00
return func(w http.ResponseWriter, r *http.Request) {
2020-12-04 16:03:09 +01:00
log.Printf(`Single User: %v`, a.singleUser)
2020-12-04 11:28:35 +01:00
if a.singleUser {
now := time.Now().Unix()
session := &model.Session{
ID: "single-user",
Token: "single-user",
UserID: "single-user",
CreateAt: now,
UpdateAt: now,
}
ctx := context.WithValue(r.Context(), "session", session)
handler(w, r.WithContext(ctx))
return
}
2020-12-02 21:12:14 +01:00
token, _ := auth.ParseAuthTokenFromRequest(r)
session, err := a.app().GetSession(token)
if err != nil {
2021-01-13 03:49:08 +01:00
if required {
2021-01-14 19:03:01 +01:00
errorResponse(w, http.StatusUnauthorized, map[string]string{"error": err.Error()}, err)
2021-01-13 03:49:08 +01:00
return
}
handler(w, r)
2020-12-02 21:12:14 +01:00
return
}
ctx := context.WithValue(r.Context(), "session", session)
handler(w, r.WithContext(ctx))
}
}