feat: add public visibility

prod
Steven 2 years ago
parent 5a79304153
commit 469c841713

@ -4,6 +4,8 @@ package api
type Visibility string
const (
// VisibilityPublic is the PUBLIC visibility.
VisibilityPublic Visibility = "PUBLIC"
// VisibilityWorkspace is the WORKSPACE visibility.
VisibilityWorkspace Visibility = "WORKSPACE"
// VisibilityPrivite is the PRIVATE visibility.
@ -12,6 +14,8 @@ const (
func (e Visibility) String() string {
switch e {
case VisibilityPublic:
return "PUBLIC"
case VisibilityWorkspace:
return "WORKSPACE"
case VisibilityPrivite:

@ -60,7 +60,9 @@ func aclMiddleware(s *Server, next echo.HandlerFunc) echo.HandlerFunc {
return next(c)
}
if common.HasPrefixes(path, "/api/ping", "/api/status", "/api/user/:id") && c.Request().Method == http.MethodGet {
println("path", path)
if common.HasPrefixes(path, "/api/ping", "/api/status", "/api/user/:id", "/api/workspace/:workspaceName/shortcut/:shortcutName") && c.Request().Method == http.MethodGet {
return next(c)
}

@ -92,11 +92,6 @@ func (s *Server) registerWorkspaceRoutes(g *echo.Group) {
g.GET("/workspace/:workspaceName/shortcut/:shortcutName", func(c echo.Context) error {
ctx := c.Request().Context()
userID, ok := c.Get(getUserIDContextKey()).(int)
if !ok {
return echo.NewHTTPError(http.StatusUnauthorized, "Missing user in session")
}
workspaceName := c.Param("workspaceName")
shortcutName := c.Param("shortcutName")
if workspaceName == "" || shortcutName == "" {
@ -113,20 +108,6 @@ func (s *Server) registerWorkspaceRoutes(g *echo.Group) {
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Errorf("failed to find workspace with name %s", workspaceName)).SetInternal(err)
}
workspaceUser, err := s.Store.FindWordspaceUser(ctx, &api.WorkspaceUserFind{
WorkspaceID: &workspace.ID,
UserID: &userID,
})
if err != nil {
if common.ErrorCode(err) == common.NotFound {
return echo.NewHTTPError(http.StatusNotFound, "workspace user not found")
}
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find workspace user").SetInternal(err)
}
if workspaceUser == nil {
return echo.NewHTTPError(http.StatusUnauthorized, "not workspace user")
}
shortcut, err := s.Store.FindShortcut(ctx, &api.ShortcutFind{
WorkspaceID: &workspace.ID,
Name: &shortcutName,
@ -138,6 +119,27 @@ func (s *Server) registerWorkspaceRoutes(g *echo.Group) {
return echo.NewHTTPError(http.StatusInternalServerError, fmt.Errorf("failed to find shortcut with name %s", shortcutName)).SetInternal(err)
}
if shortcut.Visibility != api.VisibilityPublic {
userID, ok := c.Get(getUserIDContextKey()).(int)
if !ok {
return echo.NewHTTPError(http.StatusUnauthorized, "Missing user in session")
}
workspaceUser, err := s.Store.FindWordspaceUser(ctx, &api.WorkspaceUserFind{
WorkspaceID: &workspace.ID,
UserID: &userID,
})
if err != nil {
if common.ErrorCode(err) == common.NotFound {
return echo.NewHTTPError(http.StatusNotFound, "workspace user not found")
}
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to find workspace user").SetInternal(err)
}
if workspaceUser == nil {
return echo.NewHTTPError(http.StatusUnauthorized, "not workspace user")
}
}
c.Response().Header().Set(echo.HeaderContentType, echo.MIMEApplicationJSONCharsetUTF8)
if err := json.NewEncoder(c.Response().Writer).Encode(composeResponse(shortcut)); err != nil {
return echo.NewHTTPError(http.StatusInternalServerError, "Failed to encode shortcut response").SetInternal(err)

@ -116,7 +116,7 @@ CREATE TABLE shortcut (
name TEXT NOT NULL,
link TEXT NOT NULL DEFAULT '',
description TEXT NOT NULL DEFAULT '',
visibility TEXT NOT NULL CHECK (visibility IN ('PRIVATE', 'WORKSPACE')) DEFAULT 'PRIVATE',
visibility TEXT NOT NULL CHECK (visibility IN ('PRIVATE', 'WORKSPACE', 'PUBLIC')) DEFAULT 'PRIVATE',
FOREIGN KEY(creator_id) REFERENCES user(id) ON DELETE CASCADE,
FOREIGN KEY(workspace_id) REFERENCES workspace(id) ON DELETE CASCADE
);

@ -9,6 +9,6 @@ VALUES
(
11,
101,
'Demo',
'demo',
''
);

@ -16,3 +16,22 @@ VALUES
'百度搜索',
'WORKSPACE'
);
INSERT INTO
shortcut (
`creator_id`,
`workspace_id`,
`name`,
`link`,
`description`,
`visibility`
)
VALUES
(
102,
11,
'bl',
'https://bilibili.com',
'B站',
'PUBLIC'
);

@ -1,5 +1,5 @@
import { useEffect } from "react";
import { Route, Routes, useNavigate } from "react-router-dom";
import { Route, Routes, useLocation, useNavigate } from "react-router-dom";
import { userService, workspaceService } from "./services";
import useLoading from "./hooks/useLoading";
import Only from "./components/common/OnlyWhen";
@ -9,11 +9,27 @@ import WorkspaceDetail from "./pages/WorkspaceDetail";
import UserDetail from "./pages/UserDetail";
import ShortcutRedirector from "./pages/ShortcutRedirector";
const pathnameWhitelist = [/\/.+?\/go\/.+/];
function App() {
const navigate = useNavigate();
const location = useLocation();
const pageLoadingStatus = useLoading();
useEffect(() => {
let needAuth = true;
for (const regexp of pathnameWhitelist) {
if (regexp.test(location.pathname)) {
needAuth = false;
break;
}
}
if (!needAuth) {
pageLoadingStatus.setFinish();
return;
}
userService.initialState().finally(() => {
if (!userService.getState().user) {
pageLoadingStatus.setFinish();

@ -148,7 +148,7 @@ const CreateShortcutDialog: React.FC<Props> = (props: Props) => {
checked={state.shortcutCreate.visibility === "PRIVATE"}
/>
<label htmlFor="visibility-private" className="ml-1 mr-4">
Only for myself
Private
</label>
<input
type="radio"
@ -158,8 +158,19 @@ const CreateShortcutDialog: React.FC<Props> = (props: Props) => {
onChange={handleVisibilityInputChange}
checked={state.shortcutCreate.visibility === "WORKSPACE"}
/>
<label htmlFor="visibility-workspace" className="ml-1">
Public in workspace
<label htmlFor="visibility-workspace" className="ml-1 mr-4">
Workspace
</label>
<input
type="radio"
name="visibility"
id="visibility-public"
value="PUBLIC"
onChange={handleVisibilityInputChange}
checked={state.shortcutCreate.visibility === "PUBLIC"}
/>
<label htmlFor="visibility-public" className="ml-1">
Public
</label>
</div>
</div>

@ -1,6 +1,6 @@
type ShortcutId = number;
type Visibility = "PRIVATE" | "WORKSPACE";
type Visibility = "PRIVATE" | "WORKSPACE" | "PUBLIC";
interface Shortcut {
id: ShortcutId;

Loading…
Cancel
Save