Skip to content
This repository has been archived by the owner on Oct 4, 2024. It is now read-only.

Commit

Permalink
Merge pull request #89 from mytiki/feat/Implemment-Google-OAuth-logic
Browse files Browse the repository at this point in the history
Feat/implemment google o auth logic
  • Loading branch information
ricardobrg authored Apr 26, 2024
2 parents 5d3e66d + 8045ab3 commit b44677e
Show file tree
Hide file tree
Showing 18 changed files with 734 additions and 53 deletions.
52 changes: 4 additions & 48 deletions .github/workflows/codeql.yml
Original file line number Diff line number Diff line change
@@ -1,14 +1,3 @@
# For most projects, this workflow file will not need changing; you simply need
# to commit it to your repository.
#
# You may wish to alter this file to override the set of languages analyzed,
# or to provide custom queries or build logic.
#
# ******** NOTE ********
# We have attempted to detect the languages in your repository. Please check
# the `language` matrix defined below to confirm you have the correct set of
# supported CodeQL languages.
#
name: "CodeQL"

on:
Expand All @@ -22,67 +11,34 @@ on:
jobs:
analyze:
name: Analyze (${{ matrix.language }})
# Runner size impacts CodeQL analysis time. To learn more, please see:
# - https://gh.io/recommended-hardware-resources-for-running-codeql
# - https://gh.io/supported-runners-and-hardware-resources
# - https://gh.io/using-larger-runners (GitHub.com only)
# Consider using larger runners or machines with greater resources for possible analysis time improvements.
runs-on: ${{ (matrix.language == 'swift' && 'macos-latest') || 'ubuntu-latest' }}
timeout-minutes: ${{ (matrix.language == 'swift' && 120) || 360 }}
permissions:
# required for all workflows
security-events: write

# required to fetch internal or private CodeQL packs
packages: read

# only required for workflows in private repositories
actions: read
contents: read

strategy:
fail-fast: false
matrix:
language: ['swift']
# CodeQL supports the following values keywords for 'language': 'c-cpp', 'csharp', 'go', 'java-kotlin', 'javascript-typescript', 'python', 'ruby', 'swift'
# Use `c-cpp` to analyze code written in C, C++ or both
# Use 'java-kotlin' to analyze code written in Java, Kotlin or both
# Use 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
# To learn more about changing the languages that are analyzed or customizing the build mode for your analysis,
# see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/customizing-your-advanced-setup-for-code-scanning.
# If you are analyzing a compiled language, you can modify the 'build-mode' for that language to customize how
# your codebase is analyzed, see https://docs.github.com/en/code-security/code-scanning/creating-an-advanced-setup-for-code-scanning/codeql-code-scanning-for-compiled-languages
build-mode: ['manual']
steps:
- name: Checkout repository
uses: actions/checkout@v4

