Skip to content
Open
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
2 changes: 1 addition & 1 deletion Package.swift
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ let package = Package(
name: "PerfectTurnstileMySQL",
targets: [],
dependencies: [
.Package(url: "https://github.com/SwiftORM/MySQL-StORM.git", majorVersion: 1, minor: 0),
.Package(url: "https://github.com/nawar/MySQL-StORM.git", majorVersion: 1, minor: 0),
.Package(url: "https://github.com/PerfectlySoft/Perfect-HTTPServer.git", majorVersion: 2, minor: 1),
.Package(url: "https://github.com/PerfectlySoft/Perfect-Mustache.git", majorVersion: 2, minor: 0),
.Package(url: "https://github.com/iamjono/SwiftString.git", majorVersion: 1, minor: 0),
Expand Down
29 changes: 23 additions & 6 deletions Sources/Account.swift
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,9 @@ open class AuthAccount : MySQLStORM, Account {

/// Stored Google ID when logging in with Google
public var googleID: String = ""

/// Stored LinkedIn ID when logging in with Google
public var linkedInID: String = ""

/// Optional first name
public var firstname: String = ""
Expand All @@ -40,10 +43,16 @@ open class AuthAccount : MySQLStORM, Account {

/// Internal container variable for the current Token object
public var internal_token: AccessTokenStore = AccessTokenStore()

/// The table to store the data

/// xmpp username
public var _xmpp_un: String = ""

/// xmpp password
public var _xmpp_pw: String = ""

/// The table to store the data
override open func table() -> String {
return "users"
return "people"
}

/// Shortcut to store the id
Expand All @@ -58,9 +67,12 @@ open class AuthAccount : MySQLStORM, Account {
password = this.data["password"] as? String ?? ""
facebookID = this.data["facebookID"] as? String ?? ""
googleID = this.data["googleID"] as? String ?? ""
linkedInID = this.data["linkedInID"] as? String ?? ""
firstname = this.data["firstname"] as? String ?? ""
lastname = this.data["lastname"] as? String ?? ""
email = this.data["email"] as? String ?? ""
_xmpp_un = this.data["xmpp_un"] as? String ?? ""
_xmpp_pw = this.data["xmpp_pw"] as? String ?? ""
}

/// Iterate through rows and set to object data
Expand Down Expand Up @@ -88,7 +100,14 @@ open class AuthAccount : MySQLStORM, Account {
func get(_ un: String, _ pw: String) throws -> AuthAccount {
let cursor = StORMCursor(limit: 1, offset: 0)
do {
try select(whereclause: "username = ?", params: [un], orderby: [], cursor: cursor)
let joins = StORMDataSourceJoin(table: "users",
onCondition: "people.uniqueID = users.people_uniqueID",
direction: .INNER)
try select(columns: ["people.username", "people.password",
"users.username as xmpp_un","users.password as xmpp_pw"],
whereclause: "people.username = ?", params: [un], orderby: [], cursor: cursor,
joins: [joins], having: [], groupBy: [])

if self.results.rows.count == 0 {
throw StORMError.noRecordFound
}
Expand Down Expand Up @@ -120,5 +139,3 @@ open class AuthAccount : MySQLStORM, Account {
}
}
}


103 changes: 98 additions & 5 deletions Sources/AuthHandlersJSON.swift
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,25 @@
//
//


import PerfectLib
import PerfectHTTP
import PerfectMustache
import StORM
import MySQL
import MySQLStORM
import Foundation

import TurnstilePerfect
import Turnstile
import TurnstileCrypto
import TurnstileWeb

#if os(Linux)
import SwiftGlibc
#else
import Darwin
#endif


/// public var that houses the Token object
public var tokenStore: AccessTokenStore?
Expand Down Expand Up @@ -55,6 +62,12 @@ public class AuthHandlersJSON {
resp["error"] = "none"
resp["login"] = "ok"
resp["token"] = token

if let authAccount = request.user.authDetails?.account as? AuthAccount {
resp["xmpp_un"] = authAccount._xmpp_un
resp["xmpp_pw"] = authAccount._xmpp_pw
}

} catch {
resp["error"] = "Invalid username or password"
}
Expand Down Expand Up @@ -94,17 +107,62 @@ public class AuthHandlersJSON {

do {
try request.user.register(credentials: credentials)


// if the registeration is good, register for the xmpp as well
if let authAccount = request.user.authDetails?.account as? AuthAccount {

// now register for the xmpp server using ejablibswiftCore.soberdctl
let res = try runProc(cmd: "ejabberdctl", args: ["register",username, "localhost", password])
Log.info(message: "Ejabberdctl result:\(res)")

// using the returned data, update the just created ejabberd user with
// foreign key of people_uniqueID

let server = MySQL()
let conn = server.connect(host: MySQLConnector.host , user: MySQLConnector.username, password: MySQLConnector.password, db: MySQLConnector.database, port: UInt32(MySQLConnector.port))

if conn {

let sql = "UPDATE users SET people_uniqueID = '\(authAccount.uniqueID)' WHERE username = '\(authAccount.username)'"
if server.query(statement: sql) {
Log.info(message: "Successfull update")
} else {
Log.warning(message: "Update issue")
}

defer { server.close() }

} else {
Log.warning(message: "Issue with opening:\(server.errorMessage())")
}
}

// login as you go and send the user the info
try request.user.login(credentials: credentials)

//register
resp["error"] = "none"
resp["login"] = "ok"
resp["token"] = response.request.user.authDetails?.sessionID

if let authAccount = request.user.authDetails?.account as? AuthAccount {
resp["xmpp_un"] = authAccount._xmpp_un
resp["xmpp_pw"] = authAccount._xmpp_pw
}

} catch let e as TurnstileError {
resp["error"] = e.description
} catch {
resp["error"] = "An unknown error occurred."
}
} catch let e as PerfectError {
if case .systemError(let (_,text)) = e {
Log.debug(message: text)
resp["error"] = text
}
resp["error"] = "An unknown error occurred. \(e.localizedDescription)"
} catch let e {
Log.debug(message: e.localizedDescription)
resp["error"] = e.localizedDescription
}

do {
try response.setBody(json: resp)
} catch {
Expand All @@ -127,6 +185,13 @@ public class AuthHandlersJSON {
response.setHeader(.contentType, value: "application/json")
var resp = [String: String]()

// Destroy the token and clean the token store
if let headerValue = request.header(HTTPRequestHeader.Name.authorization) {
if let res = tokenStore?.destroy(headerValue), !res {
Log.warning(message: "Couldn't delete token from the store")
}
}

request.user.logout()
resp["error"] = "none"
resp["logout"] = "complete"
Expand Down Expand Up @@ -258,5 +323,33 @@ public class AuthHandlersJSON {
}
response.completed()
}

private static func runProc(cmd: String, args: [String], read: Bool = false) throws -> String? {
let envs = [("PATH", "/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin")]
let proc = try SysProcess(cmd, args: args, env: envs)
var ret: String?
if read {
var ary = [UInt8]()
while true {
do {
guard let s = try proc.stdout?.readSomeBytes(count: 1024), s.count > 0 else {
break
}
ary.append(contentsOf: s)
} catch PerfectLib.PerfectError.fileError(let code, _) {
if code != EINTR {
break
}
}
}
ret = UTF8Encoding.encode(bytes: ary)
}
let res = try proc.wait(hang: true)
if res != 0 {
let s = try proc.stderr?.readString()
throw PerfectError.systemError(Int32(res), s!)
}
return ret
}

}
14 changes: 14 additions & 0 deletions Sources/Tokens.swift
Original file line number Diff line number Diff line change
Expand Up @@ -91,4 +91,18 @@ open class AccessTokenStore : MySQLStORM {
}
return token
}

/// Destroy the token, after logout, by deleting it from token store
public func destroy(_ headerValue: String) -> Bool {

guard let range = headerValue.range(of: "Bearer ") else { return false }

let token = headerValue.substring(from: range.upperBound)
do {
try delete(token, idName: "token")
} catch {
print(error)
}
return true
}
}