diff --git a/enzevalos_iphone.xcodeproj/project.pbxproj b/enzevalos_iphone.xcodeproj/project.pbxproj index 06c31b271d851d8881c933b99a8012e5457d1762..9a3f8ad0f5ee5db166b4921ec053dd10c1fe450b 100644 --- a/enzevalos_iphone.xcodeproj/project.pbxproj +++ b/enzevalos_iphone.xcodeproj/project.pbxproj @@ -120,6 +120,7 @@ 477548E421F77BA0000B22A8 /* StudyParameterProtocol.swift in Sources */ = {isa = PBXBuildFile; fileRef = 477548E321F77BA0000B22A8 /* StudyParameterProtocol.swift */; }; 4775D7A8243F0D630052F2CC /* DisplayProtocols.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4775D7A7243F0D630052F2CC /* DisplayProtocols.swift */; }; 4775D7AA243F0E260052F2CC /* SimulatorData.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4775D7A9243F0E260052F2CC /* SimulatorData.swift */; }; + 4775D7AC243F18BC0052F2CC /* SecurityBriefingView.swift in Sources */ = {isa = PBXBuildFile; fileRef = 4775D7AB243F18BC0052F2CC /* SecurityBriefingView.swift */; }; 477670C4228453FB00043604 /* ButtonCell.xib in Resources */ = {isa = PBXBuildFile; fileRef = 477670C3228453FB00043604 /* ButtonCell.xib */; }; 477670C6228454F700043604 /* ButtonCell.swift in Sources */ = {isa = PBXBuildFile; fileRef = 477670C5228454F700043604 /* ButtonCell.swift */; }; 478154A721FF3F0900A931EC /* Warning.swift in Sources */ = {isa = PBXBuildFile; fileRef = 478154A621FF3F0900A931EC /* Warning.swift */; }; @@ -569,6 +570,7 @@ 477548E321F77BA0000B22A8 /* StudyParameterProtocol.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = StudyParameterProtocol.swift; sourceTree = "<group>"; }; 4775D7A7243F0D630052F2CC /* DisplayProtocols.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = DisplayProtocols.swift; sourceTree = "<group>"; }; 4775D7A9243F0E260052F2CC /* SimulatorData.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SimulatorData.swift; sourceTree = "<group>"; }; + 4775D7AB243F18BC0052F2CC /* SecurityBriefingView.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = SecurityBriefingView.swift; sourceTree = "<group>"; }; 477670C3228453FB00043604 /* ButtonCell.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = ButtonCell.xib; sourceTree = "<group>"; }; 477670C5228454F700043604 /* ButtonCell.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = ButtonCell.swift; sourceTree = "<group>"; }; 478154A621FF3F0900A931EC /* Warning.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Warning.swift; sourceTree = "<group>"; }; @@ -1290,6 +1292,7 @@ 47C822632438A84C005BCE73 /* SenderViewChildren */, 47C8224824379EAE005BCE73 /* MessageViewChildren */, 47C8224B24379EAE005BCE73 /* AttachmentChildren */, + 4775D7AB243F18BC0052F2CC /* SecurityBriefingView.swift */, ); path = "Tabbed Views"; sourceTree = "<group>"; @@ -2256,6 +2259,7 @@ 47C8226D2438C2CF005BCE73 /* ReadViewModel.swift in Sources */, 47C822602437A143005BCE73 /* CornerRounder.swift in Sources */, 8428A85D1F436A05007649A5 /* Badges.swift in Sources */, + 4775D7AC243F18BC0052F2CC /* SecurityBriefingView.swift in Sources */, 971D404A2428C87E002FCD31 /* BadgeCaseView.swift in Sources */, 47C8225B24379EAE005BCE73 /* MessageViewMain.swift in Sources */, 8428A8651F436A11007649A5 /* BadgeCaseCollectionViewCell.swift in Sources */, diff --git a/enzevalos_iphone/Dialog/DialogOption.swift b/enzevalos_iphone/Dialog/DialogOption.swift index e6b13a208fd411a3c2c04ee303ba89b3fd077713..7a220e3a7b0bbc0fc8e3b8d1aacb816faa9fb428 100644 --- a/enzevalos_iphone/Dialog/DialogOption.swift +++ b/enzevalos_iphone/Dialog/DialogOption.swift @@ -71,6 +71,47 @@ struct DialogStruct: Dialog { enum ButtonAction { case AskSenderToConfirm, AskSenderToSendPK, AskSenderToResendForPK, InvitePerson, IgnoreMail, AskUserToImportSK, ImportSK, ImportPK, MoreInformation, ExportSK, OK, IgnoreWarning, SendPK + + var title: LocalizedStringKey { + get { + switch self { + case .AskSenderToConfirm: return "Security.Dialog.Button.Title.Confirmation" + case .AskSenderToSendPK: return "Security.Dialog.Button.Title.Ask.ForPK" + case .AskSenderToResendForPK: return "Security.Dialog.Button.Title.Ask.Resend.ForPK" + case .InvitePerson: return "Security.Dialog.Button.Title.Invite" + case .IgnoreMail: return "Security.Dialog.Button.Title.Ignore.Mail" + case .AskUserToImportSK: return "MISSING" + case .ImportSK: return "Security.Dialog.Button.Title.Import.SK" + case .ImportPK: return "MISSING" + case .MoreInformation: return "MoreInformation" + case .ExportSK: return "MISSING" + case .OK: return "Security.Dialog.Button.Title.OK" + case .IgnoreWarning: return "MISSING" + case .SendPK: return "Security.Dialog.Button.Title.Send.PK" + } + } + } + + var color: Color { + get { + let defaultColor = Color.blue + switch self { + case .AskSenderToConfirm: return defaultColor + case .AskSenderToSendPK: return defaultColor + case .AskSenderToResendForPK: return defaultColor + case .InvitePerson: return defaultColor + case .IgnoreMail: return defaultColor + case .AskUserToImportSK: return defaultColor + case .ImportSK: return defaultColor + case .ImportPK: return defaultColor + case .MoreInformation: return defaultColor + case .ExportSK: return defaultColor + case .OK: return defaultColor + case .IgnoreWarning: return defaultColor + case .SendPK: return defaultColor + } + } + } } enum DialogOption: Dialog { diff --git a/enzevalos_iphone/PersistentMail +CoreDataProperties.swift b/enzevalos_iphone/PersistentMail +CoreDataProperties.swift index 9151291c0637eaf0e9db46be1c51cbeaa091a7d4..dac47b609d78212da0b51f27c3a3c28452205fbf 100644 --- a/enzevalos_iphone/PersistentMail +CoreDataProperties.swift +++ b/enzevalos_iphone/PersistentMail +CoreDataProperties.swift @@ -469,6 +469,12 @@ extension PersistentMail: DisplayMail { func markAsRead(isRead: Bool) { self.isRead = isRead } + + var transportEnc: Bool { + get { + return true + } + } } extension Attachment: DisplayAttachment { diff --git a/enzevalos_iphone/SwiftUI/Data/DisplayProtocols.swift b/enzevalos_iphone/SwiftUI/Data/DisplayProtocols.swift index 74cc34e991db663bf08555741c380d75f755afd9..616e42fecdddbd7cecaebe220b67e858d94120c4 100644 --- a/enzevalos_iphone/SwiftUI/Data/DisplayProtocols.swift +++ b/enzevalos_iphone/SwiftUI/Data/DisplayProtocols.swift @@ -31,8 +31,26 @@ enum ResponseType { enum CryptoState { case UnableToDecrypt, InvalidSignature, NoCrypto, PlainMissingPublicKeyToVerify, PlainButValidSignature, EncValidSign, EncNoSignature, EncButMissingPublicKeyToVerify + + var buttonActions: [ButtonAction] { + get { + switch self { + case .UnableToDecrypt: return [.AskUserToImportSK, .AskSenderToResendForPK] + case .InvalidSignature: return [.AskSenderToConfirm, .IgnoreMail] + case .NoCrypto: return [.InvitePerson] + case .PlainMissingPublicKeyToVerify: return [.AskSenderToSendPK] + case .PlainButValidSignature: return [.SendPK] + case .EncValidSign: return [] + case .EncNoSignature: return [.AskSenderToConfirm] + case .EncButMissingPublicKeyToVerify: return [.AskSenderToSendPK] + } + } + } + + } + protocol DisplayAttachment { var myName: String { get } var myData: Data { get } @@ -77,6 +95,7 @@ protocol DisplayMail { // Crypto var signedState: SignatureState { get } var encState: EncryptionState { get } + var transportEnc: Bool { get } var persistentMail: PersistentMail? { get } @@ -135,6 +154,7 @@ extension DisplayMail { } } + var dialog: DialogStruct { get { // TODO: Do we add new public key stuff? @@ -240,6 +260,13 @@ extension DisplayMail { } } + var buttonActions: [ButtonAction] { + get { + let (_, state) = evaluateSecurity() + return state.buttonActions + } + } + var warnings: [DialogStruct] { get { var result = [DialogStruct] () diff --git a/enzevalos_iphone/SwiftUI/Data/SimulatorData.swift b/enzevalos_iphone/SwiftUI/Data/SimulatorData.swift index d5e46ee7deb2c91252d65802c8828715016078bd..770db50a7895af5ec52da6434b5c0a1fd6dcd3c7 100644 --- a/enzevalos_iphone/SwiftUI/Data/SimulatorData.swift +++ b/enzevalos_iphone/SwiftUI/Data/SimulatorData.swift @@ -173,6 +173,8 @@ struct PseuoMail: DisplayMail { return nil } + var transportEnc: Bool = true + } diff --git a/enzevalos_iphone/SwiftUI/Read/ReadMainView.swift b/enzevalos_iphone/SwiftUI/Read/ReadMainView.swift index 27c8aef4323c3573016431f153c65aa0dcbefe4e..cefafae8ba5446354f98703463dcfba72dba15cf 100644 --- a/enzevalos_iphone/SwiftUI/Read/ReadMainView.swift +++ b/enzevalos_iphone/SwiftUI/Read/ReadMainView.swift @@ -43,7 +43,7 @@ struct ReadMainView <M: DisplayMail>: View { Tab( image: Image(systemName: "shield"), description: "security", - content:AnyView(AttachmentsViewMain(attachments: mail.displayAttachments, dlAll: true)) + content:AnyView(SecurityBriefingView(mail: mail)) ), Tab( image: Image(systemName: "person.fill"), diff --git a/enzevalos_iphone/SwiftUI/Read/Tabbed Views/MessageViewMain.swift b/enzevalos_iphone/SwiftUI/Read/Tabbed Views/MessageViewMain.swift index 627c776bd367314091a7736f29e1ce5c07009810..60ca018b0f81a9e6a09e2d17dfb61ec8297b3328 100644 --- a/enzevalos_iphone/SwiftUI/Read/Tabbed Views/MessageViewMain.swift +++ b/enzevalos_iphone/SwiftUI/Read/Tabbed Views/MessageViewMain.swift @@ -30,16 +30,7 @@ struct MessageViewMain <M: DisplayMail>: View { VStack{ Subjectbar Divider() - if mail.warnings.count > 0 { - ForEach(0..<mail.warnings.count) { index in - DialogView(option: self.mail.warnings[index], ctaAction: self.action, additionalAction: self.action, dismissAction: self.action, extend: false) - } - Divider() - MessageBody.padding(.horizontal) - } - else{ - MessageBody.padding(.horizontal) - } + MessageBody.padding(.horizontal) } } .onTapGesture { diff --git a/enzevalos_iphone/SwiftUI/Read/Tabbed Views/SecurityBriefingView.swift b/enzevalos_iphone/SwiftUI/Read/Tabbed Views/SecurityBriefingView.swift new file mode 100644 index 0000000000000000000000000000000000000000..a8417597935f500bfacc13ed10b8be3c4af30425 --- /dev/null +++ b/enzevalos_iphone/SwiftUI/Read/Tabbed Views/SecurityBriefingView.swift @@ -0,0 +1,149 @@ +// +// SecurityBriefingView.swift +// enzevalos_iphone +// +// Created by Oliver Wiese on 09.04.20. +// Copyright © 2020 fu-berlin. All rights reserved. +// + +import SwiftUI + +struct SecurityBriefingView<M: DisplayMail>: View { + let mail: M + + let padding: CGFloat = 10 + @State private var showWarning = true + + var body: some View { + ScrollView { + title + if mail.warnings.count > 0 && showWarning { + ForEach(0..<mail.warnings.count) {index in + DialogView(option: self.mail.warnings[index], ctaAction: self.action, additionalAction: self.action, dismissAction: self.action, extend: false) + } + } + confidentiality + Divider() + authenticity + Divider() + actions + } + } + + func action () { + showWarning.toggle() + } + + var title: some View { + Text("ReadView.SecurityBriefing.Title") + .font(.largeTitle) + } + + var confidentiality: some View { + var stateString: LocalizedStringKey + var secure = false + switch (mail.encState, mail.transportEnc) { + case (.NoEncryption, true): stateString = "ReadView.SecurityBriefing.Conf.State.TransportEnc" + case (.NoEncryption, false): stateString = "ReadView.SecurityBriefing.Conf.State.Plain" + case (.UnableToDecrypt, _): stateString = "ReadView.SecurityBriefing.Conf.State.UnableToDecrypt" + case (.ValidEncryptedWithOldKey, _), (.ValidedEncryptedWithCurrentKey, _): stateString = "ReadView.SecurityBriefing.Conf.State.Encrypted" + secure = true + } + + return InfoView( + titleString: "ReadView.SecurityBriefing.Conf.Title", + descriptionString: "ReadView.SecurityBriefing.Conf.Description", + stateString: stateString, + padding: padding, secure: secure) + } + + var authenticity: some View { + var stateString: LocalizedStringKey + var secure = false + switch mail.signedState { + case .InvalidSignature: + stateString = "ReadView.SecurityBriefing.Auth.State.InvalidSignature" + case .NoSignature: + stateString = "ReadView.SecurityBriefing.Auth.State.UnSigned" + case .NoPublicKey: + stateString = "ReadView.SecurityBriefing.Auth.State.MissingPK" + case .ValidSignature: + stateString = "ReadView.SecurityBriefing.Auth.State.Signed" + secure = true + } + return InfoView( + titleString: "ReadView.SecurityBriefing.Auth.Title", + descriptionString: "ReadView.SecurityBriefing.Auth.Description", + stateString: stateString, + padding: padding, secure: secure) + } + + var actions: some View { + VStack { + Text("ReadView.SecurityBriefing.Actions.Title") + .font(.headline) + .padding(padding) + Text("ReadView.SecurityBriefing.Actions.Description" ) + .fontWeight(.light) + .padding(padding) + ForEach(0..<mail.buttonActions.count) {index in + Button(action: { + print("Click!") + }, label: { + Text(self.mail.buttonActions[index].title) + .frame(maxWidth: .infinity, minHeight: 50, maxHeight: 50) + .addBorder(self.mail.buttonActions[index].color, width: 1, cornerRadius: 30) + // .foregroundColor(.white) + //.background(RoundedCorners(color: self.mail.buttonActions[index].color, radius: 30)) + .padding(.vertical, 10) + .padding(.horizontal, 20) + }) + } + } + } +} + +struct InfoView: View { + let titleString: LocalizedStringKey + let descriptionString: LocalizedStringKey + var stateString: LocalizedStringKey + var padding: CGFloat + var secure: Bool + + var body: some View { + VStack(alignment: .leading) { + Text(titleString) + .font(.headline) + .padding(padding) + // Text(descriptionString) + // .fontWeight(.light) + // .padding(padding) + HStack { + if secure { + Image(systemName: "checkmark") + .resizable() + .frame(width: 40, height: 40) + .foregroundColor(Color(ThemeManager.encryptedMessageColor())) + .padding(.leading, padding) + } else { + Image(systemName: "xmark.octagon.fill") + .resizable() + .frame(width: 40, height: 40) + .foregroundColor(Color(ThemeManager.troubleMessageColor())) + .padding(.leading, padding) + } + + Text(stateString) + .padding(padding) + } + } + } +} + +struct SecurityBriefingView_Previews: PreviewProvider { + static var previews: some View { + let sim = Simulators<SecurityBriefingView<PseuoMail>>() + return sim.previews(view: SecurityBriefingView(mail: DummyData.MissingPKMail)) + + } +} diff --git a/enzevalos_iphone/SwiftUI/Read/Tabbed Views/SenderViewMain.swift b/enzevalos_iphone/SwiftUI/Read/Tabbed Views/SenderViewMain.swift index c2dcada82121fb65d77b740e8b92a206f4c843ec..5b9abe1079590f2562e31415906155826bd0de9b 100644 --- a/enzevalos_iphone/SwiftUI/Read/Tabbed Views/SenderViewMain.swift +++ b/enzevalos_iphone/SwiftUI/Read/Tabbed Views/SenderViewMain.swift @@ -36,15 +36,7 @@ struct SenderViewMain <M: DisplayMail>: View { var body: some View { ScrollView { - if mail.warnings.count > 0 { - ForEach(0..<mail.warnings.count) { index in - DialogView(option: self.mail.warnings[index], ctaAction: {print("Hello")}, additionalAction: {print("Hello")}, dismissAction: {print("Hello")}, extend: (index == (self.mail.warnings.count - 1))) - } - - } else { - map - } - + map icon sender .offset(y: (-110/2 + 20)) diff --git a/enzevalos_iphone/en.lproj/Localizable.strings b/enzevalos_iphone/en.lproj/Localizable.strings index 4d30a330e70c6058591c23d1f87078dad457b9cd..b082efeb3cbed807ed443bc617c4d8cce2b5282d 100644 --- a/enzevalos_iphone/en.lproj/Localizable.strings +++ b/enzevalos_iphone/en.lproj/Localizable.strings @@ -383,3 +383,18 @@ "Security.Dialog.Button.Title.Invite" = "Ask to use encryption"; "Security.Dialog.Button.Title.Ask.ForPK" = "Ask to send ID"; "Security.Dialog.Button.Title.Send.PK" = "Send own public key"; +"ReadView.SecurityBriefing.Title" = "Security Briefing"; +"ReadView.SecurityBriefing.Conf.Title" = "Who can read the email?"; +"ReadView.SecurityBriefing.Conf.Description" = "Deine Mails gehen durch verschiedene Hände: Deinem Mail-Provider, dem Mail-Provider der anderen Seite und vielleicht weitere Mail-Provider als Vermittler dazwischen. Außerdem transporieren dein Internet-Provider und andere auch andere Internet-Provider deine Mail."; +"ReadView.SecurityBriefing.Conf.State.Encrypted" = "Only you, the sender and receiver know the content of these mails."; +"ReadView.SecurityBriefing.Conf.State.Plain" = "Everyone can read the content"; +"ReadView.SecurityBriefing.Conf.State.TransportEnc" = "The involved email providers know the content. You, the sender and receivers know the content, too."; +"ReadView.SecurityBriefing.Conf.State.UnableToDecrypt" = "This is a confidential mail, but it could not be decrypted. If you can read this mail on other devices, you should synchronize them. If not, the sender might have made a mistake and you can ask the sender to send the mail again."; +"ReadView.SecurityBriefing.Conf.Problem.PrivacyPolicy" = "At least one involved email provider read the mail advertising as they say in their privicy policy."; +"ReadView.SecurityBriefing.Auth.Title" = "Who is the sender?"; +"ReadView.SecurityBriefing.Auth.State.UnSigned" = "we do not know if the sender address represents the real sender. Be aware that a fraud can impersonate the sender."; +"ReadView.SecurityBriefing.Auth.State.Signed" = "The senders of these mails have an ID and we have a genuine record about previous mails of them."; +"ReadView.SecurityBriefing.Auth.State.MissingPK" = "We can not verify the sender because sender's ID is missing. But after importing sender's ID we can verify the sender."; +"ReadView.SecurityBriefing.Auth.State.InvalidSignature" = "This mail has been manipulated! If you want to read it anyway, please be cautions."; +"ReadView.SecurityBriefing.Actions.Title" = "Improving the security"; +"ReadView.SecurityBriefing.Actions.Description" = "We can improve the security of this email and other emails in the future";