| package apidVerifyApiKey |
| |
| import ( |
| "database/sql" |
| "encoding/json" |
| "fmt" |
| "net/http" |
| ) |
| |
| type sucResponseDetail struct { |
| Key string `json:"key"` |
| ExpiresAt int64 `json:"expiresAt"` |
| IssuedAt int64 `json:"issuedAt"` |
| Status string `json:"status"` |
| RedirectionURIs string `json:"redirectionURIs"` |
| DeveloperAppId string `json:"developerId"` |
| DeveloperAppNam string `json:"developerAppName"` |
| } |
| |
| type errResultDetail struct { |
| ErrorCode string `json:"errorCode"` |
| Reason string `json:"reason"` |
| } |
| |
| type kmsResponseSuccess struct { |
| RspInfo sucResponseDetail `json:"result"` |
| Type string `json:"type"` |
| } |
| |
| type kmsResponseFail struct { |
| ErrInfo errResultDetail `json:"result"` |
| Type string `json:"type"` |
| } |
| |
| // handle client API |
| func handleRequest(w http.ResponseWriter, r *http.Request) { |
| if r.Method != "POST" { |
| return |
| } |
| |
| err := r.ParseForm() |
| if err != nil { |
| w.WriteHeader(http.StatusBadRequest) |
| w.Write([]byte("Unable to parse form")) |
| } |
| |
| f := r.Form |
| elems := []string{"action", "key", "uriPath", "organization", "environment"} |
| for _, elem := range elems { |
| if f.Get(elem) == "" { |
| w.WriteHeader(http.StatusBadRequest) |
| w.Write([]byte(fmt.Sprintf("Missing element: %s", elem))) |
| } |
| } |
| |
| org := f.Get("organization") |
| key := f.Get("key") |
| path := f.Get("uriPath") |
| env := f.Get("environment") |
| action := f.Get("action") |
| |
| b, err := verifyAPIKey(key, path, env, org, action) |
| if err != nil { |
| log.Errorf("error: %s", err) |
| w.WriteHeader(http.StatusInternalServerError) |
| w.Write([]byte(err.Error())) |
| return |
| } |
| |
| log.Debugf("handleVerifyAPIKey result %s", b) |
| w.Write(b) |
| } |
| |
| // todo: The following was basically just copied from old APID - needs review. |
| |
| // returns []byte to be written to client |
| func verifyAPIKey(key, path, env, org, action string) ([]byte, error) { |
| var ( |
| sSql string |
| status, redirectionURIs string |
| developerAppName, developerId string |
| resName, resEnv, reason, errorCode string |
| issuedAt, expiresAt int64 |
| ) |
| |
| if key == "" || org == "" || path == "" || env == "" || action != "verify" { |
| log.Error("Input params Invalid/Incomplete") |
| reason = "Input Params Incomplete or Invalid" |
| errorCode = "INCORRECT_USER_INPUT" |
| return errorResponse(reason, errorCode) |
| } |
| |
| db, err := data.DB() |
| if err != nil { |
| log.Errorf("Unable to access DB") |
| reason = err.Error() |
| errorCode = "SEARCH_INTERNAL_ERROR" |
| return errorResponse(reason, errorCode) |
| } |
| |
| /* |
| * NOTE: that here c.expired_at has been commented out because it is not |
| * kept track of by Cassandra (hence always defaults to -1). FIXME |
| */ |
| |
| sSql = "SELECT ap.res_names, ap.env, c.issued_at, c.status, a.cback_url, d.username, d.id FROM APP_CREDENTIAL AS c INNER JOIN APP AS a ON c.app_id = a.id INNER JOIN DEVELOPER AS d ON a.dev_id = d.id INNER JOIN APP_AND_API_PRODUCT_MAPPER as mp ON mp.app_cred_id = c.id INNER JOIN API_PRODUCT as ap ON ap.id = mp.api_prdt_id WHERE (UPPER(d.sts) = 'ACTIVE' AND mp.api_prdt_id = ap.id AND mp.app_id = a.id AND mp.app_cred_id = c.id AND UPPER(mp.api_prdt_status) = 'APPROVED' AND UPPER(a.status) = 'APPROVED' AND UPPER(c.status) = 'APPROVED' AND c.id = '" + key + "' AND c.org = '" + org + "');" |
| |
| err = db.QueryRow(sSql).Scan(&resName, &resEnv, &issuedAt, &status, |
| &redirectionURIs, &developerAppName, &developerId) |
| expiresAt = -1 |
| switch { |
| case err == sql.ErrNoRows: |
| reason = "API Key verify failed for (" + key + ", " + org + ", " + path + ", " + env + ")" |
| errorCode = "REQ_ENTRY_NOT_FOUND" |
| return errorResponse(reason, errorCode) |
| |
| case err != nil: |
| reason = err.Error() |
| errorCode = "SEARCH_INTERNAL_ERROR" |
| return errorResponse(reason, errorCode) |
| } |
| |
| /* |
| * Perform all validations related to the Query made with the data |
| * we just retrieved |
| */ |
| result := validatePath(resName, path) |
| if result == false { |
| reason = "Path Validation Failed (" + resName + " vs " + path + ")" |
| errorCode = "PATH_VALIDATION_FAILED" |
| return errorResponse(reason, errorCode) |
| |
| } |
| |
| /* Verify if the ENV matches */ |
| result = validateEnv(resEnv, env) |
| if result == false { |
| reason = "ENV Validation Failed (" + resEnv + " vs " + env + ")" |
| errorCode = "ENV_VALIDATION_FAILED" |
| return errorResponse(reason, errorCode) |
| } |
| |
| resp := kmsResponseSuccess{ |
| Type: "APIKeyContext", |
| RspInfo: sucResponseDetail{ |
| Key: key, |
| ExpiresAt: expiresAt, |
| IssuedAt: issuedAt, |
| Status: status, |
| RedirectionURIs: redirectionURIs, |
| DeveloperAppId: developerId, |
| DeveloperAppNam: developerAppName}, |
| } |
| return json.Marshal(resp) |
| } |
| |
| func errorResponse(reason, errorCode string) ([]byte, error) { |
| |
| log.Error(reason) |
| resp := kmsResponseFail{ |
| Type: "ErrorResult", |
| ErrInfo: errResultDetail{ |
| Reason: reason, |
| ErrorCode: errorCode}, |
| } |
| return json.Marshal(resp) |
| } |