8
8
"crypto/tls"
9
9
"encoding/json"
10
10
"net/http"
11
+ "slices"
11
12
"strings"
12
13
13
14
"github.com/OCP-on-NERC/prom-keycloak-proxy/errors"
@@ -66,6 +67,27 @@ func Protect(gocloakClient *gocloak.GoCloak, authRealm string, authClientId stri
66
67
return
67
68
}
68
69
70
+ userInfo , err := gocloakClient .GetUserInfo (context .Background (), accessToken , authRealm )
71
+ if err != nil {
72
+ log .Warn ().
73
+ Int ("status" , 401 ).
74
+ Str ("method" , r .Method ).
75
+ Str ("path" , r .RequestURI ).
76
+ Str ("ip" , r .RemoteAddr ).
77
+ Str ("client-id" , authClientId ).
78
+ Str ("query" , query ).
79
+ Msg ("Unauthorized" )
80
+
81
+ w .WriteHeader (401 )
82
+ json .NewEncoder (w ).Encode (errors .BadRequestError (err .Error ()))
83
+ return
84
+ }
85
+ username := * userInfo .PreferredUsername
86
+ var userClientId string = ""
87
+ if strings .Contains (username , "service-account-" ) {
88
+ userClientId = strings .ReplaceAll (username , "service-account-" , "" )
89
+ }
90
+
69
91
isTokenValid := * rptResult .Active
70
92
71
93
if ! isTokenValid {
@@ -74,7 +96,8 @@ func Protect(gocloakClient *gocloak.GoCloak, authRealm string, authClientId stri
74
96
Str ("method" , r .Method ).
75
97
Str ("path" , r .RequestURI ).
76
98
Str ("ip" , r .RemoteAddr ).
77
- Str ("client-id" , authClientId ).
99
+ Str ("username" , username ).
100
+ Str ("client-id" , userClientId ).
78
101
Str ("query" , query ).
79
102
Msg ("Unauthorized" )
80
103
@@ -84,7 +107,7 @@ func Protect(gocloakClient *gocloak.GoCloak, authRealm string, authClientId stri
84
107
}
85
108
86
109
queryValues := r .URL .Query ()
87
- queryValuesForAuth := queries .ParseAuthorizations (queryValues )
110
+ queryValuesForAuth , keys , values := queries .ParseAuthorizations (queryValues )
88
111
matchers := queryValuesForAuth [queries .QueryParam ]
89
112
var permissions []string
90
113
@@ -107,15 +130,16 @@ func Protect(gocloakClient *gocloak.GoCloak, authRealm string, authClientId stri
107
130
},
108
131
)
109
132
110
- if err != nil || len ( * rpp ) < 2 {
133
+ if err != nil {
111
134
log .Warn ().
112
135
Int ("status" , 403 ).
113
136
Str ("method" , r .Method ).
114
137
Str ("path" , r .RequestURI ).
115
138
Str ("ip" , r .RemoteAddr ).
116
- Str ("client-id" , authClientId ).
139
+ Str ("username" , username ).
140
+ Str ("client-id" , userClientId ).
117
141
Str ("query" , query ).
118
- Msg ("Forbidden" )
142
+ Msg (err . Error () )
119
143
120
144
w .WriteHeader (403 )
121
145
json .NewEncoder (w ).Encode (errors .UnauthorizedError ())
@@ -129,7 +153,8 @@ func Protect(gocloakClient *gocloak.GoCloak, authRealm string, authClientId stri
129
153
Str ("method" , r .Method ).
130
154
Str ("path" , r .RequestURI ).
131
155
Str ("ip" , r .RemoteAddr ).
132
- Str ("client-id" , authClientId ).
156
+ Str ("username" , username ).
157
+ Str ("client-id" , userClientId ).
133
158
Str ("query" , query ).
134
159
Msg ("Bad Request" )
135
160
@@ -138,15 +163,56 @@ func Protect(gocloakClient *gocloak.GoCloak, authRealm string, authClientId stri
138
163
return
139
164
}
140
165
141
- log .Info ().
142
- Int ("status" , 200 ).
143
- Str ("method" , r .Method ).
144
- Str ("path" , r .RequestURI ).
145
- Str ("ip" , r .RemoteAddr ).
146
- Str ("client-id" , authClientId ).
147
- Str ("query" , query ).
148
- RawJSON ("permissions" , out ).
149
- Msg ("OK" )
166
+ var final_result bool = true
167
+ var unauthorized_key string = ""
168
+ var unauthorized_value string = ""
169
+ for i , key := range keys {
170
+ value := values [i ]
171
+ current_result := false
172
+ for _ , permission := range * rpp {
173
+ if key == * permission .ResourceName && slices .Contains (* permission .Scopes , value ) {
174
+ current_result = true
175
+ break
176
+ }
177
+ }
178
+ if ! current_result {
179
+ final_result = false
180
+ unauthorized_key = key
181
+ unauthorized_value = value
182
+ break
183
+ }
184
+ }
185
+
186
+ if final_result {
187
+ log .Info ().
188
+ Int ("status" , 200 ).
189
+ Str ("method" , r .Method ).
190
+ Str ("path" , r .RequestURI ).
191
+ Str ("ip" , r .RemoteAddr ).
192
+ Str ("username" , username ).
193
+ Str ("client-id" , userClientId ).
194
+ Str ("query" , query ).
195
+ RawJSON ("permissions" , out ).
196
+ Msg ("OK" )
197
+ } else {
198
+ message := "You are not authorized to access the resource \" " + unauthorized_key + "\" with scope \" " + unauthorized_value + "\" "
199
+ log .Warn ().
200
+ Int ("status" , 403 ).
201
+ Str ("method" , r .Method ).
202
+ Str ("path" , r .RequestURI ).
203
+ Str ("ip" , r .RemoteAddr ).
204
+ Str ("username" , username ).
205
+ Str ("client-id" , userClientId ).
206
+ Str ("query" , query ).
207
+ Msg (message )
208
+
209
+ w .WriteHeader (403 )
210
+ json .NewEncoder (w ).Encode (errors.HttpError {
211
+ Code : 403 ,
212
+ Error : "Forbidden" ,
213
+ Message : message })
214
+ return
215
+ }
150
216
151
217
// Our middleware logic goes here...
152
218
next .ServeHTTP (w , r )
0 commit comments