From 9ad5e657d494557427edc094cccb4aa2b9b8768a Mon Sep 17 00:00:00 2001 From: Jens Timmerman Date: Sun, 4 Oct 2020 18:23:39 +0200 Subject: [PATCH] added login functionality --- vrtnu/vrtnu/ContentView.swift | 32 ++++++- vrtnu/vrtnu/VrtNuLayout.swift | 171 +++++++++++++++++----------------- vrtnu/vrtnu/vrtnuApp.swift | 14 +-- 3 files changed, 120 insertions(+), 97 deletions(-) diff --git a/vrtnu/vrtnu/ContentView.swift b/vrtnu/vrtnu/ContentView.swift index 5cdb9b0..40331f4 100644 --- a/vrtnu/vrtnu/ContentView.swift +++ b/vrtnu/vrtnu/ContentView.swift @@ -9,12 +9,39 @@ import SwiftUI import AVKit import AVFoundation import Combine +import TVUIKit struct ContentView: View { + @ViewBuilder + var body: some View { + let vrtNu = VRTNu() + if vrtNu.loggedIN() { + VRTNuView(vrtNu: vrtNu) + }else{ + LoginView(vrtNu: vrtNu) + } + } +} + +struct LoginView: View{ + var vrtNu: VRTNu + @State private var password: String = "" + @State private var username: String = "" + + var body: some View { + TextField("VRTNu username", text: $username) + SecureField("VRTNu password", text: $password) + Button("Inloggen", action: { + vrtNu.login(username: username, password: password) + }) + } +} +struct VRTNuView: View{ + var vrtNu: VRTNu var body: some View { NavigationView(){ - List(VRTNu().shows, id: \.self){ show in + List(vrtNu.getShows(), id: \.self){ show in NavigationLink(destination: ShowView(show: show)){ HStack{ AsyncImage(url: show.imageURL,placeholder: { @@ -28,7 +55,6 @@ struct ContentView: View { } } } - struct ShowView: View { var show: Show var body: some View { @@ -102,7 +128,7 @@ struct VideoView: View { } struct ContentView_Previews: PreviewProvider { static var previews: some View { - SeasonView(season: VRTNu().shows[0].getSeasons()[0]) + SeasonView(season: VRTNu().getShows()[0].getSeasons()[0]) //ContentView() } } diff --git a/vrtnu/vrtnu/VrtNuLayout.swift b/vrtnu/vrtnu/VrtNuLayout.swift index 4f49fce..e8b5bca 100644 --- a/vrtnu/vrtnu/VrtNuLayout.swift +++ b/vrtnu/vrtnu/VrtNuLayout.swift @@ -7,8 +7,10 @@ import Foundation +let just = JustOf() struct Episode: Hashable, Comparable{ + static func < (lhs: Episode, rhs: Episode) -> Bool { return lhs.name < rhs.name } @@ -19,10 +21,11 @@ struct Episode: Hashable, Comparable{ lazy var video: Video = { - let just = JustOf() + let token = self.season.show.vrtNu.getToken() //`requests.get('https://www.vrt.be/vrtnu/a-z/%s/%s/%s.mssecurevideo.json' % (show, season, episode)).json()` let url = "https://www.vrt.be/vrtnu/a-z/" + season.show.showName + "/" + season.seasonName + "/" + name + ".mssecurevideo.json" print(url) + let msecjson = just.get(url).json! let mssecdict = msecjson as! NSDictionary print(msecjson) @@ -30,74 +33,9 @@ struct Episode: Hashable, Comparable{ let videoid = intmssecdict.value(forKey: "videoid") as! String let clientid = intmssecdict.value(forKey: "clientid") as! String - /* - get login token - ``` - session = requests.session() - username = urllib.parse.quote('', safe='') - password = urllib.parse.quote('', safe='') - auth_data = { - 'APIKey': '3_0Z2HujMtiWq_pkAjgnS2Md2E11a1AwZjYiBETtwNE-EoEHDINgtnvcAOpNgmrVGy', - 'targetEnv': 'jssdk', - 'loginID': username, - 'password': password, - 'authMode': 'cookie', - } - auth_info = requests.post('https://accounts.eu1.gigya.com/accounts.login', data=auth_data).json() - # When requesting a token, no actual token is returned, but the - # necessary cookies are set. - session.post('https://token.vrt.be', - headers={ - 'Content-Type': 'application/json', - 'Referer': 'https://www.vrt.be/vrtnu/', - }, - data=json.dumps({ - 'uid': auth_info['UID'], - 'uidsig': auth_info['UIDSignature'], - 'ts': auth_info['signatureTimestamp'], - 'email': auth_info['profile']['email'], - }).encode('utf-8')) - token = session.post('https://media-services-public.vrt.be/vualto-video-aggregator-web/rest/external/v1/tokens', headers={'Content-Type': 'application/json'}, data=b'').json()['vrtPlayerToken'] - ```*/ - let username = "testuser" - let password = "testpw" - let auth_data = [ - "ApiKey": "3_0Z2HujMtiWq_pkAjgnS2Md2E11a1AwZjYiBETtwNE-EoEHDINgtnvcAOpNgmrVGy", - "targetEnv": "jssdk", - "loginID": username, - "password": password, - "authMode": "cookie", - ] - let auth_json = just.post("https://accounts.eu1.gigya.com/accounts.login", data: auth_data).json! - let auth_info = auth_json as! NSDictionary - print(auth_info) - - // no token is returnd but necessary cookies are set - just.post("https://token.vrt.be", json:[ - "uid": auth_info.value(forKey: "UID"), - "uidsig": auth_info.value(forKey: "UIDSignature"), - "ts": auth_info.value(forKey: "signatureTimestamp"), - //"email": auth_info.value(forKey: "profile"['email'], - "email": username - ], - headers: [ - "Conetnt-Type": "application/json", - "Referer": "https://www.vrt.be/vrtnu/", - ] - - ) - - ///token = session.post('https://media-services-public.vrt.be/vualto-video-aggregator-web/rest/external/v1/tokens', headers={'Content-Type': 'application/json'}, data=b'').json()['vrtPlayerToken'] - - let tokenjson = just.post("https://media-services-public.vrt.be/vualto-video-aggregator-web/rest/external/v1/tokens", headers:["Content-Type": "application/json"]).json! - let tokendict = tokenjson as! NSDictionary - let token = tokendict.value(forKey: "vrtPlayerToken") as! String - print(token) - - var mediaurl = "https://media-services-public.vrt.be/vualto-video-aggregator-web/rest/external/v1/videos/" + videoid mediaurl = mediaurl + "?vrtPlayerToken=" - mediaurl = mediaurl + token + "&client=" + mediaurl = mediaurl + self.season.show.vrtNu.getToken() + "&client=" mediaurl = mediaurl + clientid + "@PROD" print(mediaurl) let videojson = just.get(mediaurl).json! @@ -207,6 +145,7 @@ struct Show: Hashable, Comparable{ let showURL: URL let title: String let imageURL: URL + let vrtNu: VRTNu lazy var seasons: [Season] = { //`re.findall('value="#parsys_container_banner_%s_(.*)">' % show, requests.get('https://www.vrt.be/vrtnu/a-z/%s/' % show).text)` @@ -229,12 +168,13 @@ struct Show: Hashable, Comparable{ }() - init(showName: String, title: String, imageURL: URL) { + init(vrtNu: VRTNu, showName: String, title: String, imageURL: URL) { self.showURL = URL(string: "https://www.vrt.be/vrtnu/a-z/" + showName)! self.showName = showName self.title = title //TODO: get image urls for shows self.imageURL = imageURL + self.vrtNu = vrtNu } @@ -256,11 +196,10 @@ extension NSTextCheckingResult { } } -struct VRTNu { - let shows: [Show] +struct VRTNu: Hashable { + lazy var loggedin: Bool = loggedIN() - init() { - print("init") + lazy var shows: [Show] = { let regexPattern = "a href=\"/vrtnu/a-z/(.*).relevant" let imageregexPattern = "data-responsive-image=\".*(jpg|png)" let data = Just.get("https://www.vrt.be/vrtnu/a-z/").text! @@ -276,23 +215,81 @@ struct VRTNu { for i in 0 ..< output.count{ show = output[i].replacingOccurrences(of: ".relevant", with: "").replacingOccurrences(of: "a href=\"/vrtnu/a-z/", with: "") image = imageoutput[i].replacingOccurrences(of: "https:", with: "").replacingOccurrences(of: "http:", with: "").replacingOccurrences(of: "data-responsive-image=\"", with: "https:") - myshows.append(Show(showName: show, title: show, imageURL: URL(string: image)!)) + myshows.append(Show(vrtNu: self, showName: show, title: show, imageURL: URL(string: image)!)) } myshows.sort() - self.shows = myshows - //print(self.shows) + return myshows + }() + + func getToken() -> String { + ///token = session.post('https://media-services-public.vrt.be/vualto-video-aggregator-web/rest/external/v1/tokens', headers={'Content-Type': 'application/json'}, data=b'').json()['vrtPlayerToken'] + let tokenjson = just.post("https://media-services-public.vrt.be/vualto-video-aggregator-web/rest/external/v1/tokens", headers:["Content-Type": "application/json"]).json! + let tokendict = tokenjson as! NSDictionary + let token = tokendict.value(forKey: "vrtPlayerToken") as! String + print(token) + return token + } + + func loggedIN() -> Bool{ + + //check if current token is valid + let testtoken = self.getToken() + let testurl = URL(string: "https://media-services-public.vrt.be/vualto-video-aggregator-web/rest/external/v1/videos/pbs-pub-414bb095-6c5c-4c0e-b998-649fe03f07d7$vid-7ed5d7e0-e284-4df0-a76d-ff497e667d04?vrtPlayerToken=" + testtoken + "&client=vrtvideo@PROD")! + + let videojson = just.get(testurl).json! as! NSDictionary + if videojson.object(forKey: "code") != nil{ + if videojson.value(forKey: "code") as! String == "AUTHENTICATION_REQUIRED" + { + print("not authenticated") + return false + } + print("maybe vrt authentication logic changed? please report this") + } + return true - - /*self.shows = [ - Show(showUrl: URL(string: "a-z/het-peulengaleis/")!, title: "Het Peulengaleis"), - Show(showUrl: URL(string: "https://www.vrt.be/vrtnu/a-z/het-peulengaleis2/")!, title: "Het Peulengaleis 2"), - Show(showUrl: URL(string: "https://www.vrt.be/vrtnu/a-z/het-peulengaleis3/")!, title: "Het Peulengaleis 3"), - Show(showUrl: URL(string: "https://www.vrt.be/vrtnu/a-z/het-peulengaleis4/")!, title: "Het Peulengaleis 4"), - // Show(showUrl: URL(string: "https://www.vrt.be/vrtnu/a-z/het-peulengaleis5/")!, title: "Het Peulengaleis 5"), - //Show(showUrl: URL(string: "https://www.vrt.be/vrtnu/a-z/het-peulengaleis6/")!, title: "Het Peulengaleis 6"), - //Show(showUrl: URL(string: "https://www.vrt.be/vrtnu/a-z/het-peulengaleis7/")!, title: "Het Peulengaleis 7"), - //Show(showUrl: URL(string: "https://www.vrt.be/vrtnu/a-z/het-peulengaleis8/")!, title: "Het Peulengaleis 8"), - - ]*/ + } + func login(username: String, password:String) -> Bool { + let auth_data = [ + "ApiKey": "3_0Z2HujMtiWq_pkAjgnS2Md2E11a1AwZjYiBETtwNE-EoEHDINgtnvcAOpNgmrVGy", + "targetEnv": "jssdk", + "loginID": username, + "password": password, + "authMode": "cookie", + ] + let auth_json = just.post("https://accounts.eu1.gigya.com/accounts.login", data: auth_data).json! + let auth_info = auth_json as! NSDictionary + print(auth_info) + if auth_info.object(forKey: "statusCode") != nil{ + if auth_info.value(forKey: "statusCode") as! Int == 403 + { + print("not authenticated") + return false + } + } + // no token is returnd but necessary cookies are set + just.post("https://token.vrt.be", json:[ + "uid": auth_info.value(forKey: "UID"), + "uidsig": auth_info.value(forKey: "UIDSignature"), + "ts": auth_info.value(forKey: "signatureTimestamp"), + //"email": auth_info.value(forKey: "profile"['email'], + "email": username + ], + headers: [ + "Conetnt-Type": "application/json", + "Referer": "https://www.vrt.be/vrtnu/", + ] + + ) + return loggedIN() + + } + + init() { + print("init") + } + + func getShows() -> [Show]{ + var mutableself = self + return mutableself.shows } } diff --git a/vrtnu/vrtnu/vrtnuApp.swift b/vrtnu/vrtnu/vrtnuApp.swift index 1012020..b96bf22 100644 --- a/vrtnu/vrtnu/vrtnuApp.swift +++ b/vrtnu/vrtnu/vrtnuApp.swift @@ -18,13 +18,13 @@ struct vrtnuApp: App { func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey : Any]? = nil) -> Bool { - let audioSession = AVAudioSession.sharedInstance() - do { - try audioSession.setCategory(.playback, mode: .moviePlayback) - } - catch { - print("Setting category to AVAudioSessionCategoryPlayback failed.") - } + //let audioSession = AVAudioSession.sharedInstance() + //do { + // try audioSession.setCategory(.playback, mode: .moviePlayback) + //} + //catch { + // print("Setting category to AVAudioSessionCategoryPlayback failed.") + //} return true } }