Allow sharing with workspace
This commit is contained in:
parent
94a1a16f5f
commit
98bfd5a57a
2 changed files with 44 additions and 34 deletions
|
@ -116,7 +116,7 @@ func (a *API) checkCSRFToken(r *http.Request) bool {
|
||||||
return false
|
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 {
|
if a.WorkspaceAuthenticator == nil {
|
||||||
// Native auth: always use root workspace
|
// Native auth: always use root workspace
|
||||||
container := store.Container{
|
container := store.Container{
|
||||||
|
@ -133,19 +133,44 @@ func (a *API) getContainer(r *http.Request) (*store.Container, error) {
|
||||||
return nil, errors.New("No workspace specified")
|
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{
|
container := store.Container{
|
||||||
WorkspaceID: workspaceID,
|
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
|
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) {
|
func (a *API) handleGetBlocks(w http.ResponseWriter, r *http.Request) {
|
||||||
// swagger:operation GET /api/v1/workspaces/{workspaceID}/blocks getBlocks
|
// 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)
|
vars := mux.Vars(r)
|
||||||
blockID := vars["blockID"]
|
blockID := vars["blockID"]
|
||||||
|
|
||||||
container, err := a.getContainer(r)
|
container, err := a.getContainerAllowingReadTokenForBlock(r, blockID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
noContainerErrorResponse(w, err)
|
noContainerErrorResponse(w, err)
|
||||||
return
|
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()
|
query := r.URL.Query()
|
||||||
levels, err := strconv.ParseInt(query.Get("l"), 10, 32)
|
levels, err := strconv.ParseInt(query.Get("l"), 10, 32)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|
|
@ -45,9 +45,19 @@ class ShareBoardComponent extends React.PureComponent<Props, State> {
|
||||||
|
|
||||||
const isSharing = Boolean(sharing && sharing.id === this.props.boardId && sharing.enabled)
|
const isSharing = Boolean(sharing && sharing.id === this.props.boardId && sharing.enabled)
|
||||||
const readToken = (sharing && isSharing) ? sharing.token : ''
|
const readToken = (sharing && isSharing) ? sharing.token : ''
|
||||||
|
|
||||||
const shareUrl = new URL(window.location.toString())
|
const shareUrl = new URL(window.location.toString())
|
||||||
shareUrl.searchParams.set('r', readToken)
|
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
|
let stateDescription: string
|
||||||
if (isSharing) {
|
if (isSharing) {
|
||||||
|
|
Loading…
Reference in a new issue