From 05d0dc6a4f9db11f25590bb616164d44e09417c0 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Gj=C3=B8lga?= Date: Fri, 25 Jun 2021 13:49:01 +0200 Subject: [PATCH 01/17] started working with a WkWebView with cookie retrieval --- Quickfeed.xcodeproj/project.pbxproj | 4 + Quickfeed/Views/AuthWebWiew.swift | 119 ++++++++++++++++++++++++++++ Quickfeed/Views/LogIn.swift | 3 +- 3 files changed, 125 insertions(+), 1 deletion(-) create mode 100644 Quickfeed/Views/AuthWebWiew.swift diff --git a/Quickfeed.xcodeproj/project.pbxproj b/Quickfeed.xcodeproj/project.pbxproj index b54bc20..d284a93 100644 --- a/Quickfeed.xcodeproj/project.pbxproj +++ b/Quickfeed.xcodeproj/project.pbxproj @@ -76,6 +76,7 @@ FA8EA6A126039B0D00A10351 /* GroupList.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA8EA6A026039B0D00A10351 /* GroupList.swift */; }; FA9B950A26835A64003F115B /* ag.grpc.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAC9BCF4268358F5009B1E9B /* ag.grpc.swift */; }; FA9B950B26835A77003F115B /* ag.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAC9BCF3268358F5009B1E9B /* ag.pb.swift */; }; + FA9B950D2685D0A6003F115B /* AuthWebWiew.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA9B950C2685D0A6003F115B /* AuthWebWiew.swift */; }; FA9DC66A2644548D007F1A24 /* ReviewListHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA9DC6692644548D007F1A24 /* ReviewListHeader.swift */; }; FAA5DA36262EC643009DAEDE /* GradingBenchmarkHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAA5DA35262EC643009DAEDE /* GradingBenchmarkHeader.swift */; }; FAA798B5262D6C82005E2713 /* AssignmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAA798B4262D6C82005E2713 /* AssignmentView.swift */; }; @@ -168,6 +169,7 @@ FA85791225BEB4EA00223DB9 /* Quickfeed.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Quickfeed.entitlements; sourceTree = ""; }; FA8EA69B26038F5D00A10351 /* AddGroupForm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddGroupForm.swift; sourceTree = ""; }; FA8EA6A026039B0D00A10351 /* GroupList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupList.swift; sourceTree = ""; }; + FA9B950C2685D0A6003F115B /* AuthWebWiew.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthWebWiew.swift; sourceTree = ""; }; FA9DC6692644548D007F1A24 /* ReviewListHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReviewListHeader.swift; sourceTree = ""; }; FAA5DA35262EC643009DAEDE /* GradingBenchmarkHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradingBenchmarkHeader.swift; sourceTree = ""; }; FAA798B4262D6C82005E2713 /* AssignmentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssignmentView.swift; sourceTree = ""; }; @@ -416,6 +418,7 @@ FA85790A25BEB4E900223DB9 /* ContentView.swift */, D08D62952611D72A00343250 /* LogIn.swift */, D035C75725E92795005AC2BA /* NavigatorView.swift */, + FA9B950C2685D0A6003F115B /* AuthWebWiew.swift */, D0F6A1432609F20A00C1D825 /* User */, D04331D726028EAB0034C4B9 /* Admin */, D04B46E125D12E9D00AC8926 /* Student */, @@ -645,6 +648,7 @@ FA5A40E62609DCA700A20A13 /* SelectedMembers.swift in Sources */, FAA8330525E3E073008C05F4 /* MemberListItem.swift in Sources */, FA29717825D311B5000C99A1 /* SearchFieldController.swift in Sources */, + FA9B950D2685D0A6003F115B /* AuthWebWiew.swift in Sources */, FAA8333E25E519E2008C05F4 /* ResultGrid.swift in Sources */, FA5FBDE225E7E63E007EC0E3 /* ServerProvider.swift in Sources */, D04B46EC25D1301200AC8926 /* LabSection.swift in Sources */, diff --git a/Quickfeed/Views/AuthWebWiew.swift b/Quickfeed/Views/AuthWebWiew.swift new file mode 100644 index 0000000..569928f --- /dev/null +++ b/Quickfeed/Views/AuthWebWiew.swift @@ -0,0 +1,119 @@ +// +// AuthWebWiew.swift +// Quickfeed +// +// Created by Oskar Gjølga on 25/06/2021. +// + +import SwiftUI +import WebKit +import Combine +import Foundation +import AppKit + +struct AuthWebView: View { + @ObservedObject var model: WebViewModel + + init(mesgURL: String) { + //Assign the url to the model and initialise the model + self.model = WebViewModel(link: mesgURL) + } + + var body: some View { + //Create the WebView with the model + SwiftUIWebView(viewModel: model) + .onChange(of: model.pageTitle, perform: { value in + print(model.sitedata) + + }) + } +} + +struct SwiftUIWebView: NSViewRepresentable { + + public typealias NSViewType = WKWebView + @ObservedObject var viewModel: WebViewModel + + private let webView: WKWebView = WKWebView() + public func makeNSView(context: NSViewRepresentableContext) -> WKWebView { + webView.navigationDelegate = context.coordinator + webView.uiDelegate = context.coordinator as? WKUIDelegate + webView.load(Foundation.URLRequest(url: URL(string: viewModel.link)!)) + return webView + } + + public func updateNSView(_ nsView: WKWebView, context: NSViewRepresentableContext) { } + + public func makeCoordinator() -> Coordinator { + return Coordinator(viewModel) + } + + class Coordinator: NSObject, WKNavigationDelegate { + private var viewModel: WebViewModel + + init(_ viewModel: WebViewModel) { + //Initialise the WebViewModel + self.viewModel = viewModel + } + + public func webView(_: WKWebView, didFail: WKNavigation!, withError: Error) { } + + public func webView(_: WKWebView, didFailProvisionalNavigation: WKNavigation!, withError: Error) { } + + //After the webpage is loaded, assign the data in WebViewModel class + public func webView(_ web: WKWebView, didFinish: WKNavigation!) { + self.viewModel.pageTitle = web.title! + self.viewModel.link = web.url?.absoluteString as! String + self.viewModel.didFinishLoading = true + web.getCookies(for: "uis.itest.run"){data in + self.viewModel.sitedata = data + print(data) + } + + + } + + public func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { } + + public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { + decisionHandler(.allow) + } + + } + +} + + +class WebViewModel: ObservableObject { + @Published var sitedata: [String : Any] + @Published var link: String + @Published var didFinishLoading: Bool = false + @Published var pageTitle: String + + init (link: String) { + self.link = link + self.pageTitle = "" + self.sitedata = [:] + } +} + +extension WKWebView { + + private var httpCookieStore: WKHTTPCookieStore { return WKWebsiteDataStore.default().httpCookieStore } + + func getCookies(for domain: String? = nil, completion: @escaping ([String : Any])->()) { + var cookieDict = [String : AnyObject]() + httpCookieStore.getAllCookies { cookies in + for cookie in cookies { + if let domain = domain { + if cookie.domain.contains(domain) { + cookieDict[cookie.name] = cookie.properties as AnyObject? + } + } else { + cookieDict[cookie.name] = cookie.properties as AnyObject? + } + } + completion(cookieDict) + } + } +} diff --git a/Quickfeed/Views/LogIn.swift b/Quickfeed/Views/LogIn.swift index c3a0b97..b39cd74 100644 --- a/Quickfeed/Views/LogIn.swift +++ b/Quickfeed/Views/LogIn.swift @@ -26,7 +26,8 @@ struct LogIn: View { } .padding(.horizontal) GitHubLogIn(viewModel: viewModel, login: $login) + AuthWebView(mesgURL: "https://uis.itest.run") } - .frame(width: 300, height: 165) + .frame(width: 500, height: 500) } } From 6adab4b7216d81cc1efe34e89d008d6a902502a1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Gj=C3=B8lga?= Date: Fri, 25 Jun 2021 14:13:29 +0200 Subject: [PATCH 02/17] removed warnings --- Quickfeed/Views/AuthWebWiew.swift | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/Quickfeed/Views/AuthWebWiew.swift b/Quickfeed/Views/AuthWebWiew.swift index 569928f..aafad0c 100644 --- a/Quickfeed/Views/AuthWebWiew.swift +++ b/Quickfeed/Views/AuthWebWiew.swift @@ -2,7 +2,7 @@ // AuthWebWiew.swift // Quickfeed // -// Created by Oskar Gjølga on 25/06/2021. +// WebView in SwiftUI: https://stackoverflow.com/questions/62962063/implement-webkit-with-swiftui-on-macos-and-create-a-preview-of-a-webpage // import SwiftUI @@ -23,8 +23,7 @@ struct AuthWebView: View { //Create the WebView with the model SwiftUIWebView(viewModel: model) .onChange(of: model.pageTitle, perform: { value in - print(model.sitedata) - + print(model.siteData) }) } } @@ -63,10 +62,10 @@ struct SwiftUIWebView: NSViewRepresentable { //After the webpage is loaded, assign the data in WebViewModel class public func webView(_ web: WKWebView, didFinish: WKNavigation!) { self.viewModel.pageTitle = web.title! - self.viewModel.link = web.url?.absoluteString as! String + self.viewModel.link = web.url!.absoluteString self.viewModel.didFinishLoading = true web.getCookies(for: "uis.itest.run"){data in - self.viewModel.sitedata = data + self.viewModel.siteData = data print(data) } @@ -75,7 +74,7 @@ struct SwiftUIWebView: NSViewRepresentable { public func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { } - public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Void) { + public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Swift.Void) { decisionHandler(.allow) } @@ -85,7 +84,7 @@ struct SwiftUIWebView: NSViewRepresentable { class WebViewModel: ObservableObject { - @Published var sitedata: [String : Any] + @Published var siteData: [String : Any] @Published var link: String @Published var didFinishLoading: Bool = false @Published var pageTitle: String @@ -93,7 +92,7 @@ class WebViewModel: ObservableObject { init (link: String) { self.link = link self.pageTitle = "" - self.sitedata = [:] + self.siteData = [:] } } From 4359c48eb5fa61dedfd780cfcfb3b1e147c63bcd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Kristian=20Teisrud?= Date: Mon, 28 Jun 2021 17:59:42 +0200 Subject: [PATCH 03/17] reorganize serverprovider and providerprotocol; added MARK: commands to make the code more understandable to others --- Quickfeed/Providers/ProviderProtocol.swift | 71 +++++--- Quickfeed/Providers/ServerProvider.swift | 191 +++++++++++++-------- 2 files changed, 170 insertions(+), 92 deletions(-) diff --git a/Quickfeed/Providers/ProviderProtocol.swift b/Quickfeed/Providers/ProviderProtocol.swift index 29c34cd..68e661c 100644 --- a/Quickfeed/Providers/ProviderProtocol.swift +++ b/Quickfeed/Providers/ProviderProtocol.swift @@ -9,43 +9,66 @@ import NIO protocol ProviderProtocol{ + // MARK: Users func setUser(userID: UInt64) func getUser() -> User? - func getCoursesForCurrentUser(userID: UInt64, userStatus: [Enrollment.UserStatus]) -> [Course]? - func isAuthorizedTeacher() -> Bool - func getCourses() -> [Course]? func getUsers() -> [User]? func updateUser(user: User) - - func getCourse(courseId: UInt64) -> Course? - func getAssignments(courseID: UInt64) -> [Assignment] - func createEnrollment(courseID: UInt64, userID: UInt64) - func updateEnrollment(enrollment: Enrollment, status: Enrollment.UserStatus) + func isAuthorizedTeacher() -> Bool - func createNewCourse(course: Course) -> Course? - func updateCourse(course: Course) + // MARK: Groups + func getGroup(groupID: UInt64) -> Group? + func getGroupByUserAndCourse(courseId: UInt64, groupID: UInt64?, userId: UInt64) -> Group? + func getGroupsByCourse(courseId: UInt64) -> EventLoopFuture func createGroup(group: Group) -> EventLoopFuture + func updateGroup(group: Group) + func deleteGroup(userID: UInt64, groupID: UInt64, courseID: UInt64) + // MARK: Courses + func getCourse(courseId: UInt64) -> Course? + func getCourses() -> [Course]? + func getCoursesByUser(userID: UInt64, userStatus: [Enrollment.UserStatus]) -> [Course]? + func createCourse(course: Course) -> Course? + func updateCourse(course: Course) + func updateCourseVisibility(enrollment: Enrollment) - func getGroupByUserAndCourse(courseId: UInt64, groupID: UInt64?, userId: UInt64) -> Group? - func getGroupsByCourse(courseId: UInt64) -> EventLoopFuture - func getSubmissionsByUser(courseId: UInt64, userId: UInt64) -> [Submission] - func getSubmissionsByGroub(courseId: UInt64, groupId: UInt64) -> [Submission] - func getSubmissionsByCourse(courseId: UInt64, type: SubmissionsForCourseRequest.TypeEnum) -> EventLoopFuture - func getEnrollmentsForUser(userId: UInt64) -> [Enrollment] - func getOrganization(orgName: String) -> EventLoopFuture - func getProviders() -> [String] + // MARK: Assignments + //func getAssignments(courseID: UInt64) -> [Assignment]? func updateAssignments(courseId: UInt64) -> Bool + + // MARK: Enrollments + func getEnrollmentsByUser(userID: UInt64, userStatus: [Enrollment.UserStatus]) -> [Enrollment]? + func getEnrollmentsByCourse(courseId: UInt64, ignoreGroupMembers: Bool?, withActivity: Bool?, userStatus: [Enrollment.UserStatus]) -> EventLoopFuture + func createEnrollment(enrollment: Enrollment) + func updateEnrollment(enrollment: Enrollment) + func updateEnrollments(courseID: UInt64) + + // MARK: Submissions + func getSubmissions(userID: UInt64?, groupID: UInt64?, courseID: UInt64) -> [Submission]? + func getSubmissionsByCourse(courseId: UInt64, type: SubmissionsForCourseRequest.TypeEnum) -> EventLoopFuture func updateSubmission(courseId: UInt64, submisssion: Submission) -> Bool func updateSubmissions(assignmentID: UInt64, courseID: UInt64, score: UInt32, release: Bool, approve: Bool) - func rebuildSubmission(assignmentId: UInt64, submissionId: UInt64) -> Submission? - func getRepositories(courseId: UInt64, types: [Repository.Type]) + func rebuildSubmission(submissionID: UInt64, assignmentID: UInt64) -> Bool - func getEnrollmentsByCourse(courseId: UInt64, ignoreGroupMembers: Bool?, withActivity: Bool?, userStatus: [Enrollment.UserStatus]) -> EventLoopFuture + // MARK: Manual Grading + // MARK: Misc + func getProviders() -> [String]? + func getOrganization(orgName: String) -> EventLoopFuture + func getRepositories(courseID: UInt64, repositoryTypes: [Repository.TypeEnum]) -> Repositories? + func isEmptyRepo(userID: UInt64, groupID: UInt64, courseID: UInt64) + + // TODO: clean + func getCoursesForCurrentUser(userID: UInt64, userStatus: [Enrollment.UserStatus]) -> [Course]? + func getAssignments(courseID: UInt64) -> [Assignment] + func createEnrollment(courseID: UInt64, userID: UInt64) + func getEnrollmentsForUser(userId: UInt64) -> [Enrollment] + func updateEnrollment(enrollment: Enrollment, status: Enrollment.UserStatus) + func getSubmissionsByUser(courseId: UInt64, userId: UInt64) -> [Submission] + func getSubmissionsByGroub(courseId: UInt64, groupId: UInt64) -> [Submission] + func loadCriteria(courseId: UInt64, assignmentId: UInt64) -> [GradingBenchmark] func createReview(courseId: UInt64, review: Review) -> Review? - func getReviewers(submissionId: UInt64, courseId: UInt64) -> Reviewers? func updateReview(courseId: UInt64, review: Review) - func loadCriteria(courseId: UInt64, assignmentId: UInt64) -> [GradingBenchmark] - + func getReviewers(submissionId: UInt64, courseId: UInt64) -> Reviewers? + func createNewCourse(course: Course) -> Course? } diff --git a/Quickfeed/Providers/ServerProvider.swift b/Quickfeed/Providers/ServerProvider.swift index 4a59b85..7d417b3 100644 --- a/Quickfeed/Providers/ServerProvider.swift +++ b/Quickfeed/Providers/ServerProvider.swift @@ -7,14 +7,14 @@ import Foundation import NIO class ServerProvider: ProviderProtocol{ - - var grpcManager: GRPCManager = GRPCManager.shared static let shared: ServerProvider = ServerProvider() + var grpcManager: GRPCManager = GRPCManager.shared private init(){ print("New ServerProvider") } + // MARK: Users func setUser(userID: UInt64){ grpcManager.setUser(userID: userID) } @@ -23,32 +23,143 @@ class ServerProvider: ProviderProtocol{ return grpcManager.getUser() } + func getUsers() -> [User]? { + return grpcManager.getUsers() + } + func updateUser(user: User) { grpcManager.updateUser(user: user) } - func getCoursesForCurrentUser(userID: UInt64, userStatus: [Enrollment.UserStatus]) -> [Course]? { - return grpcManager.getCoursesByUser(userID: userID, userStatus: userStatus) + func isAuthorizedTeacher() -> Bool { + return grpcManager.isAuthorizedTeacher() } - func getOrganization(orgName: String) -> EventLoopFuture { - return grpcManager.getOrganization(orgName: orgName) + // MARK: Groups + func getGroup(groupID: UInt64) -> Group? { + return grpcManager.getGroup(groupID: groupID) } - func isAuthorizedTeacher() -> Bool { - return grpcManager.isAuthorizedTeacher() + func getGroupByUserAndCourse(courseId: UInt64, groupID: UInt64?, userId: UInt64) -> Group? { + return self.grpcManager.getGroupByUserAndCourse(userID: userId, groupID: groupID, courseID: courseId) + } + + func getGroupsByCourse(courseId: UInt64) -> EventLoopFuture { + return self.grpcManager.getGroupsByCourse(courseID: courseId) + } + + func createGroup(group: Group) -> EventLoopFuture { + return self.grpcManager.createGroup(group: group) + } + + func updateGroup(group: Group) { + self.grpcManager.updateGroup(group: group) + } + + func deleteGroup(userID: UInt64, groupID: UInt64, courseID: UInt64) { + grpcManager.deleteGroup(userID: userID, groupID: groupID, courseID: courseID) + } + + // MARK: Courses + func getCourse(courseId: UInt64) -> Course? { + return self.grpcManager.getCourse(courseID: courseId) } func getCourses() -> [Course]? { return grpcManager.getCourses() } - func getUsers() -> [User]? { - return grpcManager.getUsers() + func getCoursesByUser(userID: UInt64, userStatus: [Enrollment.UserStatus]) -> [Course]? { + return grpcManager.getCoursesByUser(userID: userID, userStatus: userStatus) + } + + func createCourse(course: Course) -> Course? { + return grpcManager.createCourse(course: course) + } + + func updateCourse(course: Course) { + grpcManager.updateCourse(course: course) + } + + func updateCourseVisibility(enrollment: Enrollment) { + grpcManager.updateCourseVisibility(enrollment: enrollment) + } + + // MARK: Assignments +// func getAssignments(courseID: UInt64) -> [Assignment]? { +// return grpcManager.getAssignments(courseID: courseID) +// } + + func updateAssignments(courseId: UInt64) -> Bool { + return self.grpcManager.updateAssignments(courseID: courseId) + } + + // MARK: Enrollments + func getEnrollmentsByUser(userID: UInt64, userStatus: [Enrollment.UserStatus]) -> [Enrollment]? { + return grpcManager.getEnrollmentsByUser(userID: userID, userStatus: userStatus) + } + + func getEnrollmentsByCourse(courseId: UInt64, ignoreGroupMembers: Bool?, withActivity: Bool?, userStatus: [Enrollment.UserStatus]) -> EventLoopFuture { + return self.grpcManager.getEnrollmentsByCourse(courseID: courseId, ignoreGroupMembers: ignoreGroupMembers, withActivity: withActivity, userStatus: userStatus) + } + + func createEnrollment(enrollment: Enrollment) { + grpcManager.createEnrollment(enrollment: enrollment) + } + + func updateEnrollment(enrollment: Enrollment) { + grpcManager.updateEnrollment(enrollment: enrollment) + } + + func updateEnrollments(courseID: UInt64) { + grpcManager.updateEnrollments(courseID: courseID) + } + + // MARK: Submissions + func getSubmissions(userID: UInt64?, groupID: UInt64?, courseID: UInt64) -> [Submission]? { + return grpcManager.getSubmissions(userID: userID, groupID: groupID, courseID: courseID) + } + + func getSubmissionsByCourse(courseId: UInt64, type: SubmissionsForCourseRequest.TypeEnum) -> EventLoopFuture { + return self.grpcManager.getSubmissionsByCourse(courseID: courseId, type: type) + } + + func updateSubmission(courseId: UInt64, submisssion: Submission) -> Bool { + return self.grpcManager.updateSubmission(submissionID: submisssion.id, courseID: courseId, score: submisssion.score, released: submisssion.released, status: submisssion.status) + } + + func updateSubmissions(assignmentID: UInt64, courseID: UInt64, score: UInt32, release: Bool, approve: Bool) { + grpcManager.updateSubmissions(courseID: courseID, assignmentID: assignmentID, scoreLimit: score, release: release, approve: approve) + } + + func rebuildSubmission(submissionID: UInt64, assignmentID: UInt64) -> Bool { + return grpcManager.rebuildSubmission(submissionID: submissionID, assignmentID: assignmentID) + } + + // MARK: Manual Grading + + + // MARK: Misc + func getProviders() -> [String]? { + return grpcManager.getProviders() + } + + func getOrganization(orgName: String) -> EventLoopFuture { + return grpcManager.getOrganization(orgName: orgName) + } + + func getRepositories(courseID: UInt64, repositoryTypes: [Repository.TypeEnum]) -> Repositories? { + return grpcManager.getRepositories(courseID: courseID, repositoryTypes: repositoryTypes) + } + + func isEmptyRepo(userID: UInt64, groupID: UInt64, courseID: UInt64) { + grpcManager.isEmptyRepo(userID: userID, groupID: groupID, courseID: courseID) } - func getCourse(courseId: UInt64) -> Course? { - return self.grpcManager.getCourse(courseID: courseId) + // TODO: clean up + + func getCoursesForCurrentUser(userID: UInt64, userStatus: [Enrollment.UserStatus]) -> [Course]? { + return grpcManager.getCoursesByUser(userID: userID, userStatus: userStatus) } func getAssignments(courseID: UInt64) -> [Assignment] { @@ -58,9 +169,6 @@ class ServerProvider: ProviderProtocol{ } return [] } - func updateAssignments(courseId: UInt64) -> Bool { - return self.grpcManager.updateAssignments(courseID: courseId) - } // ENROLLMENTS @@ -81,28 +189,6 @@ class ServerProvider: ProviderProtocol{ enrollment.status = status grpcManager.updateEnrollment(enrollment: enrollment) } - - func getEnrollmentsByCourse(courseId: UInt64, ignoreGroupMembers: Bool?, withActivity: Bool?, userStatus: [Enrollment.UserStatus]) -> EventLoopFuture{ - return self.grpcManager.getEnrollmentsByCourse(courseID: courseId, ignoreGroupMembers: ignoreGroupMembers, withActivity: withActivity, userStatus: userStatus) - } - - // GROUPS - func createGroup(group: Group) -> EventLoopFuture { - return self.grpcManager.createGroup(group: group) - } - - func updateGroup(group: Group) { - self.grpcManager.updateGroup(group: group) - } - - func getGroupByUserAndCourse(courseId: UInt64, groupID: UInt64?, userId: UInt64) -> Group? { - return self.grpcManager.getGroupByUserAndCourse(userID: userId, groupID: groupID, courseID: courseId) - } - - func getGroupsByCourse(courseId: UInt64) -> EventLoopFuture { - return self.grpcManager.getGroupsByCourse(courseID: courseId) - } - // SUBMISSIONS func getSubmissionsByUser(courseId: UInt64, userId: UInt64) -> [Submission] { @@ -116,18 +202,6 @@ class ServerProvider: ProviderProtocol{ //return self.grpcManager.getSubbmissionByGroup(courseID: courseId, groupID: groupId) } - func getSubmissionsByCourse(courseId: UInt64, type: SubmissionsForCourseRequest.TypeEnum) -> EventLoopFuture { - return self.grpcManager.getSubmissionsByCourse(courseID: courseId, type: type) - } - - func updateSubmission(courseId: UInt64, submisssion: Submission) -> Bool { - return self.grpcManager.updateSubmission(submissionID: submisssion.id, courseID: courseId, score: submisssion.score, released: submisssion.released, status: submisssion.status) - } - - func updateSubmissions(assignmentID: UInt64, courseID: UInt64, score: UInt32, release: Bool, approve: Bool) { - grpcManager.updateSubmissions(courseID: courseID, assignmentID: assignmentID, scoreLimit: score, release: release, approve: approve) - } - // MANUAL GRADING func loadCriteria(courseId: UInt64, assignmentId: UInt64) -> [GradingBenchmark] { @@ -150,23 +224,4 @@ class ServerProvider: ProviderProtocol{ func createNewCourse(course: Course) -> Course? { return grpcManager.createCourse(course: course) } - - func updateCourse(course: Course) { - grpcManager.updateCourse(course: course) - } - - // NOT IMPLEMENTED - - func getProviders() -> [String] { - fatalError("Not implemented") - } - - func rebuildSubmission(assignmentId: UInt64, submissionId: UInt64) -> Submission? { - fatalError("Not implemented") - } - - func getRepositories(courseId: UInt64, types: [Repository.Type]) { - fatalError("Not implemented") - } - } From 69a78b484d0c81d38d2da526ad96e9807e5de4b2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Kristian=20Teisrud?= Date: Mon, 28 Jun 2021 19:54:04 +0200 Subject: [PATCH 04/17] removed duplicate methods of submissions --- Quickfeed/Providers/ProviderProtocol.swift | 10 +--- Quickfeed/Providers/ServerProvider.swift | 57 ++------------------- Quickfeed/ViewModels/StudentViewModel.swift | 10 ++-- Quickfeed/ViewModels/TeacherViewModel.swift | 11 ++-- Quickfeed/ViewModels/UserViewModel.swift | 10 ++-- 5 files changed, 23 insertions(+), 75 deletions(-) diff --git a/Quickfeed/Providers/ProviderProtocol.swift b/Quickfeed/Providers/ProviderProtocol.swift index 68e661c..f28ccb0 100644 --- a/Quickfeed/Providers/ProviderProtocol.swift +++ b/Quickfeed/Providers/ProviderProtocol.swift @@ -33,7 +33,7 @@ protocol ProviderProtocol{ func updateCourseVisibility(enrollment: Enrollment) // MARK: Assignments - //func getAssignments(courseID: UInt64) -> [Assignment]? + func getAssignments(courseID: UInt64) -> [Assignment]? func updateAssignments(courseId: UInt64) -> Bool // MARK: Enrollments @@ -59,16 +59,8 @@ protocol ProviderProtocol{ func isEmptyRepo(userID: UInt64, groupID: UInt64, courseID: UInt64) // TODO: clean - func getCoursesForCurrentUser(userID: UInt64, userStatus: [Enrollment.UserStatus]) -> [Course]? - func getAssignments(courseID: UInt64) -> [Assignment] - func createEnrollment(courseID: UInt64, userID: UInt64) - func getEnrollmentsForUser(userId: UInt64) -> [Enrollment] - func updateEnrollment(enrollment: Enrollment, status: Enrollment.UserStatus) - func getSubmissionsByUser(courseId: UInt64, userId: UInt64) -> [Submission] - func getSubmissionsByGroub(courseId: UInt64, groupId: UInt64) -> [Submission] func loadCriteria(courseId: UInt64, assignmentId: UInt64) -> [GradingBenchmark] func createReview(courseId: UInt64, review: Review) -> Review? func updateReview(courseId: UInt64, review: Review) func getReviewers(submissionId: UInt64, courseId: UInt64) -> Reviewers? - func createNewCourse(course: Course) -> Course? } diff --git a/Quickfeed/Providers/ServerProvider.swift b/Quickfeed/Providers/ServerProvider.swift index 7d417b3..b7b353f 100644 --- a/Quickfeed/Providers/ServerProvider.swift +++ b/Quickfeed/Providers/ServerProvider.swift @@ -86,9 +86,9 @@ class ServerProvider: ProviderProtocol{ } // MARK: Assignments -// func getAssignments(courseID: UInt64) -> [Assignment]? { -// return grpcManager.getAssignments(courseID: courseID) -// } + func getAssignments(courseID: UInt64) -> [Assignment]? { + return grpcManager.getAssignments(courseID: courseID) + } func updateAssignments(courseId: UInt64) -> Bool { return self.grpcManager.updateAssignments(courseID: courseId) @@ -157,52 +157,6 @@ class ServerProvider: ProviderProtocol{ } // TODO: clean up - - func getCoursesForCurrentUser(userID: UInt64, userStatus: [Enrollment.UserStatus]) -> [Course]? { - return grpcManager.getCoursesByUser(userID: userID, userStatus: userStatus) - } - - func getAssignments(courseID: UInt64) -> [Assignment] { - let assignments = self.grpcManager.getAssignments(courseID: courseID) - if assignments != nil { - return assignments! - } - return [] - } - - // ENROLLMENTS - - func createEnrollment(courseID: UInt64, userID: UInt64) { - var enrollment = Enrollment() - enrollment.courseID = courseID - enrollment.userID = userID - - self.grpcManager.createEnrollment(enrollment: enrollment) - } - - func getEnrollmentsForUser(userId: UInt64) -> [Enrollment] { - return self.grpcManager.getEnrollmentsByUser(userID: userId, userStatus: [Enrollment.UserStatus.teacher, Enrollment.UserStatus.student, Enrollment.UserStatus.pending])! - } - - func updateEnrollment(enrollment: Enrollment, status: Enrollment.UserStatus) { - var enrollment = enrollment - enrollment.status = status - grpcManager.updateEnrollment(enrollment: enrollment) - } - - // SUBMISSIONS - func getSubmissionsByUser(courseId: UInt64, userId: UInt64) -> [Submission] { - /*let submissions = self.grpcManager.getSubmissionsForEnrollment(courseId: courseId, userId: userId) - return submissions*/ - return self.grpcManager.getSubmissions(userID: userId, groupID: nil, courseID: courseId)! - } - - func getSubmissionsByGroub(courseId: UInt64, groupId: UInt64) -> [Submission] { - return self.grpcManager.getSubmissions(userID: nil, groupID: groupId, courseID: courseId)! - //return self.grpcManager.getSubbmissionByGroup(courseID: courseId, groupID: groupId) - } - - // MANUAL GRADING func loadCriteria(courseId: UInt64, assignmentId: UInt64) -> [GradingBenchmark] { return self.grpcManager.loadCriteria(courseID: courseId, assignmentID: assignmentId)! @@ -219,9 +173,4 @@ class ServerProvider: ProviderProtocol{ func getReviewers(submissionId: UInt64, courseId: UInt64) -> Reviewers?{ return self.grpcManager.getReviewers(submissionID: submissionId, courseID: courseId) } - - // Courses - func createNewCourse(course: Course) -> Course? { - return grpcManager.createCourse(course: course) - } } diff --git a/Quickfeed/ViewModels/StudentViewModel.swift b/Quickfeed/ViewModels/StudentViewModel.swift index e5ad732..fa05d6c 100644 --- a/Quickfeed/ViewModels/StudentViewModel.swift +++ b/Quickfeed/ViewModels/StudentViewModel.swift @@ -54,7 +54,7 @@ class StudentViewModel: UserViewModelProtocol{ } func getEnrollmentForCurrentCourse() -> Enrollment?{ - let enrollments = provider.getEnrollmentsForUser(userId: user.id) + let enrollments = provider.getEnrollmentsByUser(userID: self.user.id, userStatus: [Enrollment.UserStatus.teacher, Enrollment.UserStatus.student, Enrollment.UserStatus.pending])! for element in enrollments{ if element.course.id == course!.id{ return element @@ -79,7 +79,7 @@ class StudentViewModel: UserViewModelProtocol{ } func getAssignments(){ - self.assignments = provider.getAssignments(courseID: course!.id) + self.assignments = provider.getAssignments(courseID: course!.id)! } func hasGroupAssignments() -> Bool{ @@ -109,15 +109,15 @@ class StudentViewModel: UserViewModelProtocol{ } func getSubmissions(){ - var submissions = provider.getSubmissionsByUser(courseId: course!.id, userId: user.id) + var submissions = provider.getSubmissions(userID: user.id, groupID: nil, courseID: course!.id)! if self.group != nil{ - submissions.append(contentsOf: provider.getSubmissionsByGroub(courseId: course!.id, groupId: group!.id)) + submissions.append(contentsOf: provider.getSubmissions(userID: nil, groupID: group!.id, courseID: course!.id)!) } self.submissions = submissions } func getSlipdays() -> UInt32? { - let enrollments = provider.getEnrollmentsForUser(userId: user.id) + let enrollments = provider.getEnrollmentsByUser(userID: self.user.id, userStatus: [Enrollment.UserStatus.teacher, Enrollment.UserStatus.student, Enrollment.UserStatus.pending])! for element in enrollments{ if element.courseID == course!.id{ return element.slipDaysRemaining diff --git a/Quickfeed/ViewModels/TeacherViewModel.swift b/Quickfeed/ViewModels/TeacherViewModel.swift index 1d14787..0bc91ff 100644 --- a/Quickfeed/ViewModels/TeacherViewModel.swift +++ b/Quickfeed/ViewModels/TeacherViewModel.swift @@ -99,7 +99,7 @@ class TeacherViewModel: UserViewModelProtocol{ } func loadAssignments(){ - self.assignments = self.provider.getAssignments(courseID: self.currentCourse.id) + self.assignments = self.provider.getAssignments(courseID: self.currentCourse.id)! self.loadManuallyGradedAssignments(courseId: self.currentCourse.id) } @@ -118,7 +118,7 @@ class TeacherViewModel: UserViewModelProtocol{ } func getSubmissionsByUser(courseId: UInt64, userId: UInt64) -> [Submission]{ - return self.provider.getSubmissionsByUser(courseId: courseId, userId: userId) + return self.provider.getSubmissions(userID: userId, groupID: nil, courseID: courseId)! } func getUserName(userId: UInt64) -> String{ @@ -134,7 +134,10 @@ class TeacherViewModel: UserViewModelProtocol{ } func updateEnrollment(enrollment: Enrollment, status: Enrollment.UserStatus){ - self.provider.updateEnrollment(enrollment: enrollment, status: status) + var enrollment = enrollment + enrollment.status = status + + self.provider.updateEnrollment(enrollment: enrollment) } // MANUAL GRADING @@ -148,7 +151,7 @@ class TeacherViewModel: UserViewModelProtocol{ } func getSubmissionByAssignment(userId: UInt64, assigmentID: UInt64) -> Submission{ - let submissions = provider.getSubmissionsByUser(courseId: self.currentCourse.id, userId: userId) + let submissions = provider.getSubmissions(userID: userId, groupID: nil, courseID: self.currentCourse.id)! return submissions.first(where: {$0.assignmentID == assigmentID})! } diff --git a/Quickfeed/ViewModels/UserViewModel.swift b/Quickfeed/ViewModels/UserViewModel.swift index b4b0911..a42a772 100644 --- a/Quickfeed/ViewModels/UserViewModel.swift +++ b/Quickfeed/ViewModels/UserViewModel.swift @@ -58,7 +58,7 @@ class UserViewModel: UserViewModelProtocol { } func getAllCoursesForCurrentUser() { - self.courses = self.provider.getCoursesForCurrentUser(userID: self.user!.id, userStatus: [Enrollment.UserStatus.student, Enrollment.UserStatus.teacher]) + self.courses = self.provider.getCoursesByUser(userID: self.user!.id, userStatus: [Enrollment.UserStatus.student, Enrollment.UserStatus.teacher]) } func isTeacherForCourse(courseId: UInt64) -> Bool? { @@ -82,7 +82,11 @@ class UserViewModel: UserViewModelProtocol { // Enrollment func createEnrollment(courseID: UInt64) { - self.provider.createEnrollment(courseID: courseID, userID: self.user!.id) + var enrollment = Enrollment() + enrollment.courseID = courseID + enrollment.userID = self.user!.id + + self.provider.createEnrollment(enrollment: enrollment) self.getEnrollments() } @@ -98,7 +102,7 @@ class UserViewModel: UserViewModelProtocol { } func getEnrollments() { - self.enrollments = self.provider.getEnrollmentsForUser(userId: self.user!.id) + self.enrollments = self.provider.getEnrollmentsByUser(userID: self.user!.id, userStatus: [Enrollment.UserStatus.teacher, Enrollment.UserStatus.student, Enrollment.UserStatus.pending])! if self.enrollments.count != 0 { self.sortEnrollmentsByCode() } From 94f99c88c468d2dfd5641f34acbf61119606e825 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Gj=C3=B8lga?= Date: Tue, 29 Jun 2021 12:14:58 +0200 Subject: [PATCH 05/17] minor adjustments --- Quickfeed/Managers/GRPCManager.swift | 2 +- Quickfeed/Views/AuthWebWiew.swift | 43 ++++++++++++----------- Quickfeed/Views/Helpers/GitHubLogIn.swift | 8 +---- Quickfeed/Views/LogIn.swift | 17 +++++++-- 4 files changed, 39 insertions(+), 31 deletions(-) diff --git a/Quickfeed/Managers/GRPCManager.swift b/Quickfeed/Managers/GRPCManager.swift index b7df332..818cb69 100644 --- a/Quickfeed/Managers/GRPCManager.swift +++ b/Quickfeed/Managers/GRPCManager.swift @@ -18,7 +18,7 @@ class GRPCManager { var defaultOptions: CallOptions? private init(){ - let hostname = "localhost" + let hostname = "uis.itest.run" let port = 9090 let configuration = ClientConnection.Configuration( diff --git a/Quickfeed/Views/AuthWebWiew.swift b/Quickfeed/Views/AuthWebWiew.swift index aafad0c..e8790f6 100644 --- a/Quickfeed/Views/AuthWebWiew.swift +++ b/Quickfeed/Views/AuthWebWiew.swift @@ -12,22 +12,36 @@ import Foundation import AppKit struct AuthWebView: View { - @ObservedObject var model: WebViewModel + @ObservedObject var viewModel: UserViewModel + @ObservedObject var webViewModel: WebViewModel - init(mesgURL: String) { - //Assign the url to the model and initialise the model - self.model = WebViewModel(link: mesgURL) + init(viewModel: UserViewModel, mesgURL: String) { + self.viewModel = viewModel + self.webViewModel = WebViewModel(link: mesgURL) } var body: some View { - //Create the WebView with the model - SwiftUIWebView(viewModel: model) - .onChange(of: model.pageTitle, perform: { value in - print(model.siteData) + SwiftUIWebView(viewModel: webViewModel) + .onChange(of: webViewModel.pageTitle, perform: { value in + print(webViewModel.siteData) }) } } + +class WebViewModel: ObservableObject { + @Published var siteData: [String : Any] + @Published var link: String + @Published var didFinishLoading: Bool = false + @Published var pageTitle: String + + init (link: String) { + self.link = link + self.pageTitle = "" + self.siteData = [:] + } +} + struct SwiftUIWebView: NSViewRepresentable { public typealias NSViewType = WKWebView @@ -83,18 +97,7 @@ struct SwiftUIWebView: NSViewRepresentable { } -class WebViewModel: ObservableObject { - @Published var siteData: [String : Any] - @Published var link: String - @Published var didFinishLoading: Bool = false - @Published var pageTitle: String - - init (link: String) { - self.link = link - self.pageTitle = "" - self.siteData = [:] - } -} + extension WKWebView { diff --git a/Quickfeed/Views/Helpers/GitHubLogIn.swift b/Quickfeed/Views/Helpers/GitHubLogIn.swift index d171a67..1071939 100644 --- a/Quickfeed/Views/Helpers/GitHubLogIn.swift +++ b/Quickfeed/Views/Helpers/GitHubLogIn.swift @@ -5,7 +5,7 @@ import SwiftUI -struct GitHubLogIn: View { +struct GitHubLogInButton: View { @ObservedObject var viewModel: UserViewModel @Binding var login: Bool @@ -23,11 +23,5 @@ struct GitHubLogIn: View { .foregroundColor(.white) .cornerRadius(10.0) .contentShape(Rectangle()) - .onTapGesture { - GitHubManager(viewModel: viewModel).logInWithGitHub() - if viewModel.user != nil{ - login = !login - } - } } } diff --git a/Quickfeed/Views/LogIn.swift b/Quickfeed/Views/LogIn.swift index b39cd74..ec16da5 100644 --- a/Quickfeed/Views/LogIn.swift +++ b/Quickfeed/Views/LogIn.swift @@ -8,6 +8,8 @@ import SwiftUI struct LogIn: View { @ObservedObject var viewModel: UserViewModel @Binding var login: Bool + @State var signingIn: Bool = false + @State var hostName: String = "https://uis.itest.run/app/login/login/github" var body: some View { VStack{ @@ -25,9 +27,18 @@ struct LogIn: View { } } .padding(.horizontal) - GitHubLogIn(viewModel: viewModel, login: $login) - AuthWebView(mesgURL: "https://uis.itest.run") + TextField("Hostname", text: $hostName) + GitHubLogInButton(viewModel: viewModel, login: $login) + .onTapGesture { + signingIn = true + } + .sheet(isPresented: $signingIn, content: { + AuthWebView(viewModel: viewModel, mesgURL: self.hostName) + .frame(width: 600, height: 600) + }) + + } - .frame(width: 500, height: 500) + .frame(width: 300, height: 300) } } From 1deaca8fb869f4fde258597cf3ad3115e9d6ecb2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Gj=C3=B8lga?= Date: Tue, 29 Jun 2021 15:10:00 +0200 Subject: [PATCH 06/17] solution that seems to obtain the sessionid --- Quickfeed/Views/AuthWebWiew.swift | 34 +++++++++++++++++++++++-------- Quickfeed/Views/LogIn.swift | 8 +++++--- 2 files changed, 30 insertions(+), 12 deletions(-) diff --git a/Quickfeed/Views/AuthWebWiew.swift b/Quickfeed/Views/AuthWebWiew.swift index e8790f6..4cf0d21 100644 --- a/Quickfeed/Views/AuthWebWiew.swift +++ b/Quickfeed/Views/AuthWebWiew.swift @@ -14,16 +14,19 @@ import AppKit struct AuthWebView: View { @ObservedObject var viewModel: UserViewModel @ObservedObject var webViewModel: WebViewModel + @Binding var signingIn: Bool - init(viewModel: UserViewModel, mesgURL: String) { + init(viewModel: UserViewModel, mesgURL: String, signingIn: Binding) { self.viewModel = viewModel self.webViewModel = WebViewModel(link: mesgURL) + self._signingIn = signingIn } var body: some View { SwiftUIWebView(viewModel: webViewModel) - .onChange(of: webViewModel.pageTitle, perform: { value in - print(webViewModel.siteData) + .onChange(of: webViewModel.link, perform: { value in + print(webViewModel.pageTitle) + print(webViewModel.siteData["session"].unsafelyUnwrapped) }) } } @@ -41,7 +44,21 @@ class WebViewModel: ObservableObject { self.siteData = [:] } } - +/* +class Cookie{ + let Created: Int + let Domain: String + let Expires: Date + let HttpOnly: Bool + let Name: String + let Path: String + let Secure: Bool + let Value: String + init(opt: AnyObject) { + self.Created = opt.getAttribute("Created") + } +} +*/ struct SwiftUIWebView: NSViewRepresentable { public typealias NSViewType = WKWebView @@ -80,7 +97,6 @@ struct SwiftUIWebView: NSViewRepresentable { self.viewModel.didFinishLoading = true web.getCookies(for: "uis.itest.run"){data in self.viewModel.siteData = data - print(data) } @@ -103,16 +119,16 @@ extension WKWebView { private var httpCookieStore: WKHTTPCookieStore { return WKWebsiteDataStore.default().httpCookieStore } - func getCookies(for domain: String? = nil, completion: @escaping ([String : Any])->()) { - var cookieDict = [String : AnyObject]() + func getCookies(for domain: String? = nil, completion: @escaping ([String : String])->()) { + var cookieDict = [String : String]() httpCookieStore.getAllCookies { cookies in for cookie in cookies { if let domain = domain { if cookie.domain.contains(domain) { - cookieDict[cookie.name] = cookie.properties as AnyObject? + cookieDict[cookie.name] = cookie.value as String? } } else { - cookieDict[cookie.name] = cookie.properties as AnyObject? + cookieDict[cookie.name] = cookie.value as String? } } completion(cookieDict) diff --git a/Quickfeed/Views/LogIn.swift b/Quickfeed/Views/LogIn.swift index ec16da5..4e0286c 100644 --- a/Quickfeed/Views/LogIn.swift +++ b/Quickfeed/Views/LogIn.swift @@ -9,7 +9,7 @@ struct LogIn: View { @ObservedObject var viewModel: UserViewModel @Binding var login: Bool @State var signingIn: Bool = false - @State var hostName: String = "https://uis.itest.run/app/login/login/github" + @State var authUrl: String = "https://uis.itest.run/app/login/login/github" var body: some View { VStack{ @@ -27,13 +27,15 @@ struct LogIn: View { } } .padding(.horizontal) - TextField("Hostname", text: $hostName) + TextField("Hostname", text: $authUrl) GitHubLogInButton(viewModel: viewModel, login: $login) .onTapGesture { signingIn = true } .sheet(isPresented: $signingIn, content: { - AuthWebView(viewModel: viewModel, mesgURL: self.hostName) + AuthWebView(viewModel: viewModel, + mesgURL: authUrl, + signingIn: $signingIn) .frame(width: 600, height: 600) }) From c39b47c5214d1fc2e8f6d72f3585a25a6b9db15c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bj=C3=B8rn=20Kristian=20Teisrud?= Date: Tue, 29 Jun 2021 15:21:02 +0200 Subject: [PATCH 07/17] cleaned up manual grading section of serverprovider --- Quickfeed/Providers/ProviderProtocol.swift | 30 ++++--- Quickfeed/Providers/ServerProvider.swift | 87 +++++++++++++-------- Quickfeed/ViewModels/StudentViewModel.swift | 4 +- Quickfeed/ViewModels/TeacherViewModel.swift | 16 ++-- Quickfeed/ViewModels/UserViewModel.swift | 2 +- 5 files changed, 82 insertions(+), 57 deletions(-) diff --git a/Quickfeed/Providers/ProviderProtocol.swift b/Quickfeed/Providers/ProviderProtocol.swift index f28ccb0..38420e1 100644 --- a/Quickfeed/Providers/ProviderProtocol.swift +++ b/Quickfeed/Providers/ProviderProtocol.swift @@ -18,14 +18,14 @@ protocol ProviderProtocol{ // MARK: Groups func getGroup(groupID: UInt64) -> Group? - func getGroupByUserAndCourse(courseId: UInt64, groupID: UInt64?, userId: UInt64) -> Group? - func getGroupsByCourse(courseId: UInt64) -> EventLoopFuture + func getGroupByUserAndCourse(courseID: UInt64, groupID: UInt64?, userID: UInt64) -> Group? + func getGroupsByCourse(courseID: UInt64) -> EventLoopFuture func createGroup(group: Group) -> EventLoopFuture func updateGroup(group: Group) func deleteGroup(userID: UInt64, groupID: UInt64, courseID: UInt64) // MARK: Courses - func getCourse(courseId: UInt64) -> Course? + func getCourse(courseID: UInt64) -> Course? func getCourses() -> [Course]? func getCoursesByUser(userID: UInt64, userStatus: [Enrollment.UserStatus]) -> [Course]? func createCourse(course: Course) -> Course? @@ -34,33 +34,37 @@ protocol ProviderProtocol{ // MARK: Assignments func getAssignments(courseID: UInt64) -> [Assignment]? - func updateAssignments(courseId: UInt64) -> Bool + func updateAssignments(courseID: UInt64) -> Bool // MARK: Enrollments func getEnrollmentsByUser(userID: UInt64, userStatus: [Enrollment.UserStatus]) -> [Enrollment]? - func getEnrollmentsByCourse(courseId: UInt64, ignoreGroupMembers: Bool?, withActivity: Bool?, userStatus: [Enrollment.UserStatus]) -> EventLoopFuture + func getEnrollmentsByCourse(courseID: UInt64, ignoreGroupMembers: Bool?, withActivity: Bool?, userStatus: [Enrollment.UserStatus]) -> EventLoopFuture func createEnrollment(enrollment: Enrollment) func updateEnrollment(enrollment: Enrollment) func updateEnrollments(courseID: UInt64) // MARK: Submissions func getSubmissions(userID: UInt64?, groupID: UInt64?, courseID: UInt64) -> [Submission]? - func getSubmissionsByCourse(courseId: UInt64, type: SubmissionsForCourseRequest.TypeEnum) -> EventLoopFuture - func updateSubmission(courseId: UInt64, submisssion: Submission) -> Bool + func getSubmissionsByCourse(courseID: UInt64, type: SubmissionsForCourseRequest.TypeEnum) -> EventLoopFuture + func updateSubmission(courseID: UInt64, submisssion: Submission) -> Bool func updateSubmissions(assignmentID: UInt64, courseID: UInt64, score: UInt32, release: Bool, approve: Bool) func rebuildSubmission(submissionID: UInt64, assignmentID: UInt64) -> Bool // MARK: Manual Grading + func createBenchmark(gradingBenchmark: GradingBenchmark) -> GradingBenchmark? + func updateBenchmark(gradingBenchmark: GradingBenchmark) + func deleteBenchmark(gradingBenchmark: GradingBenchmark) + func createCriterion(gradingCriterion: GradingCriterion) -> GradingCriterion? + func updateCriterion(gradingCriterion: GradingCriterion) + func deleteCriterion(gradingCriterion: GradingCriterion) + func createReview(courseID: UInt64, review: Review) -> Review? + func updateReview(courseID: UInt64, review: Review) + func getReviewers(submissionID: UInt64, courseID: UInt64) -> Reviewers? + func loadCriteria(courseID: UInt64, assignmentID: UInt64) -> [GradingBenchmark] // MARK: Misc func getProviders() -> [String]? func getOrganization(orgName: String) -> EventLoopFuture func getRepositories(courseID: UInt64, repositoryTypes: [Repository.TypeEnum]) -> Repositories? func isEmptyRepo(userID: UInt64, groupID: UInt64, courseID: UInt64) - - // TODO: clean - func loadCriteria(courseId: UInt64, assignmentId: UInt64) -> [GradingBenchmark] - func createReview(courseId: UInt64, review: Review) -> Review? - func updateReview(courseId: UInt64, review: Review) - func getReviewers(submissionId: UInt64, courseId: UInt64) -> Reviewers? } diff --git a/Quickfeed/Providers/ServerProvider.swift b/Quickfeed/Providers/ServerProvider.swift index b7b353f..f2fa80b 100644 --- a/Quickfeed/Providers/ServerProvider.swift +++ b/Quickfeed/Providers/ServerProvider.swift @@ -8,6 +8,7 @@ import NIO class ServerProvider: ProviderProtocol{ static let shared: ServerProvider = ServerProvider() + var grpcManager: GRPCManager = GRPCManager.shared private init(){ @@ -15,7 +16,7 @@ class ServerProvider: ProviderProtocol{ } // MARK: Users - func setUser(userID: UInt64){ + func setUser(userID: UInt64) { grpcManager.setUser(userID: userID) } @@ -40,12 +41,12 @@ class ServerProvider: ProviderProtocol{ return grpcManager.getGroup(groupID: groupID) } - func getGroupByUserAndCourse(courseId: UInt64, groupID: UInt64?, userId: UInt64) -> Group? { - return self.grpcManager.getGroupByUserAndCourse(userID: userId, groupID: groupID, courseID: courseId) + func getGroupByUserAndCourse(courseID: UInt64, groupID: UInt64?, userID: UInt64) -> Group? { + return self.grpcManager.getGroupByUserAndCourse(userID: userID, groupID: groupID, courseID: courseID) } - func getGroupsByCourse(courseId: UInt64) -> EventLoopFuture { - return self.grpcManager.getGroupsByCourse(courseID: courseId) + func getGroupsByCourse(courseID: UInt64) -> EventLoopFuture { + return self.grpcManager.getGroupsByCourse(courseID: courseID) } func createGroup(group: Group) -> EventLoopFuture { @@ -61,8 +62,8 @@ class ServerProvider: ProviderProtocol{ } // MARK: Courses - func getCourse(courseId: UInt64) -> Course? { - return self.grpcManager.getCourse(courseID: courseId) + func getCourse(courseID: UInt64) -> Course? { + return self.grpcManager.getCourse(courseID: courseID) } func getCourses() -> [Course]? { @@ -90,8 +91,8 @@ class ServerProvider: ProviderProtocol{ return grpcManager.getAssignments(courseID: courseID) } - func updateAssignments(courseId: UInt64) -> Bool { - return self.grpcManager.updateAssignments(courseID: courseId) + func updateAssignments(courseID: UInt64) -> Bool { + return self.grpcManager.updateAssignments(courseID: courseID) } // MARK: Enrollments @@ -99,8 +100,8 @@ class ServerProvider: ProviderProtocol{ return grpcManager.getEnrollmentsByUser(userID: userID, userStatus: userStatus) } - func getEnrollmentsByCourse(courseId: UInt64, ignoreGroupMembers: Bool?, withActivity: Bool?, userStatus: [Enrollment.UserStatus]) -> EventLoopFuture { - return self.grpcManager.getEnrollmentsByCourse(courseID: courseId, ignoreGroupMembers: ignoreGroupMembers, withActivity: withActivity, userStatus: userStatus) + func getEnrollmentsByCourse(courseID: UInt64, ignoreGroupMembers: Bool?, withActivity: Bool?, userStatus: [Enrollment.UserStatus]) -> EventLoopFuture { + return self.grpcManager.getEnrollmentsByCourse(courseID: courseID, ignoreGroupMembers: ignoreGroupMembers, withActivity: withActivity, userStatus: userStatus) } func createEnrollment(enrollment: Enrollment) { @@ -120,12 +121,12 @@ class ServerProvider: ProviderProtocol{ return grpcManager.getSubmissions(userID: userID, groupID: groupID, courseID: courseID) } - func getSubmissionsByCourse(courseId: UInt64, type: SubmissionsForCourseRequest.TypeEnum) -> EventLoopFuture { - return self.grpcManager.getSubmissionsByCourse(courseID: courseId, type: type) + func getSubmissionsByCourse(courseID: UInt64, type: SubmissionsForCourseRequest.TypeEnum) -> EventLoopFuture { + return self.grpcManager.getSubmissionsByCourse(courseID: courseID, type: type) } - func updateSubmission(courseId: UInt64, submisssion: Submission) -> Bool { - return self.grpcManager.updateSubmission(submissionID: submisssion.id, courseID: courseId, score: submisssion.score, released: submisssion.released, status: submisssion.status) + func updateSubmission(courseID: UInt64, submisssion: Submission) -> Bool { + return self.grpcManager.updateSubmission(submissionID: submisssion.id, courseID: courseID, score: submisssion.score, released: submisssion.released, status: submisssion.status) } func updateSubmissions(assignmentID: UInt64, courseID: UInt64, score: UInt32, release: Bool, approve: Bool) { @@ -137,7 +138,45 @@ class ServerProvider: ProviderProtocol{ } // MARK: Manual Grading + func createBenchmark(gradingBenchmark: GradingBenchmark) -> GradingBenchmark? { + return grpcManager.createBenchmark(gradingBenchmark: gradingBenchmark) + } + + func updateBenchmark(gradingBenchmark: GradingBenchmark) { + grpcManager.updateBenchmark(gradingBenchmark: gradingBenchmark) + } + + func deleteBenchmark(gradingBenchmark: GradingBenchmark) { + grpcManager.deleteBenchmark(gradingBenchmark: gradingBenchmark) + } + + func createCriterion(gradingCriterion: GradingCriterion) -> GradingCriterion? { + return grpcManager.createCriterion(gradingCriterion: gradingCriterion) + } + + func updateCriterion(gradingCriterion: GradingCriterion) { + grpcManager.updateCriterion(gradingCriterion: gradingCriterion) + } + func deleteCriterion(gradingCriterion: GradingCriterion) { + grpcManager.deleteCriterion(gradingCriterion: gradingCriterion) + } + + func createReview(courseID: UInt64, review: Review) -> Review?{ + return self.grpcManager.createReview(courseID: courseID, review: review) + } + + func updateReview(courseID: UInt64, review: Review){ + return self.grpcManager.updateReview(courseID: courseID, review: review) + } + + func getReviewers(submissionID: UInt64, courseID: UInt64) -> Reviewers?{ + return self.grpcManager.getReviewers(submissionID: submissionID, courseID: courseID) + } + + func loadCriteria(courseID: UInt64, assignmentID: UInt64) -> [GradingBenchmark] { + return self.grpcManager.loadCriteria(courseID: courseID, assignmentID: assignmentID)! + } // MARK: Misc func getProviders() -> [String]? { @@ -155,22 +194,4 @@ class ServerProvider: ProviderProtocol{ func isEmptyRepo(userID: UInt64, groupID: UInt64, courseID: UInt64) { grpcManager.isEmptyRepo(userID: userID, groupID: groupID, courseID: courseID) } - - // TODO: clean up - // MANUAL GRADING - func loadCriteria(courseId: UInt64, assignmentId: UInt64) -> [GradingBenchmark] { - return self.grpcManager.loadCriteria(courseID: courseId, assignmentID: assignmentId)! - } - - func createReview(courseId: UInt64, review: Review) -> Review?{ - return self.grpcManager.createReview(courseID: courseId, review: review) - } - - func updateReview(courseId: UInt64, review: Review){ - return self.grpcManager.updateReview(courseID: courseId, review: review) - } - - func getReviewers(submissionId: UInt64, courseId: UInt64) -> Reviewers?{ - return self.grpcManager.getReviewers(submissionID: submissionId, courseID: courseId) - } } diff --git a/Quickfeed/ViewModels/StudentViewModel.swift b/Quickfeed/ViewModels/StudentViewModel.swift index fa05d6c..a721094 100644 --- a/Quickfeed/ViewModels/StudentViewModel.swift +++ b/Quickfeed/ViewModels/StudentViewModel.swift @@ -22,7 +22,7 @@ class StudentViewModel: UserViewModelProtocol{ func setCourse(course: Course){ self.course = course - self.group = provider.getGroupByUserAndCourse(courseId: course.id, groupID: nil, userId: user.id) + self.group = provider.getGroupByUserAndCourse(courseID: course.id, groupID: nil, userID: user.id) } func createGroup(name: String, enrollments: [Enrollment]) { @@ -64,7 +64,7 @@ class StudentViewModel: UserViewModelProtocol{ } func getEnrollmentsByCourse() { - let response = self.provider.getEnrollmentsByCourse(courseId: self.course!.id, ignoreGroupMembers: true, withActivity: nil, userStatus: [Enrollment.UserStatus.student]) + let response = self.provider.getEnrollmentsByCourse(courseID: self.course!.id, ignoreGroupMembers: true, withActivity: nil, userStatus: [Enrollment.UserStatus.student]) _ = response.always {(response: Result) in switch response { case .success(let response): diff --git a/Quickfeed/ViewModels/TeacherViewModel.swift b/Quickfeed/ViewModels/TeacherViewModel.swift index 0bc91ff..5543115 100644 --- a/Quickfeed/ViewModels/TeacherViewModel.swift +++ b/Quickfeed/ViewModels/TeacherViewModel.swift @@ -37,7 +37,7 @@ class TeacherViewModel: UserViewModelProtocol{ } func loadGroups(){ - let response = self.provider.getGroupsByCourse(courseId: self.currentCourse.id) + let response = self.provider.getGroupsByCourse(courseID: self.currentCourse.id) _ = response.always {(response: Result) in switch response { case .success(let response): @@ -69,7 +69,7 @@ class TeacherViewModel: UserViewModelProtocol{ } func loadEnrollmentLinks(){ - let response = self.provider.getSubmissionsByCourse(courseId: self.currentCourse.id, type: SubmissionsForCourseRequest.TypeEnum.all) + let response = self.provider.getSubmissionsByCourse(courseID: self.currentCourse.id, type: SubmissionsForCourseRequest.TypeEnum.all) _ = response.always {(response: Result) in switch response { case .success(let response): @@ -84,7 +84,7 @@ class TeacherViewModel: UserViewModelProtocol{ } func loadEnrollments(){ - let response = self.provider.getEnrollmentsByCourse(courseId: self.currentCourse.id, ignoreGroupMembers: nil, withActivity: nil, userStatus: [Enrollment.UserStatus.student, Enrollment.UserStatus.teacher, Enrollment.UserStatus.pending]) + let response = self.provider.getEnrollmentsByCourse(courseID: self.currentCourse.id, ignoreGroupMembers: nil, withActivity: nil, userStatus: [Enrollment.UserStatus.student, Enrollment.UserStatus.teacher, Enrollment.UserStatus.pending]) _ = response.always {(response: Result) in switch response { case .success(let response): @@ -104,11 +104,11 @@ class TeacherViewModel: UserViewModelProtocol{ } func updateAssignments() -> Bool{ - return self.provider.updateAssignments(courseId: self.currentCourse.id) + return self.provider.updateAssignments(courseID: self.currentCourse.id) } func updateSubmission(submission: Submission) -> Bool{ - return provider.updateSubmission(courseId: self.currentCourse.id, submisssion: submission) + return provider.updateSubmission(courseID: self.currentCourse.id, submisssion: submission) } func loadManuallyGradedAssignments(courseId: UInt64){ @@ -142,12 +142,12 @@ class TeacherViewModel: UserViewModelProtocol{ // MANUAL GRADING func createReview(review: Review) -> Review?{ - return self.provider.createReview(courseId: self.currentCourse.id, review: review) + return self.provider.createReview(courseID: self.currentCourse.id, review: review) } func updateReview(review: Review){ - self.provider.updateReview(courseId: self.currentCourse.id, review: review) + self.provider.updateReview(courseID: self.currentCourse.id, review: review) } func getSubmissionByAssignment(userId: UInt64, assigmentID: UInt64) -> Submission{ @@ -156,7 +156,7 @@ class TeacherViewModel: UserViewModelProtocol{ } func loadCriteria(assignmentId: UInt64) -> [GradingBenchmark]{ - return self.provider.loadCriteria(courseId: currentCourse.id, assignmentId: assignmentId) + return self.provider.loadCriteria(courseID: currentCourse.id, assignmentID: assignmentId) } func reset() { diff --git a/Quickfeed/ViewModels/UserViewModel.swift b/Quickfeed/ViewModels/UserViewModel.swift index a42a772..b0a1f46 100644 --- a/Quickfeed/ViewModels/UserViewModel.swift +++ b/Quickfeed/ViewModels/UserViewModel.swift @@ -50,7 +50,7 @@ class UserViewModel: UserViewModelProtocol { } func getCourseById(courseId: UInt64) -> Course{ - return self.provider.getCourse(courseId: courseId)! + return self.provider.getCourse(courseID: courseId)! } func getAllCourses() -> [Course]? { From 98c8ef3a4426d7a38c62f7ce54339ed5b3fd7e45 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Gj=C3=B8lga?= Date: Wed, 30 Jun 2021 10:18:41 +0200 Subject: [PATCH 08/17] hide sheet when sessionid is retrieved --- Quickfeed/Views/AuthWebWiew.swift | 1 + 1 file changed, 1 insertion(+) diff --git a/Quickfeed/Views/AuthWebWiew.swift b/Quickfeed/Views/AuthWebWiew.swift index 4cf0d21..a13bd7f 100644 --- a/Quickfeed/Views/AuthWebWiew.swift +++ b/Quickfeed/Views/AuthWebWiew.swift @@ -27,6 +27,7 @@ struct AuthWebView: View { .onChange(of: webViewModel.link, perform: { value in print(webViewModel.pageTitle) print(webViewModel.siteData["session"].unsafelyUnwrapped) + signingIn = false }) } } From e8d46fb0d283e30e7874eed152cf283f8f9a0d8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Gj=C3=B8lga?= Date: Wed, 30 Jun 2021 11:11:46 +0200 Subject: [PATCH 09/17] setSession & redesigned string casting --- Quickfeed/Managers/GRPCManager.swift | 8 ++++---- Quickfeed/Managers/GitHubManager.swift | 2 +- Quickfeed/Providers/ProviderProtocol.swift | 2 +- Quickfeed/Providers/ServerProvider.swift | 4 ++-- Quickfeed/ViewModels/UserViewModel.swift | 4 ++-- Quickfeed/Views/AuthWebWiew.swift | 7 +++++-- 6 files changed, 15 insertions(+), 12 deletions(-) diff --git a/Quickfeed/Managers/GRPCManager.swift b/Quickfeed/Managers/GRPCManager.swift index 818cb69..d0a8962 100644 --- a/Quickfeed/Managers/GRPCManager.swift +++ b/Quickfeed/Managers/GRPCManager.swift @@ -32,9 +32,9 @@ class GRPCManager { print("Connecting to \(hostname)") } - func createHeader(userID: UInt64){ + func createHeader(sessionId: String){ self.defaultOptions = CallOptions() - self.defaultOptions!.customMetadata = ["custom-header-1": "value1", "user": "\(userID)"] + self.defaultOptions!.customMetadata = ["custom-header-1": "value1", "session": "\(sessionId)"] } func shutdown() { @@ -44,8 +44,8 @@ class GRPCManager { } // MARK: Users - func setUser(userID: UInt64){ - createHeader(userID: userID) + func setSession(sessionId: String){ + createHeader(sessionId: sessionId) } func getUser() -> User?{ diff --git a/Quickfeed/Managers/GitHubManager.swift b/Quickfeed/Managers/GitHubManager.swift index 55deb83..413ed5c 100644 --- a/Quickfeed/Managers/GitHubManager.swift +++ b/Quickfeed/Managers/GitHubManager.swift @@ -20,7 +20,7 @@ class GitHubManager: NSObject, ObservableObject, ASWebAuthenticationPresentation } func logInWithGitHub() { - self.viewModel.setUser(userID: 100) + //self.viewModel.setUser(userID: 100) /*guard let authURL = URL(string: "https://QuickFeed.no/auth/github/github") else { return } let session = ASWebAuthenticationSession(url: authURL, callbackURLScheme: "quickfeed", completionHandler: { (callbackURL, error) in guard error == nil, let callbackURL = callbackURL else { return } diff --git a/Quickfeed/Providers/ProviderProtocol.swift b/Quickfeed/Providers/ProviderProtocol.swift index 29c34cd..9d3936e 100644 --- a/Quickfeed/Providers/ProviderProtocol.swift +++ b/Quickfeed/Providers/ProviderProtocol.swift @@ -9,7 +9,7 @@ import NIO protocol ProviderProtocol{ - func setUser(userID: UInt64) + func setUser(sessionId: String) func getUser() -> User? func getCoursesForCurrentUser(userID: UInt64, userStatus: [Enrollment.UserStatus]) -> [Course]? func isAuthorizedTeacher() -> Bool diff --git a/Quickfeed/Providers/ServerProvider.swift b/Quickfeed/Providers/ServerProvider.swift index 4a59b85..be3306f 100644 --- a/Quickfeed/Providers/ServerProvider.swift +++ b/Quickfeed/Providers/ServerProvider.swift @@ -15,8 +15,8 @@ class ServerProvider: ProviderProtocol{ print("New ServerProvider") } - func setUser(userID: UInt64){ - grpcManager.setUser(userID: userID) + func setUser(sessionId: String){ + grpcManager.setSession(sessionId: sessionId) } func getUser() -> User? { diff --git a/Quickfeed/ViewModels/UserViewModel.swift b/Quickfeed/ViewModels/UserViewModel.swift index b4b0911..85fe7a8 100644 --- a/Quickfeed/ViewModels/UserViewModel.swift +++ b/Quickfeed/ViewModels/UserViewModel.swift @@ -17,8 +17,8 @@ class UserViewModel: UserViewModelProtocol { // User - func setUser(userID: UInt64){ - self.provider.setUser(userID: userID) + func setUser(sessionId: String){ + self.provider.setUser(sessionId: sessionId) self.getUser() } diff --git a/Quickfeed/Views/AuthWebWiew.swift b/Quickfeed/Views/AuthWebWiew.swift index a13bd7f..78ffc68 100644 --- a/Quickfeed/Views/AuthWebWiew.swift +++ b/Quickfeed/Views/AuthWebWiew.swift @@ -26,8 +26,11 @@ struct AuthWebView: View { SwiftUIWebView(viewModel: webViewModel) .onChange(of: webViewModel.link, perform: { value in print(webViewModel.pageTitle) - print(webViewModel.siteData["session"].unsafelyUnwrapped) - signingIn = false + if let sessionString = webViewModel.siteData["session"] as? String{ + viewModel.setUser(sessionId: sessionString) + print("test") + signingIn = false + } }) } } From 5aa07449497e96d76a03444cc3c51ca3fdbfefe2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Gj=C3=B8lga?= Date: Wed, 30 Jun 2021 14:05:32 +0200 Subject: [PATCH 10/17] rename setsession -> setusersession --- Quickfeed/Managers/GRPCManager.swift | 2 +- Quickfeed/Providers/ServerProvider.swift | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/Quickfeed/Managers/GRPCManager.swift b/Quickfeed/Managers/GRPCManager.swift index d0a8962..f01eee7 100644 --- a/Quickfeed/Managers/GRPCManager.swift +++ b/Quickfeed/Managers/GRPCManager.swift @@ -44,7 +44,7 @@ class GRPCManager { } // MARK: Users - func setSession(sessionId: String){ + func setUserSession(sessionId: String){ createHeader(sessionId: sessionId) } diff --git a/Quickfeed/Providers/ServerProvider.swift b/Quickfeed/Providers/ServerProvider.swift index c450c58..613d83f 100644 --- a/Quickfeed/Providers/ServerProvider.swift +++ b/Quickfeed/Providers/ServerProvider.swift @@ -17,7 +17,7 @@ class ServerProvider: ProviderProtocol{ // MARK: Users func setUser(sessionId: String){ - grpcManager.setSession(sessionId: sessionId) + grpcManager.setUserSession(sessionId: sessionId) } func getUser() -> User? { From cebd9cc20f53b5f3218c1bce791a16b607ea63a5 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Gj=C3=B8lga?= Date: Thu, 1 Jul 2021 13:17:58 +0200 Subject: [PATCH 11/17] config file --- Quickfeed.xcodeproj/project.pbxproj | 8 ++++++++ Quickfeed/Conf.swift | 30 ++++++++++++++++++++++++++++ Quickfeed/Config.xcconfig | 12 +++++++++++ Quickfeed/Info.plist | 2 ++ Quickfeed/Managers/GRPCManager.swift | 12 +++++++++-- 5 files changed, 62 insertions(+), 2 deletions(-) create mode 100644 Quickfeed/Conf.swift create mode 100644 Quickfeed/Config.xcconfig diff --git a/Quickfeed.xcodeproj/project.pbxproj b/Quickfeed.xcodeproj/project.pbxproj index d284a93..893e3a0 100644 --- a/Quickfeed.xcodeproj/project.pbxproj +++ b/Quickfeed.xcodeproj/project.pbxproj @@ -40,6 +40,7 @@ D0F6A14E2609F54300C1D825 /* UserEnrollments.swift in Sources */ = {isa = PBXBuildFile; fileRef = D0F6A14D2609F54300C1D825 /* UserEnrollments.swift */; }; D0F9FC6325BEB9A90080A1F2 /* GRPC in Frameworks */ = {isa = PBXBuildFile; productRef = D0F9FC6225BEB9A90080A1F2 /* GRPC */; }; D0F9FC6525BEB9A90080A1F2 /* CGRPCZlib in Frameworks */ = {isa = PBXBuildFile; productRef = D0F9FC6425BEB9A90080A1F2 /* CGRPCZlib */; }; + FA12A8AC268DD53F00B83F4F /* Conf.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA12A8AB268DD53F00B83F4F /* Conf.swift */; }; FA17B95525EF7D6F008BB07F /* SubmissionReview.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA17B95425EF7D6F008BB07F /* SubmissionReview.swift */; }; FA17B95D25EF81F1008BB07F /* TranslateStatus.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA17B95C25EF81F1008BB07F /* TranslateStatus.swift */; }; FA17B96225EF90E6008BB07F /* SubmissionInfo.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA17B96125EF90E6008BB07F /* SubmissionInfo.swift */; }; @@ -130,6 +131,8 @@ D0F6A13B2609DD5000C1D825 /* RemoteImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteImage.swift; sourceTree = ""; }; D0F6A1452609F25500C1D825 /* UserInformation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserInformation.swift; sourceTree = ""; }; D0F6A14D2609F54300C1D825 /* UserEnrollments.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserEnrollments.swift; sourceTree = ""; }; + FA12A8A9268DC82F00B83F4F /* Config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = ""; }; + FA12A8AB268DD53F00B83F4F /* Conf.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Conf.swift; sourceTree = ""; }; FA17B95425EF7D6F008BB07F /* SubmissionReview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubmissionReview.swift; sourceTree = ""; }; FA17B95C25EF81F1008BB07F /* TranslateStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TranslateStatus.swift; sourceTree = ""; }; FA17B96125EF90E6008BB07F /* SubmissionInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubmissionInfo.swift; sourceTree = ""; }; @@ -391,6 +394,8 @@ FA85791125BEB4EA00223DB9 /* Info.plist */, FA85791225BEB4EA00223DB9 /* Quickfeed.entitlements */, FA85790E25BEB4EA00223DB9 /* Preview Content */, + FA12A8A9268DC82F00B83F4F /* Config.xcconfig */, + FA12A8AB268DD53F00B83F4F /* Conf.swift */, ); path = Quickfeed; sourceTree = ""; @@ -603,6 +608,7 @@ FAA798B5262D6C82005E2713 /* AssignmentView.swift in Sources */, FA17B97525EFD40B008BB07F /* MemberListHeader.swift in Sources */, FA9B950B26835A77003F115B /* ag.pb.swift in Sources */, + FA12A8AC268DD53F00B83F4F /* Conf.swift in Sources */, FA17B96225EF90E6008BB07F /* SubmissionInfo.swift in Sources */, FAA8333025E4F1BD008C05F4 /* TeacherViewModel.swift in Sources */, FA9DC66A2644548D007F1A24 /* ReviewListHeader.swift in Sources */, @@ -689,6 +695,7 @@ /* Begin XCBuildConfiguration section */ FA85792925BEB4EA00223DB9 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = FA12A8A9268DC82F00B83F4F /* Config.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; @@ -750,6 +757,7 @@ }; FA85792A25BEB4EA00223DB9 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = FA12A8A9268DC82F00B83F4F /* Config.xcconfig */; buildSettings = { ALWAYS_SEARCH_USER_PATHS = NO; CLANG_ANALYZER_NONNULL = YES; diff --git a/Quickfeed/Conf.swift b/Quickfeed/Conf.swift new file mode 100644 index 0000000..98bf9cc --- /dev/null +++ b/Quickfeed/Conf.swift @@ -0,0 +1,30 @@ +// +// Conf.swift +// Quickfeed +// +// Created by Oskar Gjølga on 01/07/2021. +// + +import Foundation + +enum Configuration { + enum Error: Swift.Error { + case missingKey, invalidValue + } + + static func value(for key: String) throws -> T where T: LosslessStringConvertible { + guard let object = Bundle.main.object(forInfoDictionaryKey:key) else { + throw Error.missingKey + } + + switch object { + case let value as T: + return value + case let string as String: + guard let value = T(string) else { fallthrough } + return value + default: + throw Error.invalidValue + } + } +} diff --git a/Quickfeed/Config.xcconfig b/Quickfeed/Config.xcconfig new file mode 100644 index 0000000..a94f8b1 --- /dev/null +++ b/Quickfeed/Config.xcconfig @@ -0,0 +1,12 @@ +// +// Config.xcconfig +// Quickfeed +// +// Created by Oskar Gjølga on 01/07/2021. +// + +// Configuration settings file format documentation can be found at: +// https://help.apple.com/xcode/#/dev745c5c974 + + +BASE_URL = uis.itest.run diff --git a/Quickfeed/Info.plist b/Quickfeed/Info.plist index 89b5f57..09d8a64 100644 --- a/Quickfeed/Info.plist +++ b/Quickfeed/Info.plist @@ -31,6 +31,8 @@ CFBundleVersion 1 + BASE_URL + $(BASE_URL) LSMinimumSystemVersion $(MACOSX_DEPLOYMENT_TARGET) diff --git a/Quickfeed/Managers/GRPCManager.swift b/Quickfeed/Managers/GRPCManager.swift index f01eee7..a85a5de 100644 --- a/Quickfeed/Managers/GRPCManager.swift +++ b/Quickfeed/Managers/GRPCManager.swift @@ -8,6 +8,11 @@ import NIO import GRPC import NIOHPACK +var baseURL: String { + return try! Configuration.value(for: "BASE_URL") +} + + class GRPCManager { static let shared = GRPCManager() @@ -18,9 +23,9 @@ class GRPCManager { var defaultOptions: CallOptions? private init(){ - let hostname = "uis.itest.run" + let hostname = baseURL let port = 9090 - + print(hostname) let configuration = ClientConnection.Configuration( target: .hostAndPort(hostname, port), eventLoopGroup: eventLoopGroup, @@ -32,6 +37,9 @@ class GRPCManager { print("Connecting to \(hostname)") } + + + func createHeader(sessionId: String){ self.defaultOptions = CallOptions() self.defaultOptions!.customMetadata = ["custom-header-1": "value1", "session": "\(sessionId)"] From 3b3a9cd243bd094e184cc4eb90e75da9918df9cb Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Gj=C3=B8lga?= Date: Thu, 1 Jul 2021 13:39:47 +0200 Subject: [PATCH 12/17] fixed typo --- Quickfeed.xcodeproj/project.pbxproj | 8 ++++---- Quickfeed/Conf.swift | 5 +++++ Quickfeed/Managers/GRPCManager.swift | 4 ---- Quickfeed/Views/{AuthWebWiew.swift => AuthWebView.swift} | 2 +- Quickfeed/Views/LogIn.swift | 2 +- 5 files changed, 11 insertions(+), 10 deletions(-) rename Quickfeed/Views/{AuthWebWiew.swift => AuthWebView.swift} (99%) diff --git a/Quickfeed.xcodeproj/project.pbxproj b/Quickfeed.xcodeproj/project.pbxproj index 893e3a0..95e628e 100644 --- a/Quickfeed.xcodeproj/project.pbxproj +++ b/Quickfeed.xcodeproj/project.pbxproj @@ -77,7 +77,7 @@ FA8EA6A126039B0D00A10351 /* GroupList.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA8EA6A026039B0D00A10351 /* GroupList.swift */; }; FA9B950A26835A64003F115B /* ag.grpc.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAC9BCF4268358F5009B1E9B /* ag.grpc.swift */; }; FA9B950B26835A77003F115B /* ag.pb.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAC9BCF3268358F5009B1E9B /* ag.pb.swift */; }; - FA9B950D2685D0A6003F115B /* AuthWebWiew.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA9B950C2685D0A6003F115B /* AuthWebWiew.swift */; }; + FA9B950D2685D0A6003F115B /* AuthWebView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA9B950C2685D0A6003F115B /* AuthWebView.swift */; }; FA9DC66A2644548D007F1A24 /* ReviewListHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = FA9DC6692644548D007F1A24 /* ReviewListHeader.swift */; }; FAA5DA36262EC643009DAEDE /* GradingBenchmarkHeader.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAA5DA35262EC643009DAEDE /* GradingBenchmarkHeader.swift */; }; FAA798B5262D6C82005E2713 /* AssignmentView.swift in Sources */ = {isa = PBXBuildFile; fileRef = FAA798B4262D6C82005E2713 /* AssignmentView.swift */; }; @@ -172,7 +172,7 @@ FA85791225BEB4EA00223DB9 /* Quickfeed.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Quickfeed.entitlements; sourceTree = ""; }; FA8EA69B26038F5D00A10351 /* AddGroupForm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddGroupForm.swift; sourceTree = ""; }; FA8EA6A026039B0D00A10351 /* GroupList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupList.swift; sourceTree = ""; }; - FA9B950C2685D0A6003F115B /* AuthWebWiew.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthWebWiew.swift; sourceTree = ""; }; + FA9B950C2685D0A6003F115B /* AuthWebView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthWebView.swift; sourceTree = ""; }; FA9DC6692644548D007F1A24 /* ReviewListHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReviewListHeader.swift; sourceTree = ""; }; FAA5DA35262EC643009DAEDE /* GradingBenchmarkHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradingBenchmarkHeader.swift; sourceTree = ""; }; FAA798B4262D6C82005E2713 /* AssignmentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssignmentView.swift; sourceTree = ""; }; @@ -423,7 +423,7 @@ FA85790A25BEB4E900223DB9 /* ContentView.swift */, D08D62952611D72A00343250 /* LogIn.swift */, D035C75725E92795005AC2BA /* NavigatorView.swift */, - FA9B950C2685D0A6003F115B /* AuthWebWiew.swift */, + FA9B950C2685D0A6003F115B /* AuthWebView.swift */, D0F6A1432609F20A00C1D825 /* User */, D04331D726028EAB0034C4B9 /* Admin */, D04B46E125D12E9D00AC8926 /* Student */, @@ -654,7 +654,7 @@ FA5A40E62609DCA700A20A13 /* SelectedMembers.swift in Sources */, FAA8330525E3E073008C05F4 /* MemberListItem.swift in Sources */, FA29717825D311B5000C99A1 /* SearchFieldController.swift in Sources */, - FA9B950D2685D0A6003F115B /* AuthWebWiew.swift in Sources */, + FA9B950D2685D0A6003F115B /* AuthWebView.swift in Sources */, FAA8333E25E519E2008C05F4 /* ResultGrid.swift in Sources */, FA5FBDE225E7E63E007EC0E3 /* ServerProvider.swift in Sources */, D04B46EC25D1301200AC8926 /* LabSection.swift in Sources */, diff --git a/Quickfeed/Conf.swift b/Quickfeed/Conf.swift index 98bf9cc..3716611 100644 --- a/Quickfeed/Conf.swift +++ b/Quickfeed/Conf.swift @@ -28,3 +28,8 @@ enum Configuration { } } } + +var baseURL: String { + return try! Configuration.value(for: "BASE_URL") +} + diff --git a/Quickfeed/Managers/GRPCManager.swift b/Quickfeed/Managers/GRPCManager.swift index a85a5de..85f121d 100644 --- a/Quickfeed/Managers/GRPCManager.swift +++ b/Quickfeed/Managers/GRPCManager.swift @@ -8,9 +8,6 @@ import NIO import GRPC import NIOHPACK -var baseURL: String { - return try! Configuration.value(for: "BASE_URL") -} class GRPCManager { @@ -25,7 +22,6 @@ class GRPCManager { private init(){ let hostname = baseURL let port = 9090 - print(hostname) let configuration = ClientConnection.Configuration( target: .hostAndPort(hostname, port), eventLoopGroup: eventLoopGroup, diff --git a/Quickfeed/Views/AuthWebWiew.swift b/Quickfeed/Views/AuthWebView.swift similarity index 99% rename from Quickfeed/Views/AuthWebWiew.swift rename to Quickfeed/Views/AuthWebView.swift index 78ffc68..3ce1549 100644 --- a/Quickfeed/Views/AuthWebWiew.swift +++ b/Quickfeed/Views/AuthWebView.swift @@ -1,5 +1,5 @@ // -// AuthWebWiew.swift +// AuthWebView.swift // Quickfeed // // WebView in SwiftUI: https://stackoverflow.com/questions/62962063/implement-webkit-with-swiftui-on-macos-and-create-a-preview-of-a-webpage diff --git a/Quickfeed/Views/LogIn.swift b/Quickfeed/Views/LogIn.swift index 4e0286c..e2e53d0 100644 --- a/Quickfeed/Views/LogIn.swift +++ b/Quickfeed/Views/LogIn.swift @@ -9,7 +9,7 @@ struct LogIn: View { @ObservedObject var viewModel: UserViewModel @Binding var login: Bool @State var signingIn: Bool = false - @State var authUrl: String = "https://uis.itest.run/app/login/login/github" + @State var authUrl: String = "https://\(baseURL)/app/login/login/github" var body: some View { VStack{ From 72b51e0d6373fbfebf70a8d242d60dcb7f4004c2 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Gj=C3=B8lga?= Date: Thu, 1 Jul 2021 13:43:43 +0200 Subject: [PATCH 13/17] cleanup --- Quickfeed/Views/AuthWebView.swift | 22 +++++----------------- 1 file changed, 5 insertions(+), 17 deletions(-) diff --git a/Quickfeed/Views/AuthWebView.swift b/Quickfeed/Views/AuthWebView.swift index 3ce1549..2cf3859 100644 --- a/Quickfeed/Views/AuthWebView.swift +++ b/Quickfeed/Views/AuthWebView.swift @@ -24,11 +24,13 @@ struct AuthWebView: View { var body: some View { SwiftUIWebView(viewModel: webViewModel) - .onChange(of: webViewModel.link, perform: { value in + .onChange(of: webViewModel.pageTitle, perform: { value in print(webViewModel.pageTitle) + print("test") + print(webViewModel.siteData) if let sessionString = webViewModel.siteData["session"] as? String{ viewModel.setUser(sessionId: sessionString) - print("test") + print(sessionString) signingIn = false } }) @@ -48,21 +50,7 @@ class WebViewModel: ObservableObject { self.siteData = [:] } } -/* -class Cookie{ - let Created: Int - let Domain: String - let Expires: Date - let HttpOnly: Bool - let Name: String - let Path: String - let Secure: Bool - let Value: String - init(opt: AnyObject) { - self.Created = opt.getAttribute("Created") - } -} -*/ + struct SwiftUIWebView: NSViewRepresentable { public typealias NSViewType = WKWebView From 649705376462295873d49967c146279917fe0065 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Gj=C3=B8lga?= Date: Fri, 2 Jul 2021 08:40:12 +0200 Subject: [PATCH 14/17] reconfig --- Quickfeed/Config.xcconfig | 2 +- Quickfeed/Views/AuthWebView.swift | 65 +++++++++++++++++------------- Quickfeed/Views/LogIn.swift | 16 +++++++- qf.db | Bin 0 -> 73728 bytes 4 files changed, 51 insertions(+), 32 deletions(-) create mode 100644 qf.db diff --git a/Quickfeed/Config.xcconfig b/Quickfeed/Config.xcconfig index a94f8b1..49fdb7b 100644 --- a/Quickfeed/Config.xcconfig +++ b/Quickfeed/Config.xcconfig @@ -9,4 +9,4 @@ // https://help.apple.com/xcode/#/dev745c5c974 -BASE_URL = uis.itest.run +BASE_URL = test.oskargjolga.com diff --git a/Quickfeed/Views/AuthWebView.swift b/Quickfeed/Views/AuthWebView.swift index 2cf3859..8bb84db 100644 --- a/Quickfeed/Views/AuthWebView.swift +++ b/Quickfeed/Views/AuthWebView.swift @@ -15,25 +15,32 @@ struct AuthWebView: View { @ObservedObject var viewModel: UserViewModel @ObservedObject var webViewModel: WebViewModel @Binding var signingIn: Bool - - init(viewModel: UserViewModel, mesgURL: String, signingIn: Binding) { + @Binding var hasSession: Bool + + init(viewModel: UserViewModel, mesgURL: String, signingIn: Binding, hasSession: Binding) { self.viewModel = viewModel self.webViewModel = WebViewModel(link: mesgURL) self._signingIn = signingIn + self._hasSession = hasSession } var body: some View { - SwiftUIWebView(viewModel: webViewModel) - .onChange(of: webViewModel.pageTitle, perform: { value in - print(webViewModel.pageTitle) - print("test") - print(webViewModel.siteData) - if let sessionString = webViewModel.siteData["session"] as? String{ - viewModel.setUser(sessionId: sessionString) - print(sessionString) - signingIn = false - } - }) + VStack{ + if webViewModel.hasSession{ + Text("has session") + } + SwiftUIWebView(viewModel: webViewModel) + .onChange(of: webViewModel.link, perform: { value in + if let sessionString = webViewModel.siteData["session"] as? String{ + print(sessionString) + self.webViewModel.hasSession = false + viewModel.setUser(sessionId: sessionString) + + } else { + print("Failed to retrieve session") + } + }) + } } } @@ -43,6 +50,7 @@ class WebViewModel: ObservableObject { @Published var link: String @Published var didFinishLoading: Bool = false @Published var pageTitle: String + @Published var hasSession: Bool = false init (link: String) { self.link = link @@ -55,7 +63,7 @@ struct SwiftUIWebView: NSViewRepresentable { public typealias NSViewType = WKWebView @ObservedObject var viewModel: WebViewModel - + private let webView: WKWebView = WKWebView() public func makeNSView(context: NSViewRepresentableContext) -> WKWebView { webView.navigationDelegate = context.coordinator @@ -63,54 +71,53 @@ struct SwiftUIWebView: NSViewRepresentable { webView.load(Foundation.URLRequest(url: URL(string: viewModel.link)!)) return webView } - + public func updateNSView(_ nsView: WKWebView, context: NSViewRepresentableContext) { } - + public func makeCoordinator() -> Coordinator { return Coordinator(viewModel) } class Coordinator: NSObject, WKNavigationDelegate { private var viewModel: WebViewModel - + init(_ viewModel: WebViewModel) { - //Initialise the WebViewModel - self.viewModel = viewModel + self.viewModel = viewModel } public func webView(_: WKWebView, didFail: WKNavigation!, withError: Error) { } - + public func webView(_: WKWebView, didFailProvisionalNavigation: WKNavigation!, withError: Error) { } - - //After the webpage is loaded, assign the data in WebViewModel class + public func webView(_ web: WKWebView, didFinish: WKNavigation!) { self.viewModel.pageTitle = web.title! self.viewModel.link = web.url!.absoluteString self.viewModel.didFinishLoading = true - web.getCookies(for: "uis.itest.run"){data in + web.getCookies(for: baseURL){data in self.viewModel.siteData = data } + } - + public func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { } - + public func webView(_ webView: WKWebView, decidePolicyFor navigationAction: WKNavigationAction, decisionHandler: @escaping (WKNavigationActionPolicy) -> Swift.Void) { decisionHandler(.allow) } - + } - + } extension WKWebView { - + private var httpCookieStore: WKHTTPCookieStore { return WKWebsiteDataStore.default().httpCookieStore } - + func getCookies(for domain: String? = nil, completion: @escaping ([String : String])->()) { var cookieDict = [String : String]() httpCookieStore.getAllCookies { cookies in diff --git a/Quickfeed/Views/LogIn.swift b/Quickfeed/Views/LogIn.swift index e2e53d0..cd4f2f2 100644 --- a/Quickfeed/Views/LogIn.swift +++ b/Quickfeed/Views/LogIn.swift @@ -10,6 +10,7 @@ struct LogIn: View { @Binding var login: Bool @State var signingIn: Bool = false @State var authUrl: String = "https://\(baseURL)/app/login/login/github" + @State var hasSession: Bool = false var body: some View { VStack{ @@ -35,12 +36,23 @@ struct LogIn: View { .sheet(isPresented: $signingIn, content: { AuthWebView(viewModel: viewModel, mesgURL: authUrl, - signingIn: $signingIn) - .frame(width: 600, height: 600) + signingIn: $signingIn, + hasSession: $hasSession + ) + .frame(width: 600, height: 600) }) + .onChange(of: self.hasSession, perform: { value in + signingIn = false + print(hasSession) + + + }) + } + .frame(width: 300, height: 300) + } } diff --git a/qf.db b/qf.db new file mode 100644 index 0000000000000000000000000000000000000000..98d6c0bbf2d84e336f83f3c39d3253c16369bc46 GIT binary patch literal 73728 zcmeI(U2oe|7{Kv(YnQcKUp5Iv)j$|mof<7;+R!w(8U-peX&MxmU{~fOK1~mG;>>o+ zinvKTi7&+0;Eo%<4Ue6~FG(sEanbX%eB=x*F_qJFbuqR0eY zH_6d7ZOPOa6{N!%2OaxFg{>nM?ml|_xZZFMwf35-bv$`I)XF=R5`(~(+q8mE=f!JJ zhJxI#Sdv{Ic$?MQ!-v*clt$VPm1nwbw-w68q0}&%K60xZ|MUfOQ1rwlj`B)2b+>gS zZpS4APe)RrUM%$~*T3N;cb6bX>J6tAbQ0w9WfJDz#xTtLr7*MGWntz=HfM*KUoc0Q zN?NqweQw9A#fIEE+d)mpu7oz>GA`jPhB$TvOLQ>Rh++eW$W<&$&NTX)02 z_owQ8K{%7Q84rc}U}LRXyT4-%UYV|^-}H^=w&f=X+irZ?li}41A`=Ip(b4*-<}Y77 zJ9xQoKYQ`j{!jK~2K$>A$+*jNIlEGp>YCqF(nrL&VM}F_k<_r;VbJfTsU$~w!@4~% zH>trEj zL&C1VzEQ0`*|G*7rufEtwc&U&+4`nCbv#*|-BFZdg&_2F znDv#0W1`Vu@l|tt&9E(eBeI1nhr0nC<~>ao;$xYlV;!XnU8>v)y0MbFgl=p)I_T#m z*!AD5GF-QZ7u9kcn@$l1+Iv)Qt4pWVKew&?kB+MJ;;ES<+j?ZZU$$9mOV!$E53Iq{Y@r|D*p=OH5GTt+mXPg` ziDk`Sp4EqwHGewqXyqT3G%i5apz)=$4rS%bI&^TgT6^%oIy*=kE;}>MICWsD+?Z46 z=V;cfMiXt7l_?!}wDVW3mX4%f2giD9gF7)M?E1G?uGQ|{vtFeUMX!C?sJoGt^}H*E zl)qjrMKf`7H|bmr$yp!#XjN;qnsvUGmYLi!*-wVil~R5uJvN7c%$myU7zt@OLTB~n zDDHdXZE?A0>W(r~`x|wlVinHX`S^i6MU}^eT~D6P( Date: Fri, 2 Jul 2021 09:20:47 +0200 Subject: [PATCH 15/17] fix --- Quickfeed/Views/AuthWebView.swift | 8 +------- Quickfeed/Views/LogIn.swift | 14 ++------------ 2 files changed, 3 insertions(+), 19 deletions(-) diff --git a/Quickfeed/Views/AuthWebView.swift b/Quickfeed/Views/AuthWebView.swift index 8bb84db..564509f 100644 --- a/Quickfeed/Views/AuthWebView.swift +++ b/Quickfeed/Views/AuthWebView.swift @@ -15,25 +15,19 @@ struct AuthWebView: View { @ObservedObject var viewModel: UserViewModel @ObservedObject var webViewModel: WebViewModel @Binding var signingIn: Bool - @Binding var hasSession: Bool - init(viewModel: UserViewModel, mesgURL: String, signingIn: Binding, hasSession: Binding) { + init(viewModel: UserViewModel, mesgURL: String, signingIn: Binding) { self.viewModel = viewModel self.webViewModel = WebViewModel(link: mesgURL) self._signingIn = signingIn - self._hasSession = hasSession } var body: some View { VStack{ - if webViewModel.hasSession{ - Text("has session") - } SwiftUIWebView(viewModel: webViewModel) .onChange(of: webViewModel.link, perform: { value in if let sessionString = webViewModel.siteData["session"] as? String{ print(sessionString) - self.webViewModel.hasSession = false viewModel.setUser(sessionId: sessionString) } else { diff --git a/Quickfeed/Views/LogIn.swift b/Quickfeed/Views/LogIn.swift index cd4f2f2..eb9755c 100644 --- a/Quickfeed/Views/LogIn.swift +++ b/Quickfeed/Views/LogIn.swift @@ -10,7 +10,7 @@ struct LogIn: View { @Binding var login: Bool @State var signingIn: Bool = false @State var authUrl: String = "https://\(baseURL)/app/login/login/github" - @State var hasSession: Bool = false + var body: some View { VStack{ @@ -36,20 +36,10 @@ struct LogIn: View { .sheet(isPresented: $signingIn, content: { AuthWebView(viewModel: viewModel, mesgURL: authUrl, - signingIn: $signingIn, - hasSession: $hasSession + signingIn: $signingIn ) .frame(width: 600, height: 600) }) - .onChange(of: self.hasSession, perform: { value in - signingIn = false - print(hasSession) - - - }) - - - } .frame(width: 300, height: 300) From d81fa55f41c64b2e808de5c205b9f1b973cd1d31 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Gj=C3=B8lga?= Date: Tue, 6 Jul 2021 12:37:35 +0200 Subject: [PATCH 16/17] cleanup --- Quickfeed/ViewModels/UserViewModel.swift | 2 +- Quickfeed/Views/AuthWebView.swift | 14 ++++++++------ Quickfeed/Views/LogIn.swift | 7 ++++++- 3 files changed, 15 insertions(+), 8 deletions(-) diff --git a/Quickfeed/ViewModels/UserViewModel.swift b/Quickfeed/ViewModels/UserViewModel.swift index 2ad70ee..22acd65 100644 --- a/Quickfeed/ViewModels/UserViewModel.swift +++ b/Quickfeed/ViewModels/UserViewModel.swift @@ -19,10 +19,10 @@ class UserViewModel: UserViewModelProtocol { func setUser(sessionId: String){ self.provider.setUser(sessionId: sessionId) - self.getUser() } func getUser() { + print("get user") self.user = provider.getUser()! self.getAllCoursesForCurrentUser() self.getEnrollments() diff --git a/Quickfeed/Views/AuthWebView.swift b/Quickfeed/Views/AuthWebView.swift index 564509f..1f21f0d 100644 --- a/Quickfeed/Views/AuthWebView.swift +++ b/Quickfeed/Views/AuthWebView.swift @@ -15,20 +15,27 @@ struct AuthWebView: View { @ObservedObject var viewModel: UserViewModel @ObservedObject var webViewModel: WebViewModel @Binding var signingIn: Bool + @Binding var signedIn: Bool - init(viewModel: UserViewModel, mesgURL: String, signingIn: Binding) { + init(viewModel: UserViewModel, mesgURL: String, signingIn: Binding, signedIn: Binding) { self.viewModel = viewModel self.webViewModel = WebViewModel(link: mesgURL) self._signingIn = signingIn + self._signedIn = signedIn } var body: some View { VStack{ SwiftUIWebView(viewModel: webViewModel) .onChange(of: webViewModel.link, perform: { value in + do{ + sleep(3) + } if let sessionString = webViewModel.siteData["session"] as? String{ print(sessionString) viewModel.setUser(sessionId: sessionString) + signingIn = false + signedIn = true } else { print("Failed to retrieve session") @@ -90,9 +97,6 @@ struct SwiftUIWebView: NSViewRepresentable { web.getCookies(for: baseURL){data in self.viewModel.siteData = data } - - - } public func webView(_ webView: WKWebView, didStartProvisionalNavigation navigation: WKNavigation!) { } @@ -109,9 +113,7 @@ struct SwiftUIWebView: NSViewRepresentable { extension WKWebView { - private var httpCookieStore: WKHTTPCookieStore { return WKWebsiteDataStore.default().httpCookieStore } - func getCookies(for domain: String? = nil, completion: @escaping ([String : String])->()) { var cookieDict = [String : String]() httpCookieStore.getAllCookies { cookies in diff --git a/Quickfeed/Views/LogIn.swift b/Quickfeed/Views/LogIn.swift index eb9755c..2b74f07 100644 --- a/Quickfeed/Views/LogIn.swift +++ b/Quickfeed/Views/LogIn.swift @@ -9,6 +9,7 @@ struct LogIn: View { @ObservedObject var viewModel: UserViewModel @Binding var login: Bool @State var signingIn: Bool = false + @State var signedIn: Bool = false @State var authUrl: String = "https://\(baseURL)/app/login/login/github" @@ -36,11 +37,15 @@ struct LogIn: View { .sheet(isPresented: $signingIn, content: { AuthWebView(viewModel: viewModel, mesgURL: authUrl, - signingIn: $signingIn + signingIn: $signingIn, + signedIn: $signedIn ) .frame(width: 600, height: 600) }) } + .onChange(of: signedIn, perform: { data in + viewModel.getUser() + }) .frame(width: 300, height: 300) From e72ed9716106629979581e4fd0dad591214327d9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Oskar=20Gj=C3=B8lga?= Date: Tue, 6 Jul 2021 14:56:31 +0200 Subject: [PATCH 17/17] grpc port in config --- Quickfeed/Conf.swift | 5 ++++- Quickfeed/Config.xcconfig | 1 + Quickfeed/Info.plist | 2 ++ Quickfeed/Managers/GRPCManager.swift | 4 ++-- Quickfeed/Views/AuthWebView.swift | 2 +- Quickfeed/Views/LogIn.swift | 2 +- 6 files changed, 11 insertions(+), 5 deletions(-) diff --git a/Quickfeed/Conf.swift b/Quickfeed/Conf.swift index 3716611..d195aa9 100644 --- a/Quickfeed/Conf.swift +++ b/Quickfeed/Conf.swift @@ -29,7 +29,10 @@ enum Configuration { } } -var baseURL: String { +var CONF_BASE_URL: String { return try! Configuration.value(for: "BASE_URL") } +var CONF_GRPC_PORT: String { + return try! Configuration.value(for: "GRPC_PORT") +} diff --git a/Quickfeed/Config.xcconfig b/Quickfeed/Config.xcconfig index 49fdb7b..9521ace 100644 --- a/Quickfeed/Config.xcconfig +++ b/Quickfeed/Config.xcconfig @@ -10,3 +10,4 @@ BASE_URL = test.oskargjolga.com +GRPC_PORT = 9090 diff --git a/Quickfeed/Info.plist b/Quickfeed/Info.plist index 09d8a64..f3d7dbb 100644 --- a/Quickfeed/Info.plist +++ b/Quickfeed/Info.plist @@ -33,6 +33,8 @@ 1 BASE_URL $(BASE_URL) + GRPC_PORT + $(GRPC_PORT) LSMinimumSystemVersion $(MACOSX_DEPLOYMENT_TARGET) diff --git a/Quickfeed/Managers/GRPCManager.swift b/Quickfeed/Managers/GRPCManager.swift index 85f121d..fa3bddb 100644 --- a/Quickfeed/Managers/GRPCManager.swift +++ b/Quickfeed/Managers/GRPCManager.swift @@ -20,8 +20,8 @@ class GRPCManager { var defaultOptions: CallOptions? private init(){ - let hostname = baseURL - let port = 9090 + let hostname = CONF_BASE_URL + let port = Int(CONF_GRPC_PORT)! let configuration = ClientConnection.Configuration( target: .hostAndPort(hostname, port), eventLoopGroup: eventLoopGroup, diff --git a/Quickfeed/Views/AuthWebView.swift b/Quickfeed/Views/AuthWebView.swift index 1f21f0d..d8597ea 100644 --- a/Quickfeed/Views/AuthWebView.swift +++ b/Quickfeed/Views/AuthWebView.swift @@ -94,7 +94,7 @@ struct SwiftUIWebView: NSViewRepresentable { self.viewModel.pageTitle = web.title! self.viewModel.link = web.url!.absoluteString self.viewModel.didFinishLoading = true - web.getCookies(for: baseURL){data in + web.getCookies(for: CONF_BASE_URL){data in self.viewModel.siteData = data } } diff --git a/Quickfeed/Views/LogIn.swift b/Quickfeed/Views/LogIn.swift index 2b74f07..7b4fc33 100644 --- a/Quickfeed/Views/LogIn.swift +++ b/Quickfeed/Views/LogIn.swift @@ -10,7 +10,7 @@ struct LogIn: View { @Binding var login: Bool @State var signingIn: Bool = false @State var signedIn: Bool = false - @State var authUrl: String = "https://\(baseURL)/app/login/login/github" + @State var authUrl: String = "https://\(CONF_BASE_URL)/app/login/login/github" var body: some View {