--[[
 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'
local config = require 'lib/config'

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
    
    local oauth_domain = ""
    if config.oauth_fields and config.oauth_fields[get.key] then
        for k, v in pairs(config.oauth_fields[get.key]) do
            r.args = r.args .. ("&%s=%s"):format(k,v)
        end
        if config.oauth_fields[get.key].oauth_token then
            get.oauth_token = config.oauth_fields[get.key].oauth_token
        end
    end
    
    -- Persona callback
    if get.mode and get.mode == "persona" then
        oauth_domain = "verifier.login.persona.org"
        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
        oauth_domain = "www.googleapis.com"
        local result = https.request("https://www.googleapis.com/oauth2/v3/tokeninfo?id_token=" .. r:escape(get.id_token))
        valid, json = pcall(function() return JSON.decode(result) end)
        
    -- GitHub Auth callback
    elseif get.oauth_token and get.key == 'github' then
        local result = https.request(get.oauth_token, r.args)
        local token = result:match("(access_token=[a-f0-9]+)")
        if token then
            local result = https.request("https://api.github.com/user/emails?" .. token)
            valid, json = pcall(function() return JSON.decode(result) end)
            if valid and json then
                json = json[1]
            end
        end
        
    -- Generic callback (like ASF Oauth2)
    elseif get.state and get.code and get.oauth_token then
        oauth_domain = get.oauth_token:match("https?://(.-)/")
        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
            
            -- if the oauth provider can set admin status, do so if needed
            local authority = false
            for k, v in pairs(config.admin_oauth or {}) do
                if r.strcmp_match(oauth_domain, v) then
                    authority = true
                    break
                end
            end
            if authority then
                usr.admin = admin
            end
            
            usr.email = eml
            usr.uid = json.uid
            usr.oauth_used = oauth_domain
            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) 