Skip to content

Authentication using WkWebView #77

New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Draft
wants to merge 19 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions Quickfeed.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -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 */; };
Expand Down Expand Up @@ -76,6 +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 /* 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 */; };
Expand Down Expand Up @@ -129,6 +131,8 @@
D0F6A13B2609DD5000C1D825 /* RemoteImage.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RemoteImage.swift; sourceTree = "<group>"; };
D0F6A1452609F25500C1D825 /* UserInformation.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserInformation.swift; sourceTree = "<group>"; };
D0F6A14D2609F54300C1D825 /* UserEnrollments.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = UserEnrollments.swift; sourceTree = "<group>"; };
FA12A8A9268DC82F00B83F4F /* Config.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = Config.xcconfig; sourceTree = "<group>"; };
FA12A8AB268DD53F00B83F4F /* Conf.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Conf.swift; sourceTree = "<group>"; };
FA17B95425EF7D6F008BB07F /* SubmissionReview.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubmissionReview.swift; sourceTree = "<group>"; };
FA17B95C25EF81F1008BB07F /* TranslateStatus.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TranslateStatus.swift; sourceTree = "<group>"; };
FA17B96125EF90E6008BB07F /* SubmissionInfo.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SubmissionInfo.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -168,6 +172,7 @@
FA85791225BEB4EA00223DB9 /* Quickfeed.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = Quickfeed.entitlements; sourceTree = "<group>"; };
FA8EA69B26038F5D00A10351 /* AddGroupForm.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AddGroupForm.swift; sourceTree = "<group>"; };
FA8EA6A026039B0D00A10351 /* GroupList.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GroupList.swift; sourceTree = "<group>"; };
FA9B950C2685D0A6003F115B /* AuthWebView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AuthWebView.swift; sourceTree = "<group>"; };
FA9DC6692644548D007F1A24 /* ReviewListHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ReviewListHeader.swift; sourceTree = "<group>"; };
FAA5DA35262EC643009DAEDE /* GradingBenchmarkHeader.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = GradingBenchmarkHeader.swift; sourceTree = "<group>"; };
FAA798B4262D6C82005E2713 /* AssignmentView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = AssignmentView.swift; sourceTree = "<group>"; };
Expand Down Expand Up @@ -389,6 +394,8 @@
FA85791125BEB4EA00223DB9 /* Info.plist */,
FA85791225BEB4EA00223DB9 /* Quickfeed.entitlements */,
FA85790E25BEB4EA00223DB9 /* Preview Content */,
FA12A8A9268DC82F00B83F4F /* Config.xcconfig */,
FA12A8AB268DD53F00B83F4F /* Conf.swift */,
);
path = Quickfeed;
sourceTree = "<group>";
Expand Down Expand Up @@ -416,6 +423,7 @@
FA85790A25BEB4E900223DB9 /* ContentView.swift */,
D08D62952611D72A00343250 /* LogIn.swift */,
D035C75725E92795005AC2BA /* NavigatorView.swift */,
FA9B950C2685D0A6003F115B /* AuthWebView.swift */,
D0F6A1432609F20A00C1D825 /* User */,
D04331D726028EAB0034C4B9 /* Admin */,
D04B46E125D12E9D00AC8926 /* Student */,
Expand Down Expand Up @@ -600,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 */,
Expand Down Expand Up @@ -645,6 +654,7 @@
FA5A40E62609DCA700A20A13 /* SelectedMembers.swift in Sources */,
FAA8330525E3E073008C05F4 /* MemberListItem.swift in Sources */,
FA29717825D311B5000C99A1 /* SearchFieldController.swift in Sources */,
FA9B950D2685D0A6003F115B /* AuthWebView.swift in Sources */,
FAA8333E25E519E2008C05F4 /* ResultGrid.swift in Sources */,
FA5FBDE225E7E63E007EC0E3 /* ServerProvider.swift in Sources */,
D04B46EC25D1301200AC8926 /* LabSection.swift in Sources */,
Expand Down Expand Up @@ -685,6 +695,7 @@
/* Begin XCBuildConfiguration section */
FA85792925BEB4EA00223DB9 /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = FA12A8A9268DC82F00B83F4F /* Config.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
Expand Down Expand Up @@ -746,6 +757,7 @@
};
FA85792A25BEB4EA00223DB9 /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = FA12A8A9268DC82F00B83F4F /* Config.xcconfig */;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
CLANG_ANALYZER_NONNULL = YES;
Expand Down
38 changes: 38 additions & 0 deletions Quickfeed/Conf.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
//
// 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<T>(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
}
}
}

