<commit_before>
#include "rs-serve.h"

static int match_scope(struct rs_scope *scope, evhtp_request_t *req) {
  const char *file_path = req->uri->path->match_end;
  log_debug("checking scope, name: %s, write: %d", scope->name, scope->write);
  // check path
  if( (strcmp(scope->name, "") == 0) || // root scope
      (strncmp(file_path + 1, scope->name, scope->len) == 0) ) { // other scope
    log_debug("path authorized");
    // check mode
    if(scope->write ||
       req->method == htp_method_GET ||
       req->method == htp_method_HEAD) {
       log_debug("mode authorized");
      return 0;
    }
  }
  return -1;
}

int authorize_request(evhtp_request_t *req) {
  char *username = req->uri->path->match_start;
  const char *auth_header = evhtp_header_find(req->headers_in, "Authorization");
  log_debug("Got auth header: %s", auth_header);
  const char *token;
  if(auth_header) {
    if(strncmp(auth_header, "Bearer ", 7) == 0) {
      token = auth_header + 7;
      log_debug("Got token: %s", token);
      struct rs_authorization *auth = lookup_authorization(username, token);
      if(auth != NULL) {
        log_debug("Got authorization (%p, scopes: %p)", auth, auth->scopes);
        struct rs_scope *scope;
        for(scope = auth->scopes; scope != NULL; scope = scope->next) {
          log_debug("Compare scope %s", scope->name);
          if(match_scope(scope, req) == 0) {
            return 0;
          }
        }
      }
    }
  }
  // TODO: handle /public/ requests.
  return -1;
}<commit_msg>handle "/public/" correctly in authorize_request()<commit_after>
#include "rs-serve.h"

#define IS_READ(r) (r->method == htp_method_GET || r->method == htp_method_HEAD)

static int match_scope(struct rs_scope *scope, evhtp_request_t *req) {
  const char *file_path = req->uri->path->match_end;
  log_debug("checking scope, name: %s, write: %d", scope->name, scope->write);
  // check path
  if( (strcmp(scope->name, "") == 0) || // root scope
      (strncmp(file_path + 1, scope->name, scope->len) == 0) ) { // other scope
    log_debug("path authorized");
    // check mode
    if(scope->write || IS_READ(req)) {
      log_debug("mode authorized");
      return 0;
    }
  }
  return -1;
}

int authorize_request(evhtp_request_t *req) {
  char *username = req->uri->path->match_start;
  const char *auth_header = evhtp_header_find(req->headers_in, "Authorization");
  log_debug("Got auth header: %s", auth_header);
  const char *token;
  if(auth_header) {
    if(strncmp(auth_header, "Bearer ", 7) == 0) {
      token = auth_header + 7;
      log_debug("Got token: %s", token);
      struct rs_authorization *auth = lookup_authorization(username, token);
      if(auth != NULL) {
        log_debug("Got authorization (%p, scopes: %p)", auth, auth->scopes);
        struct rs_scope *scope;
        for(scope = auth->scopes; scope != NULL; scope = scope->next) {
          log_debug("Compare scope %s", scope->name);
          if(match_scope(scope, req) == 0) {
            return 0;
          }
        }
      }
    }
  }
  // special case: public reads on files (not directories) are allowed.
  // nothing else though.
  if(strncmp(req->uri->path->match_end, "/public/", 8) == 0 && IS_READ(req) &&
     req->uri->path->file != NULL) {
    return 0;
  }
  return -1;
}
{'fraction_non_alphanumeric': 0.16200607902735562, 'fraction_numerical': 0.007598784194528876, 'mean_word_length': 2.9698431845597106, 'pattern_counts': {'":': 0, '<': 3, '<?xml version=': 0, '>': 47, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3054332', 'n_tokens_mistral': 1152, 'n_tokens_neox': 1117, 'n_words': 265}