You've already forked focalboard
							
							
				mirror of
				https://github.com/mattermost/focalboard.git
				synced 2025-10-31 00:17:42 +02:00 
			
		
		
		
	Check for single user token
This commit is contained in:
		| @@ -9,6 +9,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { | ||||
|  | ||||
| 	private var serverProcess: Process? | ||||
| 	var serverPort = 8088 | ||||
| 	var sessionToken: String = "" | ||||
|  | ||||
| 	func applicationDidFinishLaunching(_ aNotification: Notification) { | ||||
| 		copyResources() | ||||
| @@ -69,6 +70,8 @@ class AppDelegate: NSObject, NSApplicationDelegate { | ||||
| 	} | ||||
|  | ||||
| 	private func startServer() { | ||||
| 		sessionToken = UUID().uuidString | ||||
|  | ||||
| 		let cwdUrl = webFolder() | ||||
| 		let executablePath = Bundle.main.path(forResource: "resources/bin/focalboard-server", ofType: "") | ||||
|  | ||||
| @@ -76,7 +79,7 @@ class AppDelegate: NSObject, NSApplicationDelegate { | ||||
| 		NSLog("pid: \(pid)") | ||||
| 		let serverProcess = Process() | ||||
| 		serverProcess.currentDirectoryPath = cwdUrl.path | ||||
| 		serverProcess.arguments = ["-monitorpid", "\(pid)", "-port", "\(serverPort)", "--single-user"] | ||||
| 		serverProcess.arguments = ["-monitorpid", "\(pid)", "-port", "\(serverPort)", "-single-user", sessionToken] | ||||
| 		serverProcess.launchPath = executablePath | ||||
| 		serverProcess.launch() | ||||
| 		self.serverProcess = serverProcess | ||||
|   | ||||
| @@ -19,7 +19,6 @@ class ViewController: | ||||
| 		webView.uiDelegate = self | ||||
|  | ||||
| 		clearWebViewCache() | ||||
| 		loadHomepage() | ||||
|  | ||||
| 		// Do any additional setup after loading the view. | ||||
| 		NotificationCenter.default.addObserver(self, selector: #selector(onServerStarted), name: AppDelegate.serverStartedNotification, object: nil) | ||||
| @@ -40,10 +39,22 @@ class ViewController: | ||||
| 	@objc func onServerStarted() { | ||||
| 		NSLog("onServerStarted") | ||||
| 		DispatchQueue.main.asyncAfter(deadline: .now() + 0.5) { | ||||
| 			self.updateSessionToken() | ||||
| 			self.loadHomepage() | ||||
| 		} | ||||
| 	} | ||||
|  | ||||
| 	private func updateSessionToken() { | ||||
| 		let appDelegate = NSApplication.shared.delegate as! AppDelegate | ||||
| 		let script = WKUserScript( | ||||
| 			source: "localStorage.setItem('sessionId', '\(appDelegate.sessionToken)');", | ||||
| 			injectionTime: .atDocumentStart, | ||||
| 			forMainFrameOnly: true | ||||
| 		) | ||||
| 		webView.configuration.userContentController.removeAllUserScripts() | ||||
| 		webView.configuration.userContentController.addUserScript(script) | ||||
| 	} | ||||
|  | ||||
| 	private func loadHomepage() { | ||||
| 		let appDelegate = NSApplication.shared.delegate as! AppDelegate | ||||
| 		let port = appDelegate.serverPort | ||||
|   | ||||
| @@ -27,12 +27,15 @@ const ( | ||||
| // REST APIs | ||||
|  | ||||
| type API struct { | ||||
| 	appBuilder func() *app.App | ||||
| 	singleUser bool | ||||
| 	appBuilder      func() *app.App | ||||
| 	singleUserToken string | ||||
| } | ||||
|  | ||||
| func NewAPI(appBuilder func() *app.App, singleUser bool) *API { | ||||
| 	return &API{appBuilder: appBuilder, singleUser: singleUser} | ||||
| func NewAPI(appBuilder func() *app.App, singleUserToken string) *API { | ||||
| 	return &API{ | ||||
| 		appBuilder:      appBuilder, | ||||
| 		singleUserToken: singleUserToken, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| func (a *API) app() *app.App { | ||||
|   | ||||
| @@ -198,12 +198,19 @@ func (a *API) sessionRequired(handler func(w http.ResponseWriter, r *http.Reques | ||||
|  | ||||
| func (a *API) attachSession(handler func(w http.ResponseWriter, r *http.Request), required bool) func(w http.ResponseWriter, r *http.Request) { | ||||
| 	return func(w http.ResponseWriter, r *http.Request) { | ||||
| 		log.Printf(`Single User: %v`, a.singleUser) | ||||
| 		if a.singleUser { | ||||
| 		token, _ := auth.ParseAuthTokenFromRequest(r) | ||||
|  | ||||
| 		log.Printf(`Single User: %v`, len(a.singleUserToken) > 0) | ||||
| 		if len(a.singleUserToken) > 0 { | ||||
| 			if required && (token != a.singleUserToken) { | ||||
| 				errorResponse(w, http.StatusUnauthorized, nil, nil) | ||||
| 				return | ||||
| 			} | ||||
|  | ||||
| 			now := time.Now().Unix() | ||||
| 			session := &model.Session{ | ||||
| 				ID:       "single-user", | ||||
| 				Token:    "single-user", | ||||
| 				Token:    token, | ||||
| 				UserID:   "single-user", | ||||
| 				CreateAt: now, | ||||
| 				UpdateAt: now, | ||||
| @@ -213,11 +220,10 @@ func (a *API) attachSession(handler func(w http.ResponseWriter, r *http.Request) | ||||
| 			return | ||||
| 		} | ||||
|  | ||||
| 		token, _ := auth.ParseAuthTokenFromRequest(r) | ||||
| 		session, err := a.app().GetSession(token) | ||||
| 		if err != nil { | ||||
| 			if required { | ||||
| 				errorResponse(w, http.StatusUnauthorized, map[string]string{"error": err.Error()}, err) | ||||
| 				errorResponse(w, http.StatusUnauthorized, nil, err) | ||||
| 				return | ||||
| 			} | ||||
|  | ||||
|   | ||||
| @@ -63,12 +63,12 @@ func main() { | ||||
| 	// Command line args | ||||
| 	pMonitorPid := flag.Int("monitorpid", -1, "a process ID") | ||||
| 	pPort := flag.Int("port", config.Port, "the port number") | ||||
| 	pSingleUser := flag.Bool("single-user", false, "single user mode") | ||||
| 	pSingleUserToken := flag.String("single-user", "", "single user token") | ||||
| 	flag.Parse() | ||||
|  | ||||
| 	singleUser := false | ||||
| 	if pSingleUser != nil { | ||||
| 		singleUser = *pSingleUser | ||||
| 	singleUserToken := "" | ||||
| 	if pSingleUserToken != nil { | ||||
| 		singleUserToken = *pSingleUserToken | ||||
| 	} | ||||
|  | ||||
| 	if pMonitorPid != nil && *pMonitorPid > 0 { | ||||
| @@ -81,7 +81,7 @@ func main() { | ||||
| 		config.Port = *pPort | ||||
| 	} | ||||
|  | ||||
| 	server, err := server.New(config, singleUser) | ||||
| 	server, err := server.New(config, singleUserToken) | ||||
| 	if err != nil { | ||||
| 		log.Fatal("server.New ERROR: ", err) | ||||
| 	} | ||||
|   | ||||
| @@ -49,7 +49,7 @@ type Server struct { | ||||
| 	localModeServer *http.Server | ||||
| } | ||||
|  | ||||
| func New(cfg *config.Configuration, singleUser bool) (*Server, error) { | ||||
| func New(cfg *config.Configuration, singleUserToken string) (*Server, error) { | ||||
| 	logger, err := zap.NewProduction() | ||||
| 	if err != nil { | ||||
| 		return nil, err | ||||
| @@ -63,7 +63,7 @@ func New(cfg *config.Configuration, singleUser bool) (*Server, error) { | ||||
|  | ||||
| 	auth := auth.New(cfg, store) | ||||
|  | ||||
| 	wsServer := ws.NewServer(auth, singleUser) | ||||
| 	wsServer := ws.NewServer(auth, singleUserToken) | ||||
|  | ||||
| 	filesBackendSettings := model.FileSettings{} | ||||
| 	filesBackendSettings.SetDefaults(false) | ||||
| @@ -78,7 +78,7 @@ func New(cfg *config.Configuration, singleUser bool) (*Server, error) { | ||||
| 	webhookClient := webhook.NewClient(cfg) | ||||
|  | ||||
| 	appBuilder := func() *app.App { return app.New(cfg, store, auth, wsServer, filesBackend, webhookClient) } | ||||
| 	api := api.NewAPI(appBuilder, singleUser) | ||||
| 	api := api.NewAPI(appBuilder, singleUserToken) | ||||
|  | ||||
| 	// Local router for admin APIs | ||||
| 	localRouter := mux.NewRouter() | ||||
| @@ -157,7 +157,7 @@ func New(cfg *config.Configuration, singleUser bool) (*Server, error) { | ||||
| 			"port":        cfg.Port == config.DefaultPort, | ||||
| 			"useSSL":      cfg.UseSSL, | ||||
| 			"dbType":      cfg.DBType, | ||||
| 			"single_user": singleUser, | ||||
| 			"single_user": len(singleUserToken) > 0, | ||||
| 		} | ||||
| 	}) | ||||
| 	telemetryService.RegisterTracker("activity", func() map[string]interface{} { | ||||
|   | ||||
| @@ -18,11 +18,11 @@ type IsValidSessionToken func(token string) bool | ||||
|  | ||||
| // Server is a WebSocket server. | ||||
| type Server struct { | ||||
| 	upgrader   websocket.Upgrader | ||||
| 	listeners  map[string][]*websocket.Conn | ||||
| 	mu         sync.RWMutex | ||||
| 	auth       *auth.Auth | ||||
| 	singleUser bool | ||||
| 	upgrader        websocket.Upgrader | ||||
| 	listeners       map[string][]*websocket.Conn | ||||
| 	mu              sync.RWMutex | ||||
| 	auth            *auth.Auth | ||||
| 	singleUserToken string | ||||
| } | ||||
|  | ||||
| // UpdateMsg is sent on block updates | ||||
| @@ -50,7 +50,7 @@ type websocketSession struct { | ||||
| } | ||||
|  | ||||
| // NewServer creates a new Server. | ||||
| func NewServer(auth *auth.Auth, singleUser bool) *Server { | ||||
| func NewServer(auth *auth.Auth, singleUserToken string) *Server { | ||||
| 	return &Server{ | ||||
| 		listeners: make(map[string][]*websocket.Conn), | ||||
| 		upgrader: websocket.Upgrader{ | ||||
| @@ -58,8 +58,8 @@ func NewServer(auth *auth.Auth, singleUser bool) *Server { | ||||
| 				return true | ||||
| 			}, | ||||
| 		}, | ||||
| 		auth:       auth, | ||||
| 		singleUser: singleUser, | ||||
| 		auth:            auth, | ||||
| 		singleUserToken: singleUserToken, | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @@ -91,7 +91,7 @@ func (ws *Server) handleWebSocketOnChange(w http.ResponseWriter, r *http.Request | ||||
|  | ||||
| 	wsSession := websocketSession{ | ||||
| 		client:          client, | ||||
| 		isAuthenticated: ws.singleUser, | ||||
| 		isAuthenticated: false, | ||||
| 	} | ||||
|  | ||||
| 	// Simple message handling loop | ||||
| @@ -134,8 +134,8 @@ func (ws *Server) handleWebSocketOnChange(w http.ResponseWriter, r *http.Request | ||||
| } | ||||
|  | ||||
| func (ws *Server) isValidSessionToken(token string) bool { | ||||
| 	if ws.singleUser { | ||||
| 		return true | ||||
| 	if len(ws.singleUserToken) > 0 { | ||||
| 		return token == ws.singleUserToken | ||||
| 	} | ||||
|  | ||||
| 	session, err := ws.auth.GetSession(token) | ||||
| @@ -160,10 +160,6 @@ func (ws *Server) authenticateListener(wsSession *websocketSession, token string | ||||
| } | ||||
|  | ||||
| func (ws *Server) checkAuthentication(wsSession *websocketSession, command *WebsocketCommand) bool { | ||||
| 	if ws.singleUser { | ||||
| 		return true | ||||
| 	} | ||||
|  | ||||
| 	if wsSession.isAuthenticated { | ||||
| 		return true | ||||
| 	} | ||||
|   | ||||
		Reference in New Issue
	
	Block a user