OAuth2 scopes are now generated as type aliases. For example, for Gogol.Storage.Types:
-- | View and manage your data across Google Cloud Platform services
type CloudPlatform'FullControl = "https://www.googleapis.com/auth/cloud-platform"
-- | View your data across Google Cloud Platform services
type CloudPlatform'ReadOnly = "https://www.googleapis.com/auth/cloud-platform.read-only"
-- | Manage your data and permissions in Google Cloud Storage
type Devstorage'FullControl = "https://www.googleapis.com/auth/devstorage.full_control"
-- | View your data in Google Cloud Storage
type Devstorage'ReadOnly = "https://www.googleapis.com/auth/devstorage.read_only"
-- | Manage your data in Google Cloud Storage
type Devstorage'ReadWrite = "https://www.googleapis.com/auth/devstorage.read_write"
Where the class instance for storage.objects.insert is generated as:
instance GoogleRequest StorageObjectsInsert where
type Scopes StorageObjectsInsert = '[CloudPlatform'FullControl, Devstorage'FullControl, Devstorage'ReadWrite]
The various scope-related type families have been reworked to a) explicitly only require one scope from Scopes, above, and b) allow propagating explicit scopes, such as the least privileged scope. You'll still need to make the list of scopes on Env concrete at some point in your program, but hopefully this allows more sensible scope constraints rather than being forced to carry around a concrete type-level list everywhere.
For example, omitting any constraints in the following example:
uploadFile ::
Env scopes ->
BucketName ->
Object ->
MediaType ->
FilePath ->
IO (Either Error Object)
uploadFile env bucket object media path =
liftIO $ do
let meta =
newStorageObjectsInsert bucket.text $
object
{ bucket = Just bucket.text
}
body <- GBody media <$> Network.HTTP.Client.streamFile path
runResourceT (Gogol.uploadEither env meta body)
downloadFile ::
Env scopes ->
BucketName ->
ObjectName ->
FilePath ->
IO (Either Error ())
downloadFile env bucket object path =
liftIO $ do
let meta = newStorageObjectsGet bucket.text object.text
runResourceT $ do
result <- downloadEither env meta
for result $ \stream ->
Conduit.connect stream (Conduit.Combinators.sinkFileCautious path)
Which results in the error(s):
• One scope from the following list is required:
'[CloudPlatform'FullControl, Devstorage'FullControl,
Devstorage'ReadWrite]
However, none of these scopes are present in the list of scopes you provided:
scopes
• In the first argument of ‘runResourceT’, namely
‘(uploadEither env meta body)’
In the expression: runResourceT (uploadEither env meta body)
In the second argument of ‘($)’, namely
‘\ _retryStatus -> runResourceT (uploadEither env meta body)’
|
00 | runResourceT (uploadEither env meta body)
| ^^^^^^^^^^^^^^^^^^
• One scope from the following list is required:
'[CloudPlatform'FullControl, CloudPlatform'ReadOnly,
Devstorage'FullControl, Devstorage'ReadOnly, Devstorage'ReadWrite]
However, none of these scopes are present in the list of scopes you provided:
scopes
• In a stmt of a 'do' block:
result <- downloadEither env meta
In the second argument of ‘($)’, namely
‘do result <- downloadEither env meta
for result
$ \ stream
-> Conduit.connect
stream (Conduit.Combinators.sinkFileCautious path)’
In the expression:
runResourceT
$ do result <- downloadEither env meta
for result
$ \ stream
-> Conduit.connect
stream (Conduit.Combinators.sinkFileCautious path)
|
00 | result <- downloadEither env meta
|
The error can be fixed by adding a constraint declaring which scope from required in the error message above can be found in the scopes type variable. For example, to explicitly choose the scope with least privilege for both operations:
OAuth2 scopes are now generated as type aliases. For example, for
Gogol.Storage.Types
:Where the class instance for
storage.objects.insert
is generated as:The various scope-related type families have been reworked to a) explicitly only require one scope from
Scopes
, above, and b) allow propagating explicit scopes, such as the least privileged scope. You'll still need to make the list of scopes onEnv
concrete at some point in your program, but hopefully this allows more sensible scope constraints rather than being forced to carry around a concrete type-level list everywhere.For example, omitting any constraints in the following example:
Which results in the error(s):
The error can be fixed by adding a constraint declaring which scope from
required
in the error message above can be found in thescopes
type variable. For example, to explicitly choose the scope with least privilege for both operations:Alternatively you can just leave it up to the caller to choose by propagating the full set of required scopes (of which only one is required):
See https://github.com/brendanhay/gogol/blob/7789a6a34b14a32d66b080b06c648ae2de6b206c/lib/gogol/src/Gogol/Auth/Scope.hs