git.iko.soy/typeable/openapi3
on master help sign in
Merge pull request #151 from taojang/master

Merge OAuth2 scopes

commit547031354209069d5a9d873c3a1f1133c70f5407 authorfisx <mf@zerobuzz.net> dateMon 27 Jan 2020, 17:43 (7 years ago) parent7879efa1081581
4 files changed+87−4
src/Data/Swagger.hs+2−1 src/Data/Swagger/Internal.hs+36−1 src/Data/Swagger/Lens.hs+6 test/Data/SwaggerSpec.hs+43−2
src/Data/Swagger.hs+2−1
@@ -89,6 +89,7 @@ module Data.Swagger (
8989 SecurityScheme(..),
9090 SecuritySchemeType(..),
9191 SecurityRequirement(..),
92+ SecurityDefinitions(..),
9293
9394 -- *** API key
9495 ApiKeyParams(..),
@@ -279,7 +280,7 @@ import Data.Swagger.Internal
279280-- >>> encode $ toSchema (Proxy :: Proxy Person)
280281-- "{\"required\":[\"name\",\"age\"],\"properties\":{\"name\":{\"type\":\"string\"},\"age\":{\"type\":\"integer\"}},\"type\":\"object\"}"
281282--
282−-- Please note that not all valid Haskell data types will have a proper swagger schema. For example while we can derive a
283+-- Please note that not all valid Haskell data types will have a proper swagger schema. For example while we can derive a
283284-- schema for basic enums like
284285--
285286-- >>> data SampleEnum = ChoiceOne | ChoiceTwo deriving Generic
src/Data/Swagger/Internal.hs+36−1
@@ -117,7 +117,7 @@ data Swagger = Swagger
117117 , _swaggerResponses :: Definitions Response
118118
119119 -- | Security scheme definitions that can be used across the specification.
120− , _swaggerSecurityDefinitions :: Definitions SecurityScheme
120+ , _swaggerSecurityDefinitions :: SecurityDefinitions
121121
122122 -- | A declaration of which security schemes are applied for the API as a whole.
123123 -- The list of values describes alternative security schemes that can be used
@@ -755,6 +755,22 @@ data SecurityScheme = SecurityScheme
755755 , _securitySchemeDescription :: Maybe Text
756756 } deriving (Eq, Show, Generic, Data, Typeable)
757757
758+
759+-- | merge scopes of two OAuth2 security schemes when their flows are identical.
760+-- In other case returns first security scheme
761+mergeSecurityScheme :: SecurityScheme -> SecurityScheme -> SecurityScheme
762+mergeSecurityScheme s1@(SecurityScheme (SecuritySchemeOAuth2 (OAuth2Params flow1 scopes1)) desc)
763+ s2@(SecurityScheme (SecuritySchemeOAuth2 (OAuth2Params flow2 scopes2)) _)
764+ = if flow1 == flow2 then
765+ SecurityScheme (SecuritySchemeOAuth2 (OAuth2Params flow1 (scopes1 <> scopes2))) desc
766+ else
767+ s1
768+mergeSecurityScheme s1 _ = s1
769+
770+newtype SecurityDefinitions
771+ = SecurityDefinitions (Definitions SecurityScheme)
772+ deriving (Eq, Show, Generic, Data, Typeable)
773+
758774-- | Lists the required security schemes to execute this operation.
759775-- The object can have multiple security schemes declared in it which are all required
760776-- (that is, there is a logical AND between the schemes).
@@ -904,6 +920,17 @@ instance Monoid Example where
904920 mempty = genericMempty
905921 mappend = (<>)
906922
923+instance Semigroup SecurityScheme where
924+ (<>) = mergeSecurityScheme
925+
926+instance Semigroup SecurityDefinitions where
927+ (SecurityDefinitions sd1) <> (SecurityDefinitions sd2) =
928+ SecurityDefinitions $ InsOrdHashMap.unionWith (<>) sd1 sd2
929+
930+instance Monoid SecurityDefinitions where
931+ mempty = SecurityDefinitions $ InsOrdHashMap.empty
932+ mappend = (<>)
933+
907934-- =======================================================================
908935-- SwaggerMonoid helper instances
909936-- =======================================================================
@@ -918,6 +945,7 @@ instance SwaggerMonoid Responses
918945instance SwaggerMonoid Response
919946instance SwaggerMonoid ExternalDocs
920947instance SwaggerMonoid Operation
948+instance SwaggerMonoid SecurityDefinitions
921949instance (Eq a, Hashable a) => SwaggerMonoid (InsOrdHashSet a)
922950
923951instance SwaggerMonoid MimeList
@@ -1118,6 +1146,9 @@ instance ToJSON PathItem where
11181146instance ToJSON Example where
11191147 toJSON = toJSON . Map.mapKeys show . getExample
11201148
1149+instance ToJSON SecurityDefinitions where
1150+ toJSON (SecurityDefinitions sd) = toJSON sd
1151+
11211152instance ToJSON Reference where
11221153 toJSON (Reference ref) = object [ "$ref" .= ref ]
11231154
@@ -1279,6 +1310,9 @@ instance FromJSON Operation where
12791310instance FromJSON PathItem where
12801311 parseJSON = sopSwaggerGenericParseJSON
12811312
1313+instance FromJSON SecurityDefinitions where
1314+ parseJSON js = SecurityDefinitions <$> parseJSON js
1315+
12821316instance FromJSON Reference where
12831317 parseJSON (Object o) = Reference <$> o .: "$ref"
12841318 parseJSON _ = empty
@@ -1390,3 +1424,4 @@ instance AesonDefaultValue (SwaggerType a)
13901424instance AesonDefaultValue MimeList where defaultValue = Just mempty
13911425instance AesonDefaultValue Info
13921426instance AesonDefaultValue ParamLocation
1427+instance AesonDefaultValue SecurityDefinitions where defaultValue = Just $ SecurityDefinitions mempty
src/Data/Swagger/Lens.hs+6
@@ -96,6 +96,12 @@ instance At Responses where at n = responses . at n
9696instance Ixed Operation where ix n = responses . ix n
9797instance At Operation where at n = responses . at n
9898
99+type instance Index SecurityDefinitions = Text
100+type instance IxValue SecurityDefinitions = SecurityScheme
101+
102+instance Ixed SecurityDefinitions where ix n = (coerced :: Lens' SecurityDefinitions (Definitions SecurityScheme)). ix n
103+instance At SecurityDefinitions where at n = (coerced :: Lens' SecurityDefinitions (Definitions SecurityScheme)). at n
104+
99105instance HasParamSchema NamedSchema (ParamSchema 'SwaggerKindSchema) where paramSchema = schema.paramSchema
100106
101107-- HasType instances
test/Data/SwaggerSpec.hs+43−2
@@ -43,6 +43,7 @@ spec = do
4343 describe "Parameters Definition Object" $ paramsDefinitionExample <=> paramsDefinitionExampleJSON
4444 describe "Responses Definition Object" $ responsesDefinitionExample <=> responsesDefinitionExampleJSON
4545 describe "Security Definitions Object" $ securityDefinitionsExample <=> securityDefinitionsExampleJSON
46+ describe "OAuth2 Security Definitions with merged Scope" $ oAuth2SecurityDefinitionsExample <=> oAuth2SecurityDefinitionsExampleJSON
4647 describe "Composition Schema Example" $ compositionSchemaExample <=> compositionSchemaExampleJSON
4748 describe "Swagger Object" $ do
4849 context "Todo Example" $ swaggerExample <=> swaggerExampleJSON
@@ -459,8 +460,8 @@ responsesDefinitionExampleJSON = [aesonQQ|
459460-- Responses Definition object
460461-- =======================================================================
461462
462−securityDefinitionsExample :: HashMap Text SecurityScheme
463−securityDefinitionsExample =
463+securityDefinitionsExample :: SecurityDefinitions
464+securityDefinitionsExample = SecurityDefinitions
464465 [ ("api_key", SecurityScheme
465466 { _securitySchemeType = SecuritySchemeApiKey (ApiKeyParams "api_key" ApiKeyHeader)
466467 , _securitySchemeDescription = Nothing })
@@ -492,6 +493,46 @@ securityDefinitionsExampleJSON = [aesonQQ|
492493}
493494|]
494495
496+oAuth2SecurityDefinitionsReadExample :: SecurityDefinitions
497+oAuth2SecurityDefinitionsReadExample = SecurityDefinitions
498+ [ ("petstore_auth", SecurityScheme
499+ { _securitySchemeType = SecuritySchemeOAuth2 (OAuth2Params
500+ { _oauth2Flow = OAuth2Implicit "http://swagger.io/api/oauth/dialog"
501+ , _oauth2Scopes =
502+ [ ("read:pets", "read your pets") ] } )
503+ , _securitySchemeDescription = Nothing })
504+ ]
505+
506+oAuth2SecurityDefinitionsWriteExample :: SecurityDefinitions
507+oAuth2SecurityDefinitionsWriteExample = SecurityDefinitions
508+ [ ("petstore_auth", SecurityScheme
509+ { _securitySchemeType = SecuritySchemeOAuth2 (OAuth2Params
510+ { _oauth2Flow = OAuth2Implicit "http://swagger.io/api/oauth/dialog"
511+ , _oauth2Scopes =
512+ [ ("write:pets", "modify pets in your account") ] } )
513+ , _securitySchemeDescription = Nothing })
514+ ]
515+
516+oAuth2SecurityDefinitionsExample :: SecurityDefinitions
517+oAuth2SecurityDefinitionsExample =
518+ oAuth2SecurityDefinitionsWriteExample <>
519+ oAuth2SecurityDefinitionsReadExample
520+
521+oAuth2SecurityDefinitionsExampleJSON :: Value
522+oAuth2SecurityDefinitionsExampleJSON = [aesonQQ|
523+{
524+ "petstore_auth": {
525+ "type": "oauth2",
526+ "authorizationUrl": "http://swagger.io/api/oauth/dialog",
527+ "flow": "implicit",
528+ "scopes": {
529+ "write:pets": "modify pets in your account",
530+ "read:pets": "read your pets"
531+ }
532+ }
533+}
534+|]
535+
495536-- =======================================================================
496537-- Swagger object
497538-- =======================================================================