Merge branch 'master' of github.com:AnonymusRaccoon/Aeris into mobile_client

This commit is contained in:
Arthi-chaud
2022-03-04 14:04:37 +01:00
2 changed files with 54 additions and 46 deletions
+29 -14
View File
@@ -19,17 +19,16 @@ import qualified Data.ByteString.Char8 as B8
import Servant.Auth.Server (AuthResult(Authenticated))
import System.Environment.MrEnv (envAsString)
oauthHandler :: AuthRes -> Service -> Maybe String -> Maybe String -> AppM NoContent
oauthHandler _ _ Nothing _ = throwError err400
oauthHandler _ _ _ Nothing = throwError err400
oauthHandler (Authenticated (User uid _ _)) service (Just code) (Just redirect) = do
tokens <- liftIO $ getOauthTokens service code redirect
oauthHandler :: AuthRes -> Service -> Maybe String -> AppM NoContent
oauthHandler _ _ Nothing = throwError err400
oauthHandler (Authenticated (User uid _ _)) service (Just code) = do
tokens <- liftIO $ getOauthTokens service code
case tokens of
Nothing -> throwError err403
Just t -> do
updateTokens uid t
return NoContent
oauthHandler _ service (Just code) (Just redirect) = throwError err401
oauthHandler _ service (Just code) = throwError err401
oauthDelHandler :: AuthRes -> Service -> AppM NoContent
oauthDelHandler (Authenticated (User uid _ _)) service = do
@@ -41,28 +40,34 @@ urlHandler :: Service -> Maybe String -> AppM NoContent
urlHandler _ Nothing = throwError err400
urlHandler Anilist (Just r) = do
clientId <- liftIO $ envAsString "ANILIST_CLIENT_ID" ""
backRedirect <- liftIO $ envAsString "BACK_REDIRECT_URL" ""
throwError $ err302 { errHeaders =
[("Location", B8.pack $ "https://anilist.co/api/v2/oauth/authorize?client_id=" ++ clientId ++ "&response_type=code&redirect_uri=" ++ r)] }
[("Location", B8.pack $ "https://anilist.co/api/v2/oauth/authorize?client_id=" ++ clientId ++ "&response_type=code&redirect_uri=" ++ backRedirect ++ "&state=" ++ r)] }
urlHandler Discord (Just r) = do
clientId <- liftIO $ envAsString "DISCORD_CLIENT_ID" ""
backRedirect <- liftIO $ envAsString "BACK_REDIRECT_URL" ""
throwError $ err302 { errHeaders =
[("Location", B8.pack $ "https://discord.com/api/oauth2/authorize?response_type=code&scope=identify&client_id=" ++ clientId ++ "&response_type=code&redirect_uri=" ++ r)] }
[("Location", B8.pack $ "https://discord.com/api/oauth2/authorize?response_type=code&scope=identify&client_id=" ++ clientId ++ "&response_type=code&redirect_uri=" ++ backRedirect ++ "&state=" ++ r)] }
urlHandler Google (Just r) = do
clientId <- liftIO $ envAsString "GOOGLE_CLIENT_ID" ""
backRedirect <- liftIO $ envAsString "BACK_REDIRECT_URL" ""
throwError $ err302 { errHeaders =
[("Location", B8.pack $ "https://accounts.google.com/o/oauth2/v2/auth?scope=https://www.googleapis.com/auth/youtube.force-ssl&access_type=offline&include_granted_scopes=true&response_type=code&state=state&client_id=" ++ clientId ++ "&redirect_uri=" ++ r)] }
[("Location", B8.pack $ "https://accounts.google.com/o/oauth2/v2/auth?scope=https://www.googleapis.com/auth/youtube.force-ssl&access_type=offline&prompt=consent&include_granted_scopes=true&response_type=code&client_id=" ++ clientId ++ "&redirect_uri=" ++ backRedirect ++ "&state=" ++ r)] }
urlHandler Twitter (Just r) = do
clientId <- liftIO $ envAsString "TWITTER_CLIENT_ID" ""
backRedirect <- liftIO $ envAsString "BACK_REDIRECT_URL" ""
throwError $ err302 { errHeaders =
[("Location", B8.pack $ "https://twitter.com/i/oauth2/authorize?response_type=code&scope=like.write like.read follows.read follows.write offline.access tweet.read tweet.write&state=state&code_challenge=challenge&code_challenge_method=plain&client_id=" ++ clientId ++ "&redirect_uri=" ++ r)] }
[("Location", B8.pack $ "https://twitter.com/i/oauth2/authorize?response_type=code&scope=like.write like.read follows.read follows.write offline.access tweet.read tweet.write&code_challenge=challenge&code_challenge_method=plain&client_id=" ++ clientId ++ "&redirect_uri=" ++ backRedirect ++ "&state=" ++ r)] }
urlHandler Spotify (Just r) = do
clientId <- liftIO $ envAsString "SPOTIFY_CLIENT_ID" ""
backRedirect <- liftIO $ envAsString "BACK_REDIRECT_URL" ""
throwError $ err302 { errHeaders =
[("Location", B8.pack $ "https://accounts.spotify.com/authorize?response_type=code&state=state&scope=user-library-read&client_id=" ++ clientId ++ "&redirect_uri=" ++ r)] }
[("Location", B8.pack $ "https://accounts.spotify.com/authorize?response_type=code&scope=user-library-read&client_id=" ++ clientId ++ "&redirect_uri=" ++ backRedirect ++ "&state=" ++ r)] }
urlHandler Github (Just r) = do
clientId <- liftIO $ envAsString "GITHUB_CLIENT_ID" ""
backRedirect <- liftIO $ envAsString "BACK_REDIRECT_URL" ""
throwError $ err302 { errHeaders =
[("Location", B8.pack $ "https://github.com/login/oauth/authorize?response_type=code&client_id=" ++ clientId ++ "&redirect_uri=" ++ r)] }
[("Location", B8.pack $ "https://github.com/login/oauth/authorize?response_type=code&scope=repo&client_id=" ++ clientId ++ "&redirect_uri=" ++ backRedirect ++ "&state=" ++ r)] }
servicesHandler :: AuthRes -> AppM [String]
servicesHandler (Authenticated (User uid name slug)) = do
@@ -70,13 +75,23 @@ servicesHandler (Authenticated (User uid name slug)) = do
return $ fmap (show . service) tokens
servicesHandler _ = throwError err401
type OauthAPI = UserAuth :> Capture "service" Service :> QueryParam "code" String :> QueryParam "redirect_uri" String :> Get '[JSON] NoContent
redirectHandler :: Maybe String -> Maybe String -> AppM NoContent
redirectHandler Nothing _ = return NoContent
redirectHandler _ Nothing = return NoContent
redirectHandler (Just code) (Just state) = do
throwError $ err302 { errHeaders =
[("Location", B8.pack $ state ++ "?code=" ++ code )] }
return NoContent
type OauthAPI = UserAuth :> Capture "service" Service :> QueryParam "code" String :> Get '[JSON] NoContent
:<|> UserAuth :> Capture "service" Service :> Delete '[JSON] NoContent
:<|> Capture "service" Service :> "url" :> QueryParam "redirect_uri" String :> Get '[JSON] NoContent
:<|> UserAuth :> "services" :> Get '[JSON] [String]
:<|> "redirect" :> QueryParam "code" String :> QueryParam "state" String :> Get '[JSON] NoContent
oauth :: ServerT OauthAPI AppM
oauth = oauthHandler
:<|> oauthDelHandler
:<|> urlHandler
:<|> servicesHandler
:<|> redirectHandler
+25 -32
View File
@@ -11,7 +11,7 @@ import Data.Aeson.Types (Object, Value (String))
import Data.Text (Text, pack, unpack)
import Network.HTTP.Simple (JSONException, addRequestHeader, getResponseBody, httpJSONEither, parseRequest, setRequestMethod, setRequestQueryString, setRequestBodyURLEncoded)
import System.Environment.MrEnv (envAsBool, envAsInt, envAsInteger, envAsString)
import Utils (lookupObjString, lookupObjInt)
import Utils (lookupObjString)
import Data.ByteString.Base64
data OAuth2Conf = OAuth2Conf
{ oauthClientId :: String
@@ -40,8 +40,8 @@ getGithubConfig =
<*> envAsString "GITHUB_SECRET" ""
<*> pure "https://github.com/login/oauth/access_token"
getGithubTokens :: String -> String -> IO (Maybe ExternalToken)
getGithubTokens code _ = do
getGithubTokens :: String -> IO (Maybe ExternalToken)
getGithubTokens code = do
gh <- getGithubConfig
let endpoint = tokenEndpoint code gh
request' <- parseRequest endpoint
@@ -59,9 +59,7 @@ getGithubTokens code _ = do
Left _ -> Nothing
Right obj -> do
access <- lookupObjString obj "access_token"
refresh <- lookupObjString obj "refresh_token"
expires_in <- lookupObjInt obj "expires_in"
Just $ ExternalToken (pack access) (pack refresh) expires_in Github
Just $ ExternalToken (pack access) "" 0 Github
-- DISCORD
getDiscordConfig :: IO OAuth2Conf
@@ -71,8 +69,8 @@ getDiscordConfig =
<*> envAsString "DISCORD_SECRET" ""
<*> pure "https://discord.com/api/oauth2/token"
getDiscordTokens :: String -> String -> IO (Maybe ExternalToken)
getDiscordTokens code redirect = do
getDiscordTokens :: String -> IO (Maybe ExternalToken)
getDiscordTokens code = do
cfg <- getDiscordConfig
let endpoint = tokenEndpoint code cfg
request' <- parseRequest endpoint
@@ -84,7 +82,7 @@ getDiscordTokens code redirect = do
, ("client_secret", B8.pack . oauthClientSecret $ cfg)
, ("code", B8.pack code)
, ("grant_type", "authorization_code")
, ("redirect_uri", B8.pack redirect)
, ("redirect_uri", "http://localhost:8080/auth/redirect")
]
request'
response <- httpJSONEither request
@@ -93,8 +91,7 @@ getDiscordTokens code redirect = do
Right obj -> do
access <- lookupObjString obj "access_token"
refresh <- lookupObjString obj "refresh_token"
expires_in <- lookupObjInt obj "expires_in"
Just $ ExternalToken (pack access) (pack refresh) expires_in Discord
Just $ ExternalToken (pack access) (pack refresh) 0 Discord
-- GOOGLE
getGoogleConfig :: IO OAuth2Conf
@@ -104,8 +101,8 @@ getGoogleConfig =
<*> envAsString "GOOGLE_SECRET" ""
<*> pure "https://oauth2.googleapis.com/token"
getGoogleTokens :: String -> String -> IO (Maybe ExternalToken)
getGoogleTokens code redirect = do
getGoogleTokens :: String -> IO (Maybe ExternalToken)
getGoogleTokens code = do
cfg <- getGoogleConfig
let endpoint = tokenEndpoint code cfg
request' <- parseRequest endpoint
@@ -117,7 +114,7 @@ getGoogleTokens code redirect = do
, ("client_secret", B8.pack . oauthClientSecret $ cfg)
, ("code", B8.pack code)
, ("grant_type", "authorization_code")
, ("redirect_uri", B8.pack redirect)
, ("redirect_uri", "http://localhost:8080/auth/redirect")
]
request'
response <- httpJSONEither request
@@ -126,8 +123,7 @@ getGoogleTokens code redirect = do
Right obj -> do
access <- lookupObjString obj "access_token"
refresh <- lookupObjString obj "refresh_token"
expires_in <- lookupObjInt obj "expires_in"
Just $ ExternalToken (pack access) (pack refresh) expires_in Google
Just $ ExternalToken (pack access) (pack refresh) 0 Google
-- SPOTIFY
getSpotifyConfig :: IO OAuth2Conf
@@ -137,8 +133,8 @@ getSpotifyConfig =
<*> envAsString "SPOTIFY_SECRET" ""
<*> pure "https://accounts.spotify.com/api/token"
getSpotifyTokens :: String -> String -> IO (Maybe ExternalToken)
getSpotifyTokens code redirect = do
getSpotifyTokens :: String -> IO (Maybe ExternalToken)
getSpotifyTokens code = do
cfg <- getSpotifyConfig
let basicAuth = encodeBase64 $ B8.pack $ oauthClientId cfg ++ ":" ++ oauthClientSecret cfg
@@ -151,7 +147,7 @@ getSpotifyTokens code redirect = do
setRequestBodyURLEncoded
[ ("code", B8.pack code)
, ("grant_type", "authorization_code")
, ("redirect_uri", B8.pack redirect)
, ("redirect_uri", "http://localhost:8080/auth/redirect")
]
request'
response <- httpJSONEither request
@@ -160,8 +156,7 @@ getSpotifyTokens code redirect = do
Right obj -> do
access <- lookupObjString obj "access_token"
refresh <- lookupObjString obj "refresh_token"
expires_in <- lookupObjInt obj "expires_in"
Just $ ExternalToken (pack access) (pack refresh) expires_in Spotify
Just $ ExternalToken (pack access) (pack refresh) 0 Spotify
-- TWITTER
getTwitterConfig :: IO OAuth2Conf
@@ -171,8 +166,8 @@ getTwitterConfig =
<*> envAsString "TWITTER_SECRET" ""
<*> pure "https://api.twitter.com/2/oauth2/token"
getTwitterTokens :: String -> String -> IO (Maybe ExternalToken)
getTwitterTokens code redirect = do
getTwitterTokens :: String -> IO (Maybe ExternalToken)
getTwitterTokens code = do
cfg <- getTwitterConfig
let basicAuth = encodeBase64 $ B8.pack $ "Basic " ++ oauthClientId cfg ++ ":" ++ oauthClientSecret cfg
let endpoint = tokenEndpoint code cfg
@@ -184,7 +179,7 @@ getTwitterTokens code redirect = do
setRequestBodyURLEncoded
[ ("code", B8.pack code)
, ("grant_type", "authorization_code")
, ("redirect_uri", B8.pack redirect)
, ("redirect_uri", "http://localhost:8080/auth/redirect")
, ("code_verifier", "challenge")
]
request'
@@ -194,8 +189,7 @@ getTwitterTokens code redirect = do
Right obj -> do
access <- lookupObjString obj "access_token"
refresh <- lookupObjString obj "refresh_token"
expires_in <- lookupObjInt obj "expires_in"
Just $ ExternalToken (pack access) (pack refresh) expires_in Twitter
Just $ ExternalToken (pack access) (pack refresh) 0 Twitter
-- ANILIST
getAnilistConfig :: IO OAuth2Conf
@@ -205,8 +199,8 @@ getAnilistConfig =
<*> envAsString "ANILIST_SECRET" ""
<*> pure "https://anilist.co/api/v2/oauth/token"
getAnilistTokens :: String -> String -> IO (Maybe ExternalToken)
getAnilistTokens code redirect = do
getAnilistTokens :: String -> IO (Maybe ExternalToken)
getAnilistTokens code = do
cfg <- getAnilistConfig
let endpoint = tokenEndpoint code cfg
request' <- parseRequest endpoint
@@ -218,7 +212,7 @@ getAnilistTokens code redirect = do
, ("client_secret", B8.pack . oauthClientSecret $ cfg)
, ("code", B8.pack code)
, ("grant_type", "authorization_code")
, ("redirect_uri", B8.pack redirect)
, ("redirect_uri", "http://localhost:8080/auth/redirect")
]
request'
response <- httpJSONEither request
@@ -227,14 +221,13 @@ getAnilistTokens code redirect = do
Right obj -> do
access <- lookupObjString obj "access_token"
refresh <- lookupObjString obj "refresh_token"
expires_in <- lookupObjInt obj "expires_in"
Just $ ExternalToken (pack access) (pack refresh) expires_in Anilist
Just $ ExternalToken (pack access) (pack refresh) 0 Anilist
-- General
getOauthTokens :: Service -> String -> String -> IO (Maybe ExternalToken)
getOauthTokens :: Service -> String -> IO (Maybe ExternalToken)
getOauthTokens Github = getGithubTokens
getOauthTokens Discord = getDiscordTokens
getOauthTokens Spotify = getSpotifyTokens