Send HTTP error code depending error that append.
Change message content with something more user friendly
This commit is contained in:
parent
4a4bcb418b
commit
af21b300ea
25
README.md
25
README.md
|
|
@ -16,7 +16,8 @@ go get git.kingpenguin.tk/chteufleur/HTTPAuthentificationOverXMPP.git
|
|||
```
|
||||
|
||||
### Configure
|
||||
Configure the gateway by editing the ``httpAuth.cfg`` file in order to give all XMPP component and HTTP server informations. An example of the config file can be found in [the repos](https://git.kingpenguin.tk/chteufleur/HTTPAuthentificationOverXMPP/src/master/httpAuth.cfg).
|
||||
Configure the gateway by editing the ``httpAuth.cfg`` file in order to give all XMPP component and HTTP server informations.
|
||||
An example of the config file can be found in [the repos](https://git.kingpenguin.tk/chteufleur/HTTPAuthentificationOverXMPP/src/master/httpAuth.cfg).
|
||||
|
||||
XMPP
|
||||
* xmpp_server_address : Component server address connection (default: 127.0.0.1)
|
||||
|
|
@ -35,18 +36,32 @@ HTTP
|
|||
|
||||
### Utilization
|
||||
To ask authorization, just send an HTTP request to the path ``/auth`` with parameters:
|
||||
* jid : JID of the user (user@host/resource or user@host)
|
||||
* domain : Domain you want to access
|
||||
* method : Method you access the domain
|
||||
* __jid__ : JID of the user (user@host/resource or user@host)
|
||||
* __domain__ : Domain you want to access
|
||||
* __method__ : Method you access the domain
|
||||
* transaction_id : Transaction identifier (auto generated if not provide)
|
||||
* timeout : Timeout of the request in second (default : 60, max : 300)
|
||||
|
||||
__Bold parameters__ are mandatory.
|
||||
|
||||
Example:
|
||||
```
|
||||
GET /auth?jid=user%40host%2fresource&domain=example.org&method=POST&transaction_id=WhatEverYouWant&timeout=120 HTTP/1.1
|
||||
```
|
||||
|
||||
This will send a request to the given JID. If the user accept, the server will return HTTP code 200, otherwise it will return HTTP code 401.
|
||||
This will send a request to the given JID, then return HTTP code depending on what appended.
|
||||
* 200 : User accept the request
|
||||
* 401 : User deny the request
|
||||
* 504 : User do not provide an answer (timeout)
|
||||
* 520 : Unknown error append
|
||||
* 523 : Server is unreachable
|
||||
|
||||
|
||||
If the provided JID contain a resource, it will try to send an ``iq`` stanza.
|
||||
If the answer to this ``iq`` is a ``feature-not-implemented`` or ``service-unavailable`` error,
|
||||
it will automatically send a ``message`` stanza. Unfortunately, if a ``message`` stanza is used,
|
||||
their is probably no way to get the error if the JID does not exist or is unreachable.
|
||||
|
||||
|
||||
A demo version can be found at [auth.xmpp.kingpenguin.tk](http://auth.xmpp.kingpenguin.tk) for test purpose only.
|
||||
|
||||
|
|
|
|||
19
http/http.go
19
http/http.go
|
|
@ -27,6 +27,9 @@ const (
|
|||
|
||||
RETURN_VALUE_OK = "OK"
|
||||
RETURN_VALUE_NOK = "NOK"
|
||||
|
||||
StatusUnknownError = 520
|
||||
StatusUnreachable = 523
|
||||
)
|
||||
|
||||
var (
|
||||
|
|
@ -62,7 +65,7 @@ func authHandler(w http.ResponseWriter, r *http.Request) {
|
|||
timeout = MaxTimeout
|
||||
}
|
||||
|
||||
chanAnswer := make(chan bool)
|
||||
chanAnswer := make(chan string)
|
||||
|
||||
ChanRequest <- jid
|
||||
ChanRequest <- method
|
||||
|
|
@ -72,13 +75,21 @@ func authHandler(w http.ResponseWriter, r *http.Request) {
|
|||
|
||||
select {
|
||||
case answer := <-chanAnswer:
|
||||
if answer {
|
||||
switch answer {
|
||||
case xmpp.REPLY_OK:
|
||||
w.WriteHeader(http.StatusOK)
|
||||
} else {
|
||||
|
||||
case xmpp.REPLY_DENY:
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
|
||||
case xmpp.REPLY_UNREACHABLE:
|
||||
w.WriteHeader(StatusUnreachable)
|
||||
|
||||
default:
|
||||
w.WriteHeader(StatusUnknownError)
|
||||
}
|
||||
case <-time.After(time.Duration(timeout) * time.Second):
|
||||
w.WriteHeader(http.StatusUnauthorized)
|
||||
w.WriteHeader(http.StatusGatewayTimeout)
|
||||
delete(xmpp.WaitMessageAnswers, transaction)
|
||||
}
|
||||
}
|
||||
|
|
|
|||
7
main.go
7
main.go
|
|
@ -76,13 +76,8 @@ func request() {
|
|||
client.Domain = getChanString(http.ChanRequest)
|
||||
client.Transaction = getChanString(http.ChanRequest)
|
||||
|
||||
if client.Transaction == "" {
|
||||
// Random transaction ID generation
|
||||
client.Transaction = xmpp.SessionID()
|
||||
}
|
||||
|
||||
chanResult := <-http.ChanRequest
|
||||
if v, ok := chanResult.(chan bool); ok {
|
||||
if v, ok := chanResult.(chan string); ok {
|
||||
client.ChanReply = v
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -10,6 +10,10 @@ import (
|
|||
|
||||
const (
|
||||
dictionary = "0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
|
||||
|
||||
REPLY_UNREACHABLE = "reply_unreachable"
|
||||
REPLY_DENY = "reply_deny"
|
||||
REPLY_OK = "reply_ok"
|
||||
)
|
||||
|
||||
type Client struct {
|
||||
|
|
@ -18,14 +22,20 @@ type Client struct {
|
|||
Domain string
|
||||
Transaction string
|
||||
|
||||
ChanReply chan bool
|
||||
ChanReply chan string
|
||||
}
|
||||
|
||||
func (client *Client) QueryClient() {
|
||||
log.Printf("%sQuery JID %s", LogInfo, client.JID)
|
||||
isAutoGeneratedTranctionID := false
|
||||
if client.Transaction == "" {
|
||||
// Random transaction ID generation
|
||||
client.Transaction = xmpp.SessionID()
|
||||
isAutoGeneratedTranctionID = true
|
||||
}
|
||||
clientJID, _ := xmpp.ParseJID(client.JID)
|
||||
if clientJID.Resource == "" {
|
||||
client.askViaMessage()
|
||||
client.askViaMessage(isAutoGeneratedTranctionID)
|
||||
} else {
|
||||
client.askViaIQ()
|
||||
}
|
||||
|
|
@ -41,16 +51,20 @@ func (client *Client) askViaIQ() {
|
|||
comp.Out <- m
|
||||
}
|
||||
|
||||
func (client *Client) askViaMessage() {
|
||||
m := xmpp.Message{From: jid.Domain, To: client.JID, Type: "normal"}
|
||||
func (client *Client) askViaMessage(isAutoGeneratedTranctionID bool) {
|
||||
m := xmpp.Message{From: jid.Domain, To: client.JID, Type: xmpp.MessageTypeNormal}
|
||||
|
||||
m.Thread = xmpp.SessionID()
|
||||
m.Body = "HTTP (" + client.Method + ") Authorization for " + client.Domain + " (id: " + client.Transaction + ")."
|
||||
m.Body += "\nReply to this message to confirm the request."
|
||||
m.Body += "\nIf your client doesn't support that functionnality, please send back the identifier to confirm the request."
|
||||
m.Body = client.Domain + " (with method " + client.Method + ") need to validate your identity, do you agree ?"
|
||||
m.Body += "\nValidation code : " + client.Transaction
|
||||
if !isAutoGeneratedTranctionID {
|
||||
// Send only if the transaction ID is not autogenerated
|
||||
m.Body += "\nPlease check that this code is the same as on " + client.Domain
|
||||
}
|
||||
m.Body += "\n\nIf your client doesn't support that functionnality, please send back the validation code to confirm the request."
|
||||
m.Confir = &xmpp.Confirm{Id: client.Transaction, Method: client.Method, URL: client.Domain}
|
||||
|
||||
log.Printf("%sSenp message %v", LogInfo, m)
|
||||
log.Printf("%sSend message %v", LogInfo, m)
|
||||
WaitMessageAnswers[client.Transaction] = client
|
||||
comp.Out <- m
|
||||
}
|
||||
|
|
|
|||
23
xmpp/xmpp.go
23
xmpp/xmpp.go
|
|
@ -116,17 +116,32 @@ func processConfirm(x interface{}, client *Client) {
|
|||
|
||||
if client != nil {
|
||||
if mesOK && mes.Error != nil {
|
||||
client.ChanReply <- false
|
||||
// Message error
|
||||
errCondition := mes.Error.Condition()
|
||||
if errCondition == xmpp.ServiceUnavailable {
|
||||
// unreachable
|
||||
client.ChanReply <- REPLY_UNREACHABLE
|
||||
} else {
|
||||
client.ChanReply <- REPLY_DENY
|
||||
}
|
||||
|
||||
} else if iqOK && iq.Error != nil {
|
||||
if iq.Error.Condition().Local == "service-unavailable" {
|
||||
// IQ error
|
||||
errCondition := iq.Error.Condition()
|
||||
if errCondition == xmpp.ServiceUnavailable || errCondition == xmpp.FeatureNotImplemented {
|
||||
// send by message if client doesn't implemente it
|
||||
client.JID = strings.SplitN(client.JID, "/", 2)[0]
|
||||
go client.QueryClient()
|
||||
} else if errCondition == xmpp.RemoteServerNotFound {
|
||||
// unreachable
|
||||
client.ChanReply <- REPLY_UNREACHABLE
|
||||
} else {
|
||||
client.ChanReply <- false
|
||||
client.ChanReply <- REPLY_DENY
|
||||
}
|
||||
|
||||
} else {
|
||||
client.ChanReply <- true
|
||||
// No error
|
||||
client.ChanReply <- REPLY_OK
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue