--[[
 Licensed to the Apache Software Foundation (ASF) under one or more
 contributor license agreements.  See the NOTICE file distributed with
 this work for additional information regarding copyright ownership.
 The ASF licenses this file to You under the Apache License, Version 2.0
 (the "License"); you may not use this file except in compliance with
 the License.  You may obtain a copy of the License at

     http://www.apache.org/licenses/LICENSE-2.0

 Unless required by applicable law or agreed to in writing, software
 distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
]]--

-- This is oauth.lua - an oauth providing script for ponymail

local JSON = require 'cjson'
local http = require 'socket.http'
local elastic = require 'lib/elastic'
local https = require 'ssl.https'
local user = require 'lib/user'
local cross = require 'lib/cross'

function handle(r)
    r.content_type = "application/json"
    local get = r:parseargs()
    local post = r:parsebody()
    local valid, json
    local scheme = "https"
    if r.port == 80 then
        scheme = "http"
    end
    
    -- Persona callback
    if get.mode and get.mode == "persona" then
        local result = https.request("https://verifier.login.persona.org/verify", ("assertion=%s&audience=%s://%s:%u/"):format(post.assertion, scheme, r.hostname, r.port))
        r:err(("assertion=%s&audience=%s://ponymail:443/"):format(post.assertion, scheme))
        r:err(result)
        valid, json = pcall(function() return JSON.decode(result) end)
        
    -- Google Auth callback
    elseif get.oauth_token and get.oauth_token:match("^https://www.google") and get.id_token then
        local result = https.request("https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=" .. r:escape(get.id_token))
        r:err(result)
        r:err(r:escape(get.id_token))
        valid, json = pcall(function() return JSON.decode(result) end)
        
    -- Generic callback (like ASF Oauth2)
    elseif get.state and get.code and get.oauth_token then
        local result = https.request(get.oauth_token, r.args)
        valid, json = pcall(function() return JSON.decode(result) end)
    end
    
    -- Did we get something useful from the backend?
    if valid and json then
        local eml = json.email
        local fname = json.fullname or json.name or json.email
        local admin = json.isMember
        
        -- If we got an email and a name, log in the user and set cookie etc
        if eml and fname then
            local cid = json.uid or json.email
            -- Does the user exist already?
            local oaccount = user.get(r, cid)
            local usr = {}
            if oaccount then
                usr.preferences = oaccount.preferences
            else
                usr.preferences = {}
            end
            usr.gauth = get.id_token
            usr.fullname = fname
            usr.admin = admin
            usr.email = eml
            usr.uid = json.uid
            user.update(r, cid, usr)
            r:puts[[{"okay": true, "msg": "Logged in successfully!"}]]
        
        -- didn't get email or name, bork!
        else
            r:puts[[{"okay": false, "msg": "Erroneous or missing response from backend!"}]]
        end
    -- Backend borked, let the user know
    else
        r:puts[[{"okay": false, "msg": "Invalid oauth response!"}]]
    end
    return cross.OK
end

cross.start(handle)