# Initializes the CodeQL tools for scanning.
- name: Initialize CodeQL
uses: github/codeql-action/init@v3
with:
languages: ${{ matrix.language }}
build-mode: ${{ matrix.build-mode }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.

# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality

# If the analyze step fails for one of the languages you are analyzing with
# "We were unable to automatically build your code", modify the matrix above
# to set the build mode to "manual" for that language. Then modify this step
# to build your code.
# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
- if: matrix.build-mode == 'manual'
run: |
echo 'If you are using a "manual" build mode for one or more of the' \
'languages you are analyzing, replace this with the commands to build' \
'your code, for example:'
echo ' make bootstrap'
echo ' make release'
exit 1
cd Example
pod install --repo-update
xcodebuild clean build CODE_SIGN_IDENTITY="" CODE_SIGNING_REQUIRED=NO -workspace TikiClient.xcworkspace -scheme TikiClient-Example -sdk iphonesimulator -destination 'platform=iOS Simulator,name=iPhone 14'
- name: Perform CodeQL Analysis
uses: github/codeql-action/analyze@v3
Expand Down
2 changes: 1 addition & 1 deletion Example/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -29,4 +29,4 @@ SPEC CHECKSUMS:

PODFILE CHECKSUM: 96d93e7c36e6d9cd116be19ddc3938e717dc0264

COCOAPODS: 1.14.3
COCOAPODS: 1.15.2
6 changes: 3 additions & 3 deletions Example/TikiClient.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -215,7 +215,7 @@
TargetAttributes = {
607FACCF1AFB9204008FA782 = {
CreatedOnToolsVersion = 6.3.1;
DevelopmentTeam = BKX7BJ2Q77;
DevelopmentTeam = JC63RM5U2M;
LastSwiftMigration = 0900;
};
88E1B7C42B926458005429F1 = {
Expand Down Expand Up @@ -513,7 +513,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = "$(inherited)";
DEVELOPMENT_TEAM = BKX7BJ2Q77;
DEVELOPMENT_TEAM = JC63RM5U2M;
INFOPLIST_FILE = TikiClient/Info.plist;
INFOPLIST_KEY_NSCameraUsageDescription = "The app need the camera permision";
INFOPLIST_KEY_NSLocationAlwaysAndWhenInUseUsageDescription = "";
Expand All @@ -534,7 +534,7 @@
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_WARN_QUOTED_INCLUDE_IN_FRAMEWORK_HEADER = "$(inherited)";
DEVELOPMENT_TEAM = BKX7BJ2Q77;
DEVELOPMENT_TEAM = JC63RM5U2M;
INFOPLIST_FILE = TikiClient/Info.plist;
INFOPLIST_KEY_NSCameraUsageDescription = "The app need the camera permision";
INFOPLIST_KEY_NSLocationAlwaysAndWhenInUseUsageDescription = "";
Expand Down
7 changes: 6 additions & 1 deletion Example/TikiClient/Example.swift
Original file line number Diff line number Diff line change
Expand Up @@ -123,7 +123,12 @@ struct Main: App {
}

}

Button("Login Google"){
TikiClient.loginEmail(clientID: "", completion: {print("login")})
}
Button("Token Google"){
Text(verbatim: TikiClient.verifyEmail(email: "").auth)
}
}
}
}
Expand Down
38 changes: 38 additions & 0 deletions TikiClient/Classes/Account/Account.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright (c) TIKI Inc.
* MIT license. See LICENSE file in the root directory.
*/

import Foundation
import SwiftUI

public struct Account: Hashable {

public var username: String
public var provider: AccountProvider
public var status: AccountStatus = .unverified

public static func toAccount(accounts: [AuthEmailTokenResponse]) -> [Account]{
var accoutsReturn: [Account] = []
for account in accounts {
accoutsReturn.append(Account(username: account.email, provider: AccountProvider.toAccountProvider(provider: account.provider) ?? AccountProvider.email(.google)))
}
return accoutsReturn
}

public func hash(into hasher: inout Hasher) {
hasher.combine(username)
hasher.combine(provider)
}

public static func == (lhs: Account, rhs: Account) -> Bool {
lhs.username == rhs.username &&
lhs.provider == rhs.provider
}

public init(username: String, provider: AccountProvider) {
self.username = username
self.provider = provider
self.status = EmailService.verifyStatus(email: username)
}
}
39 changes: 39 additions & 0 deletions TikiClient/Classes/Account/AccountProvider.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/*
* Copyright (c) TIKI Inc.
* MIT license. See LICENSE file in the root directory.
*/

import Foundation

public enum AccountProvider: Hashable{

case email(EmailProviderEnum)

func name() -> String{
var name = ""
switch(self){
case .email(let emailEnum) :
name = emailEnum.rawValue
}
return name.replacingOccurrences(of: "_", with: " ").capitalized
}

static func all() -> [AccountProvider] {
var providers: [AccountProvider] = []
EmailProviderEnum.allCases.forEach{ provider in
providers.append(.email(provider))
}
return providers
}

public static func toAccountProvider(provider: String) -> AccountProvider? {
if(provider == "GOOGLE"){
return email(.google)
}
if(provider == "OUTLOOK"){
return email(.outlook)
}else{
return email(.google)
}
}
}
139 changes: 139 additions & 0 deletions TikiClient/Classes/Account/AccountService.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,139 @@
/*
* Copyright (c) TIKI Inc.
* MIT license. See LICENSE file in the root directory.
*/

import Foundation

