mirror of
https://github.com/wasp-lang/wasp.git
synced 2024-11-23 19:29:17 +03:00
Allow operations to opt out of auth middleware
This patch allows operations to individually specify whether they want to use or opt out of auth middleware, via an additional `auth` argument under the actions/queries sections. If left unspecified it is assumed to be true. This is addressed by removing the current global auth middleware registration, and adding it instead to individual operation route specification.
This commit is contained in:
parent
83b00d03ce
commit
a85b408b60
@ -11,12 +11,8 @@ import {= importIdentifier =} from '{= importPath =}'
|
||||
|
||||
const router = express.Router()
|
||||
|
||||
{=# isAuthEnabled =}
|
||||
router.use(auth)
|
||||
{=/ isAuthEnabled =}
|
||||
|
||||
{=# operationRoutes =}
|
||||
router.post('{= routePath =}', {= importIdentifier =})
|
||||
router.post('{= routePath =}', {=# isAuthEnabled =} auth, {=/ isAuthEnabled =} {= importIdentifier =})
|
||||
{=/ operationRoutes =}
|
||||
|
||||
export default router
|
||||
|
@ -6,7 +6,7 @@ where
|
||||
|
||||
import Data.Aeson (object, (.=))
|
||||
import qualified Data.Aeson as Aeson
|
||||
import Data.Maybe (fromJust, isJust)
|
||||
import Data.Maybe (fromJust)
|
||||
import Generator.FileDraft (FileDraft)
|
||||
import qualified Generator.ServerGenerator.Common as C
|
||||
import Generator.ServerGenerator.OperationsG (operationFileInSrcDir)
|
||||
@ -97,15 +97,19 @@ genOperationsRouter wasp = C.makeTemplateFD tmplFile dstFile (Just tmplData)
|
||||
tmplData =
|
||||
object
|
||||
[ "operationRoutes" .= map makeOperationRoute operations,
|
||||
"isAuthEnabled" .= (isJust $ getAuth wasp)
|
||||
"isAuthEnabled" .= (or $ map authEnabled operations)
|
||||
]
|
||||
makeOperationRoute operation =
|
||||
let operationName = Wasp.Operation.getName operation
|
||||
in object
|
||||
[ "importIdentifier" .= operationName,
|
||||
"importPath" .= ("./" ++ SP.toFilePath (SP.relFileToPosix' $ operationRouteFileInOperationsRoutesDir operation)),
|
||||
"routePath" .= ("/" ++ operationRouteInOperationsRouter operation)
|
||||
"routePath" .= ("/" ++ operationRouteInOperationsRouter operation),
|
||||
"isAuthEnabled" .= (authEnabled operation)
|
||||
]
|
||||
|
||||
authEnabled :: Wasp.Operation.Operation -> Bool
|
||||
authEnabled op = (Wasp.Operation.getAuth op /= Just False)
|
||||
|
||||
operationRouteInOperationsRouter :: Wasp.Operation.Operation -> String
|
||||
operationRouteInOperationsRouter = U.camelToKebabCase . Wasp.Operation.getName
|
||||
|
@ -19,5 +19,6 @@ action = do
|
||||
{ Action._name = name,
|
||||
Action._jsFunction =
|
||||
fromMaybe (error "Action js function is missing.") (Operation.getJsFunctionFromProps props),
|
||||
Action._entities = Operation.getEntitiesFromProps props
|
||||
Action._entities = Operation.getEntitiesFromProps props,
|
||||
Action._auth = Operation.getAuthEnabledFromProps props
|
||||
}
|
||||
|
@ -3,6 +3,7 @@ module Parser.Operation
|
||||
entitiesPropParser,
|
||||
getJsFunctionFromProps,
|
||||
getEntitiesFromProps,
|
||||
getAuthEnabledFromProps,
|
||||
properties,
|
||||
-- FOR TESTS:
|
||||
Property (..),
|
||||
@ -20,6 +21,7 @@ import qualified Wasp.JsImport
|
||||
data Property
|
||||
= JsFunction !Wasp.JsImport.JsImport
|
||||
| Entities ![String]
|
||||
| AuthEnabled !Bool
|
||||
deriving (Show, Eq)
|
||||
|
||||
properties :: Parser [Property]
|
||||
@ -27,6 +29,7 @@ properties =
|
||||
L.commaSep1 $
|
||||
jsFunctionPropParser
|
||||
<|> entitiesPropParser
|
||||
<|> authEnabledPropParser
|
||||
|
||||
jsFunctionPropParser :: Parser Property
|
||||
jsFunctionPropParser = JsFunction <$> C.waspProperty "fn" Parser.JsImport.jsImport
|
||||
@ -39,3 +42,9 @@ entitiesPropParser = Entities <$> C.waspProperty "entities" (C.waspList L.identi
|
||||
|
||||
getEntitiesFromProps :: [Property] -> Maybe [String]
|
||||
getEntitiesFromProps ps = listToMaybe [es | Entities es <- ps]
|
||||
|
||||
authEnabledPropParser :: Parser Property
|
||||
authEnabledPropParser = AuthEnabled <$> C.waspProperty "auth" L.bool
|
||||
|
||||
getAuthEnabledFromProps :: [Property] -> Maybe Bool
|
||||
getAuthEnabledFromProps ps = listToMaybe [aE | AuthEnabled aE <- ps]
|
||||
|
@ -19,5 +19,6 @@ query = do
|
||||
{ Query._name = name,
|
||||
Query._jsFunction =
|
||||
fromMaybe (error "Query js function is missing.") (Operation.getJsFunctionFromProps props),
|
||||
Query._entities = Operation.getEntitiesFromProps props
|
||||
Query._entities = Operation.getEntitiesFromProps props,
|
||||
Query._auth = Operation.getAuthEnabledFromProps props
|
||||
}
|
||||
|
@ -11,7 +11,8 @@ import Wasp.JsImport (JsImport)
|
||||
data Action = Action
|
||||
{ _name :: !String,
|
||||
_jsFunction :: !JsImport,
|
||||
_entities :: !(Maybe [String])
|
||||
_entities :: !(Maybe [String]),
|
||||
_auth :: !(Maybe Bool)
|
||||
}
|
||||
deriving (Show, Eq)
|
||||
|
||||
@ -20,5 +21,6 @@ instance ToJSON Action where
|
||||
object
|
||||
[ "name" .= _name action,
|
||||
"jsFunction" .= _jsFunction action,
|
||||
"entities" .= _entities action
|
||||
"entities" .= _entities action,
|
||||
"auth" .= _auth action
|
||||
]
|
||||
|
@ -3,6 +3,7 @@ module Wasp.Operation
|
||||
getName,
|
||||
getJsFn,
|
||||
getEntities,
|
||||
getAuth
|
||||
)
|
||||
where
|
||||
|
||||
@ -30,3 +31,7 @@ getJsFn (ActionOp action) = Action._jsFunction action
|
||||
getEntities :: Operation -> Maybe [String]
|
||||
getEntities (QueryOp query) = Query._entities query
|
||||
getEntities (ActionOp action) = Action._entities action
|
||||
|
||||
getAuth :: Operation -> Maybe Bool
|
||||
getAuth (QueryOp query) = Query._auth query
|
||||
getAuth (ActionOp action) = Action._auth action
|
@ -11,7 +11,8 @@ import Wasp.JsImport (JsImport)
|
||||
data Query = Query
|
||||
{ _name :: !String,
|
||||
_jsFunction :: !JsImport,
|
||||
_entities :: !(Maybe [String])
|
||||
_entities :: !(Maybe [String]),
|
||||
_auth :: !(Maybe Bool)
|
||||
}
|
||||
deriving (Show, Eq)
|
||||
|
||||
@ -20,5 +21,6 @@ instance ToJSON Query where
|
||||
object
|
||||
[ "name" .= _name query,
|
||||
"jsFunction" .= _jsFunction query,
|
||||
"entities" .= _entities query
|
||||
"entities" .= _entities query,
|
||||
"auth" .= _auth query
|
||||
]
|
||||
|
@ -1,6 +1,7 @@
|
||||
module Parser.ActionTest where
|
||||
|
||||
import Data.Either (isLeft)
|
||||
import Data.Char (toLower)
|
||||
import Parser.Action (action)
|
||||
import Parser.Common (runWaspParser)
|
||||
import qualified Path.Posix as PPosix
|
||||
@ -19,12 +20,23 @@ spec_parseAction =
|
||||
describe "Parsing action declaration" $ do
|
||||
let parseAction = runWaspParser action
|
||||
|
||||
it "When given a valid action declaration, returns correct AST" $ do
|
||||
let testActionName = "myAction"
|
||||
testActionJsFunctionName = "myJsAction"
|
||||
testActionJsFunctionFrom = SP.fromPathRelFileP [PPosix.relfile|some/path|]
|
||||
let testAction =
|
||||
Wasp.Action.Action
|
||||
it "When given a valid action declaration, returns correct AST (no auth)" $ do
|
||||
let testAction = genActionAST Nothing
|
||||
let testActionInput = genActionInput Nothing
|
||||
parseAction testActionInput `shouldBe` Right testAction
|
||||
it "When given a valid action declaration, returns correct AST (auth = true)" $ do
|
||||
let testAction = genActionAST (Just True)
|
||||
let testActionInput = genActionInput (Just True)
|
||||
parseAction testActionInput `shouldBe` Right testAction
|
||||
it "When given a valid action declaration, returns correct AST (auth = false)" $ do
|
||||
let testAction = genActionAST (Just False)
|
||||
let testActionInput = genActionInput (Just False)
|
||||
parseAction testActionInput `shouldBe` Right testAction
|
||||
it "When given action wasp declaration without 'fn' property, should return Left" $ do
|
||||
isLeft (parseAction "action myAction { }") `shouldBe` True
|
||||
where
|
||||
genActionAST :: Maybe Bool -> Wasp.Action.Action
|
||||
genActionAST aApplyAuth = Wasp.Action.Action
|
||||
{ Wasp.Action._name = testActionName,
|
||||
Wasp.Action._jsFunction =
|
||||
Wasp.JsImport.JsImport
|
||||
@ -32,15 +44,21 @@ spec_parseAction =
|
||||
Wasp.JsImport._namedImports = [testActionJsFunctionName],
|
||||
Wasp.JsImport._from = testActionJsFunctionFrom
|
||||
},
|
||||
Wasp.Action._entities = Nothing
|
||||
Wasp.Action._entities = Nothing,
|
||||
Wasp.Action._auth = aApplyAuth
|
||||
}
|
||||
parseAction
|
||||
( "action " ++ testActionName ++ " {\n"
|
||||
++ " fn: import { "
|
||||
++ testActionJsFunctionName
|
||||
++ " } from \"@ext/some/path\"\n"
|
||||
++ "}"
|
||||
)
|
||||
`shouldBe` Right testAction
|
||||
it "When given action wasp declaration without 'fn' property, should return Left" $ do
|
||||
isLeft (parseAction "action myAction { }") `shouldBe` True
|
||||
genActionInput :: Maybe Bool -> String
|
||||
genActionInput aApplyAuth = (
|
||||
"action " ++ testActionName ++ " {\n"
|
||||
++ " fn: import { "
|
||||
++ testActionJsFunctionName
|
||||
++ " } from \"@ext/some/path\""
|
||||
++ authStr aApplyAuth
|
||||
++ "}"
|
||||
)
|
||||
authStr :: Maybe Bool -> String
|
||||
authStr (Just useAuth) = ",\n auth: " ++ map toLower (show useAuth) ++ "\n"
|
||||
authStr _ = "\n"
|
||||
testActionJsFunctionFrom = SP.fromPathRelFileP [PPosix.relfile|some/path|]
|
||||
testActionJsFunctionName = "myJsAction"
|
||||
testActionName = "myAction"
|
||||
|
@ -108,7 +108,8 @@ spec_parseWasp =
|
||||
Wasp.JsImport._namedImports = ["myJsQuery"],
|
||||
Wasp.JsImport._from = SP.fromPathRelFileP [PPosix.relfile|some/path|]
|
||||
},
|
||||
Wasp.Query._entities = Nothing
|
||||
Wasp.Query._entities = Nothing,
|
||||
Wasp.Query._auth = Nothing
|
||||
},
|
||||
WaspElementNpmDependencies $
|
||||
Wasp.NpmDependencies.NpmDependencies
|
||||
|
@ -8,18 +8,43 @@ import qualified StrongPath as SP
|
||||
import Test.Tasty.Hspec
|
||||
import qualified Wasp.JsImport
|
||||
import qualified Wasp.Query
|
||||
import Data.Char (toLower)
|
||||
|
||||
spec_parseQuery :: Spec
|
||||
spec_parseQuery =
|
||||
describe "Parsing query declaration" $ do
|
||||
let parseQuery = runWaspParser query
|
||||
|
||||
it "When given a valid query declaration, returns correct AST" $ do
|
||||
let testQueryName = "myQuery"
|
||||
testQueryJsFunctionName = "myJsQuery"
|
||||
testQueryJsFunctionFrom = SP.fromPathRelFileP [PPosix.relfile|some/path|]
|
||||
let testQuery =
|
||||
Wasp.Query.Query
|
||||
it "When given a valid query declaration, returns correct AST(without auth)" $ do
|
||||
let testQuery = genQueryAST Nothing
|
||||
let testQueryInput = genQueryInput Nothing
|
||||
parseQuery testQueryInput `shouldBe` Right testQuery
|
||||
it "When given query wasp declaration without 'fn' property, should return Left" $ do
|
||||
isLeft (parseQuery "query myQuery { }") `shouldBe` True
|
||||
it "When given a valid query declaration, returns correct AST(with auth=true)" $ do
|
||||
let testQuery = genQueryAST (Just True)
|
||||
let testQueryInput = genQueryInput (Just True)
|
||||
parseQuery testQueryInput `shouldBe` Right testQuery
|
||||
it "When given a valid query declaration, returns correct AST(with auth=false)" $ do
|
||||
let testQuery = genQueryAST (Just False)
|
||||
let testQueryInput = genQueryInput (Just False)
|
||||
parseQuery testQueryInput `shouldBe` Right testQuery
|
||||
where
|
||||
genQueryInput :: Maybe Bool -> String
|
||||
genQueryInput qApplyAuth = (
|
||||
"query " ++ testQueryName ++ " {\n"
|
||||
++ " fn: import { "
|
||||
++ testQueryJsFunctionName
|
||||
++ " } from \"@ext/some/path\",\n"
|
||||
++ " entities: [Task, Project]"
|
||||
++ authStr qApplyAuth
|
||||
++ "}"
|
||||
)
|
||||
authStr :: Maybe Bool -> String
|
||||
authStr (Just useAuth) = ",\n auth: " ++ map toLower (show useAuth) ++ "\n"
|
||||
authStr _ = "\n"
|
||||
genQueryAST :: Maybe Bool -> Wasp.Query.Query
|
||||
genQueryAST qApplyAuth = Wasp.Query.Query
|
||||
{ Wasp.Query._name = testQueryName,
|
||||
Wasp.Query._jsFunction =
|
||||
Wasp.JsImport.JsImport
|
||||
@ -27,16 +52,10 @@ spec_parseQuery =
|
||||
Wasp.JsImport._namedImports = [testQueryJsFunctionName],
|
||||
Wasp.JsImport._from = testQueryJsFunctionFrom
|
||||
},
|
||||
Wasp.Query._entities = Just ["Task", "Project"]
|
||||
Wasp.Query._entities = Just ["Task", "Project"],
|
||||
Wasp.Query._auth = qApplyAuth
|
||||
}
|
||||
parseQuery
|
||||
( "query " ++ testQueryName ++ " {\n"
|
||||
++ " fn: import { "
|
||||
++ testQueryJsFunctionName
|
||||
++ " } from \"@ext/some/path\",\n"
|
||||
++ " entities: [Task, Project]\n"
|
||||
++ "}"
|
||||
)
|
||||
`shouldBe` Right testQuery
|
||||
it "When given query wasp declaration without 'fn' property, should return Left" $ do
|
||||
isLeft (parseQuery "query myQuery { }") `shouldBe` True
|
||||
testQueryName = "myQuery"
|
||||
testQueryJsFunctionName = "myJsQuery"
|
||||
testQueryJsFunctionFrom = SP.fromPathRelFileP [PPosix.relfile|some/path|]
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user