var CONF_BASE_URL: String {
return try! Configuration.value(for: "BASE_URL")
}

var CONF_GRPC_PORT: String {
return try! Configuration.value(for: "GRPC_PORT")
}
13 changes: 13 additions & 0 deletions Quickfeed/Config.xcconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
//
// 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 = test.oskargjolga.com
GRPC_PORT = 9090
4 changes: 4 additions & 0 deletions Quickfeed/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
</array>
<key>CFBundleVersion</key>
<string>1</string>
<key>BASE_URL</key>
<string>$(BASE_URL)</string>
<key>GRPC_PORT</key>
<string>$(GRPC_PORT)</string>
<key>LSMinimumSystemVersion</key>
<string>$(MACOSX_DEPLOYMENT_TARGET)</string>
</dict>
Expand Down
18 changes: 11 additions & 7 deletions Quickfeed/Managers/GRPCManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@ import NIO
import GRPC
import NIOHPACK



class GRPCManager {
static let shared = GRPCManager()

Expand All @@ -18,9 +20,8 @@ class GRPCManager {
var defaultOptions: CallOptions?

private init(){
let hostname = "localhost"
let port = 9090

let hostname = CONF_BASE_URL
let port = Int(CONF_GRPC_PORT)!
let configuration = ClientConnection.Configuration(
target: .hostAndPort(hostname, port),
eventLoopGroup: eventLoopGroup,
Expand All @@ -32,9 +33,12 @@ 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() {
Expand All @@ -44,8 +48,8 @@ class GRPCManager {
}

// MARK: Users
func setUser(userID: UInt64){
createHeader(userID: userID)
func setUserSession(sessionId: String){
createHeader(sessionId: sessionId)
}

func getUser() -> User?{
Expand Down
2 changes: 1 addition & 1 deletion Quickfeed/Managers/GitHubManager.swift
Original file line number Diff line number Diff line change
Expand Up @@ -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 }
Expand Down
80 changes: 51 additions & 29 deletions Quickfeed/Providers/ProviderProtocol.swift
Original file line number Diff line number Diff line change
Expand Up @@ -9,43 +9,65 @@ import NIO


protocol ProviderProtocol{
func setUser(userID: UInt64)



// MARK: Users
func setUser(sessionId: String)
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<Groups>
func createGroup(group: Group) -> EventLoopFuture<Group>
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<Groups>
func getSubmissionsByUser(courseId: UInt64, userId: UInt64) -> [Submission]
func getSubmissionsByGroub(courseId: UInt64, groupId: UInt64) -> [Submission]
func getSubmissionsByCourse(courseId: UInt64, type: SubmissionsForCourseRequest.TypeEnum) -> EventLoopFuture<CourseSubmissions>
func getEnrollmentsForUser(userId: UInt64) -> [Enrollment]
func getOrganization(orgName: String) -> EventLoopFuture<Organization>
func getProviders() -> [String]
func updateAssignments(courseId: UInt64) -> Bool
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])
// MARK: Assignments
func getAssignments(courseID: UInt64) -> [Assignment]?
func updateAssignments(courseID: UInt64) -> Bool

func getEnrollmentsByCourse(courseId: UInt64, ignoreGroupMembers: Bool?, withActivity: Bool?, userStatus: [Enrollment.UserStatus]) -> EventLoopFuture<Enrollments>
// MARK: Enrollments
func getEnrollmentsByUser(userID: UInt64, userStatus: [Enrollment.UserStatus]) -> [Enrollment]?
func getEnrollmentsByCourse(courseID: UInt64, ignoreGroupMembers: Bool?, withActivity: Bool?, userStatus: [Enrollment.UserStatus]) -> EventLoopFuture<Enrollments>
func createEnrollment(enrollment: Enrollment)
func updateEnrollment(enrollment: Enrollment)
func updateEnrollments(courseID: UInt64)

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]
// MARK: Submissions
func getSubmissions(userID: UInt64?, groupID: UInt64?, courseID: UInt64) -> [Submission]?
func getSubmissionsByCourse(courseID: UInt64, type: SubmissionsForCourseRequest.TypeEnum) -> EventLoopFuture<CourseSubmissions>
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<Organization>
func getRepositories(courseID: UInt64, repositoryTypes: [Repository.TypeEnum]) -> Repositories?
func isEmptyRepo(userID: UInt64, groupID: UInt64, courseID: UInt64)
}
Loading