Allow sharing with workspace

This commit is contained in:
Chen-I Lim 2021-03-29 10:41:27 -07:00
parent 94a1a16f5f
commit 98bfd5a57a
2 changed files with 44 additions and 34 deletions

View file

@ -116,7 +116,7 @@ func (a *API) checkCSRFToken(r *http.Request) bool {
return false
}
func (a *API) getContainer(r *http.Request) (*store.Container, error) {
func (a *API) getContainerAllowingReadTokenForBlock(r *http.Request, blockID string) (*store.Container, error) {
if a.WorkspaceAuthenticator == nil {
// Native auth: always use root workspace
container := store.Container{
@ -133,19 +133,44 @@ func (a *API) getContainer(r *http.Request) (*store.Container, error) {
return nil, errors.New("No workspace specified")
}
ctx := r.Context()
session := ctx.Value("session").(*model.Session)
if !a.WorkspaceAuthenticator.DoesUserHaveWorkspaceAccess(session, workspaceID) {
return nil, errors.New("Access denied to workspace")
}
container := store.Container{
WorkspaceID: workspaceID,
}
ctx := r.Context()
session, _ := ctx.Value("session").(*model.Session)
if session == nil && len(blockID) > 0 {
// No session, check for read_token
query := r.URL.Query()
readToken := query.Get("read_token")
// Require read token
if len(readToken) < 1 {
return nil, errors.New("Access denied to workspace")
}
isValid, err := a.app().IsValidReadToken(container, blockID, readToken)
if err != nil {
log.Printf("IsValidReadToken ERROR: %v", err)
return nil, errors.New("Access denied to workspace")
}
if !isValid {
return nil, errors.New("Access denied to workspace")
}
} else {
if !a.WorkspaceAuthenticator.DoesUserHaveWorkspaceAccess(session, workspaceID) {
return nil, errors.New("Access denied to workspace")
}
}
return &container, nil
}
func (a *API) getContainer(r *http.Request) (*store.Container, error) {
return a.getContainerAllowingReadTokenForBlock(r, "")
}
func (a *API) handleGetBlocks(w http.ResponseWriter, r *http.Request) {
// swagger:operation GET /api/v1/workspaces/{workspaceID}/blocks getBlocks
//
@ -499,37 +524,12 @@ func (a *API) handleGetSubTree(w http.ResponseWriter, r *http.Request) {
vars := mux.Vars(r)
blockID := vars["blockID"]
container, err := a.getContainer(r)
container, err := a.getContainerAllowingReadTokenForBlock(r, blockID)
if err != nil {
noContainerErrorResponse(w, err)
return
}
// If not authenticated (no session), check that block is publicly shared
ctx := r.Context()
session, _ := ctx.Value("session").(*model.Session)
if session == nil {
query := r.URL.Query()
readToken := query.Get("read_token")
// Require read token
if len(readToken) < 1 {
errorResponse(w, http.StatusBadRequest, "No read_token", nil)
return
}
isValid, err := a.app().IsValidReadToken(*container, blockID, readToken)
if err != nil {
errorResponse(w, http.StatusInternalServerError, "", err)
return
}
if !isValid {
errorResponse(w, http.StatusUnauthorized, "", nil)
return
}
}
query := r.URL.Query()
levels, err := strconv.ParseInt(query.Get("l"), 10, 32)
if err != nil {

View file

@ -45,9 +45,19 @@ class ShareBoardComponent extends React.PureComponent<Props, State> {
const isSharing = Boolean(sharing && sharing.id === this.props.boardId && sharing.enabled)
const readToken = (sharing && isSharing) ? sharing.token : ''
const shareUrl = new URL(window.location.toString())
shareUrl.searchParams.set('r', readToken)
shareUrl.pathname = '/shared'
const components = shareUrl.pathname.split('/')
// TODO: Consider passing workspaceId through props instead
if (components.length >= 2 && components[1].toLowerCase() === 'workspace') {
const workspaceId = components[2]
shareUrl.pathname = `/workspace/${workspaceId}/shared`
} else {
shareUrl.pathname = '/shared'
}
let stateDescription: string
if (isSharing) {