/// # AccountService
///
/// The `AccountService` class manages user accounts, providing methods for retrieving account
/// information, handling logins, and managing sessions.
///
/// ## Overview
///
/// The `AccountService` class is responsible for maintaining a collection of 3rd party accounts,
/// allowing for account retrieval based on providers and performing login and logout operations.
///
/// ## Example
///
/// To use the `AccountService` class, follow the example below:
///
/// ```swift
/// let accountService = AccountService()
///
/// // Retrieve all accounts
/// let allAccounts = accountService.accounts()
///
/// // Retrieve accounts for a specific provider
/// let facebookAccounts = accountService.accounts(for: .facebook)
///
/// // Retrieve available account providers
/// let availableProviders = accountService.providers()
public class AccountService{
// MARK: - Properties

/// An array containing the user accounts managed by the service.
var _accounts: [Account] = EmailService.accounts()

// MARK: - Public Methods

/// Retrieves all user accounts stored in the service.
///
/// - Returns: An array of user accounts.
func accounts() -> [Account] {
_accounts = EmailService.accounts()
return _accounts
}

/// Retrieves user accounts associated with a specific `AccountProvider`.
///
/// - Parameter provider: The account provider for which accounts should be retrieved.
/// - Returns: An array of user accounts for the specified provider.
func accounts(for provider: AccountProvider) -> [Account] {
accounts()
var accounts: [Account] = []
_accounts.forEach { acc in
if acc.provider == provider { accounts.append(acc) }
}
return accounts
}

/// Retrieves available `AccountProvider`, excluding those already associated with existing accounts.
///
/// - Returns: An array of available account providers.
func providers() -> [AccountProvider] {
var providers = AccountProvider.all()
_accounts.forEach { acc in
let index = providers.firstIndex(where: {
acc.provider.name() == $0.name()
})
}
return providers
}

/// Logs in a user by creating a new account or verifying an existing one.
///
/// - Parameters:
/// - username: The username for the account.
/// - password: The password for the account.
/// - provider: The account provider for the login.
/// - Returns: The logged-in user account.
/// - Throws: An error indicating issues with the login process, such as empty credentials or an already linked account.
func login(username: String, password: String, provider: AccountProvider) throws -> Account {
if username.isEmpty || password.isEmpty {
throw TikiError.error("Username and password should not be empty.")
} else {
if _accounts.first(where: {
$0.username == username &&
$0.provider == provider &&
$0.status == .verified
}) != nil {
throw TikiError.error("Account already linked.")
} else {
let account = Account(username: username, provider: provider)
var accountType: AccountType?
switch(provider){
case .email(let emailEnum):
accountType = .email(emailEnum)
break
}
_accounts.append(Account(username: username, provider: provider))

return account
}
}
}

/// Logs out a user by removing the associated account.
///
/// - Parameters:
/// - username: The username of the account to be logged out.
/// - provider: The account provider of the account to be logged out.
/// - Returns: The logged-out user account.
/// - Throws: An error indicating issues with the logout process, such as an empty username or an account not found.
func logout(username: String, provider: AccountProvider) -> Account {
if (username.isEmpty) {
print("Username should not be empty.")

}
let index = _accounts.firstIndex(where: {
$0.username == username &&
$0.provider == provider
})
if (index == nil) {
print("Account not found.")
}
let account = _accounts[index!]
var accountType: AccountType?
_accounts.remove(at: index!)
switch(provider){
case .email(let emailEnum):
accountType = .email(emailEnum)
EmailService.logout(email: username)
break
}
return account
}

}
11 changes: 11 additions & 0 deletions TikiClient/Classes/Account/AccountStatus.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* Copyright (c) TIKI Inc.
* MIT license. See LICENSE file in the root directory.
*/

import Foundation

public enum AccountStatus{
case verified
case unverified
}
11 changes: 11 additions & 0 deletions TikiClient/Classes/Account/AccountType.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
/*
* AccountTypeEnum Enum
* Copyright (c) TIKI Inc.
* MIT license. See LICENSE file in the root directory.
*/
import Foundation

/// An enumeration representing different types of user accounts.
public enum AccountType {
case email(EmailProviderEnum)
}
22 changes: 22 additions & 0 deletions TikiClient/Classes/Auth/AuthEmailTokenResponse.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
/*
* Copyright (c) TIKI Inc.
* MIT license. See LICENSE file in the root directory.
*/

import Foundation

public struct AuthEmailTokenResponse: Codable {
public let auth: String
public let refresh: String
public let provider: String
public let email: String
public let expiration: Date?

public init(auth: String, refresh: String, provider: String, email: String, expiration: Date?) {
self.auth = auth
self.refresh = refresh
self.provider = provider
self.email = email
self.expiration = expiration
}
}
Loading

0 comments on commit b44677e

Please sign in to comment.