1
package api
2

3
import (
4
    "net/http"
5
    "strings"
6
    "fmt"
7

8
    "github.com/gin-gonic/gin"
9

10
    "github.com/earaujoassis/space/utils"
11
    "github.com/earaujoassis/space/oauth"
12
    "github.com/earaujoassis/space/services"
13
    "github.com/earaujoassis/space/security"
14
)
15

16 1
func scheme(request *http.Request) string {
17 1
    if scheme := request.Header.Get("X-Forwarded-Proto"); scheme != "" {
18 0
        return scheme
19
    }
20 1
    if request.TLS == nil {
21 1
        return "http"
22
    }
23

24 0
    return "https"
25
}
26

27 1
func requiresConformance(c *gin.Context) {
28 1
    host := fmt.Sprintf("%s://%s", scheme(c.Request), c.Request.Host)
29 1
    correctXRequestedBy := c.Request.Header.Get("X-Requested-By") == "SpaceApi"
30
    // WARNING The Origin header attribute sometimes is not sent; we should not block these requests
31 1
    sameOriginPolicy := c.Request.Header.Get("Origin") == "" || host == c.Request.Header.Get("Origin")
32 1
    if correctXRequestedBy && sameOriginPolicy {
33 0
        c.Next()
34 1
    } else {
35 1
        c.JSON(http.StatusBadRequest, utils.H{
36 1
            "error": "missing X-Requested-By header attribute or Origin header does not comply with the same-origin policy",
37 1
        })
38 1
        c.Abort()
39
    }
40
}
41

42
// The following Authorization method is used by OAuth clients only
43 1
func clientBasicAuthorization(c *gin.Context) {
44 1
    authorizationBasic := strings.Replace(c.Request.Header.Get("Authorization"), "Basic ", "", 1)
45

46 1
    if !security.ValidBase64(authorizationBasic) {
47 1
        c.JSON(http.StatusBadRequest, utils.H{
48 1
            "error": "must use valid Authorization string",
49 1
        })
50 1
        c.Abort()
51 1
        return
52
    }
53

54 0
    client := oauth.ClientAuthentication(authorizationBasic)
55 0
    if client.ID == 0 {
56 0
        c.Header("WWW-Authenticate", fmt.Sprintf("Basic realm=\"%s\"", c.Request.RequestURI))
57 0
        c.JSON(http.StatusUnauthorized, utils.H{
58 0
            "error": oauth.AccessDenied,
59 0
        })
60 0
        c.Abort()
61 0
        return
62
    }
63 0
    c.Set("Client", client)
64 0
    c.Next()
65
}
66

67
// The following Authorization method is used by the web client, with an action token
68 1
func actionTokenBearerAuthorization(c *gin.Context) {
69 1
    authorizationBearer := strings.Replace(c.Request.Header.Get("Authorization"), "Bearer ", "", 1)
70

71 1
    if !security.ValidToken(authorizationBearer) {
72 1
        c.JSON(http.StatusBadRequest, utils.H{
73 1
            "error": "must use valid token string",
74 1
        })
75 1
        c.Abort()
76 1
        return
77
    }
78

79 0
    action := services.ActionAuthentication(authorizationBearer)
80 0
    if action.UUID == "" || !services.ActionGrantsReadAbility(action) {
81 0
        c.Header("WWW-Authenticate", fmt.Sprintf("Bearer realm=\"%s\"", c.Request.RequestURI))
82 0
        c.JSON(http.StatusUnauthorized, utils.H{
83 0
            "error": oauth.AccessDenied,
84 0
        })
85 0
        c.Abort()
86 0
        return
87
    }
88 0
    c.Set("Action", action)
89 0
    c.Next()
90
}
91

92
// The following Authorization method is used by the OAuth clients, with an OAuth session token
93 1
func oAuthTokenBearerAuthorization(c *gin.Context) {
94 1
    authorizationBearer := strings.Replace(c.Request.Header.Get("Authorization"), "Bearer ", "", 1)
95

96 1
    if !security.ValidToken(authorizationBearer) {
97 1
        c.JSON(http.StatusBadRequest, utils.H{
98 1
            "error": "must use valid token string",
99 1
        })
100 1
        c.Abort()
101 1
        return
102
    }
103

104 0
    session := oauth.AccessAuthentication(authorizationBearer)
105 0
    if session.ID == 0 || !services.SessionGrantsReadAbility(session) {
106 0
        c.Header("WWW-Authenticate", fmt.Sprintf("Bearer realm=\"%s\"", c.Request.RequestURI))
107 0
        c.JSON(http.StatusUnauthorized, utils.H{
108 0
            "error": oauth.AccessDenied,
109 0
        })
110 0
        c.Abort()
111 0
        return
112
    }
113 0
    c.Set("Session", session)
114 0
    c.Next()
115
}

Read our documentation on viewing source code .

Loading