Skip to content

Commit

Permalink
Merge branch 'development' of https://github.com/hotosm/fmtm into dev…
Browse files Browse the repository at this point in the history
…elopment
  • Loading branch information
spwoodcock committed Jan 18, 2024
2 parents ee8f1a8 + 1c5420b commit c5b1cad
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 57 deletions.
36 changes: 16 additions & 20 deletions src/backend/app/auth/roles.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@

from app.auth.osm import AuthUser, login_required
from app.db.database import get_db
from app.db.db_models import DbProject, DbUser, DbUserRoles
from app.db.db_models import DbProject, DbUser, DbUserRoles, organisation_managers
from app.models.enums import HTTPStatus, ProjectRole, UserRole
from app.projects.project_deps import get_project_by_id

Expand Down Expand Up @@ -70,36 +70,32 @@ async def org_admin(
user_data: AuthUser = Depends(login_required),
) -> AuthUser:
"""Organization admin with full permission for projects in an organization."""
if project and org_id:
log.error("Both org_id and project_id cannot be passed at the same time")
raise HTTPException(
status_code=HTTPStatus.BAD_REQUEST,
detail="Both org_id and project_id cannot be passed at the same time",
)

user_id = await get_uid(user_data)

if project:
org_id = db.query(DbProject).filter_by(id=project.id).first().organisation_id

org_admin = (
db.query(DbUserRoles)
.filter_by(user_id=user_id, role=ProjectRole.ORGANIZATION_ADMIN)
db.query(organisation_managers)
.filter_by(organisation_id=org_id, user_id=user_id)
.first()
)

if not org_admin:
log.error(f"User ID {user_id} is not an admin for any organization")
log.error(f"User ID {user_id} is not an admin for organization {org_id}")
raise HTTPException(
status_code=HTTPStatus.FORBIDDEN,
detail="User must be an organization admin",
detail="User is not organization admin",
)

matched_project = db.query(DbProject).filter_by(id=org_admin.project_id).first()
matched_org_id = matched_project.organisation_id

if (
org_id
and matched_org_id == org_id
or project
and matched_org_id == project.organisation_id
):
return user_data

log.error(f"User ID {user_id} is not an organization admin for id {org_id}")
raise HTTPException(
status_code=HTTPStatus.FORBIDDEN, detail="User is not an organization admin"
)
return user_data


async def validator(
Expand Down
2 changes: 0 additions & 2 deletions src/backend/app/models/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,15 +110,13 @@ class ProjectRole(IntEnum, Enum):
- FIELD_MANAGER = can invite mappers and organise people
- ASSOCIATE_PROJECT_MANAGER = helps the project manager, cannot delete project
- PROJECT_MANAGER = has all permissions to manage a project, including delete
- ORGANIZATION_ADMIN = has project manager permissions for all projects in org
"""

MAPPER = 0
VALIDATOR = 1
FIELD_MANAGER = 2
ASSOCIATE_PROJECT_MANAGER = 3
PROJECT_MANAGER = 4
ORGANIZATION_ADMIN = 5


class MappingLevel(IntEnum, Enum):
Expand Down
3 changes: 1 addition & 2 deletions src/backend/migrations/003-project-roles.sql
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,7 @@ CREATE TYPE public.projectrole as ENUM (
'VALIDATOR',
'FIELD_MANAGER',
'ASSOCIATE_PROJECT_MANAGER',
'PROJECT_MANAGER',
'ORGANIZATION_ADMIN'
'PROJECT_MANAGER'
);
ALTER TABLE public.user_roles ALTER COLUMN "role" TYPE VARCHAR(24);
ALTER TABLE public.user_roles ALTER COLUMN "role" TYPE public.projectrole USING role::public.projectrole;
Expand Down
3 changes: 1 addition & 2 deletions src/backend/migrations/init/fmtm_base_schema.sql
Original file line number Diff line number Diff line change
Expand Up @@ -140,8 +140,7 @@ CREATE TYPE public.projectrole as ENUM (
'VALIDATOR',
'FIELD_MANAGER',
'ASSOCIATE_PROJECT_MANAGER',
'PROJECT_MANAGER',
'ORGANIZATION_ADMIN'
'PROJECT_MANAGER'
);
ALTER TYPE public.projectrole OWNER TO fmtm;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,13 +133,13 @@ const ActivitiesPanel = ({ defaultTheme, state, params, map, view, mapDivPostion
return (
<div className="fmtm-w-full fmtm-px-2 sm:fmtm-px-0 fmtm-relative">
<div className="fmtm-sticky sm:fmtm-relative -fmtm-top-[1px] fmtm-bg-white sm:fmtm-bg-[#F5F5F5]">
<div className="fmtm-flex fmtm-items-center fmtm-w-full fmtm-justify-between">
<div className="fmtm-flex fmtm-items-center fmtm-w-full fmtm-justify-between fmtm-gap-4">
<input
type="text"
onChange={handleOnchange}
value={searchText}
placeholder="Search by task id or username"
className="fmtm-min-w-[14.3rem] fmtm-w-[67%] fmtm-text-md fmtm-px-1 fmtm-py-[0.18rem] fmtm-outline-none fmtm-border-[1px] fmtm-border-[#E7E2E2]"
className="fmtm-w-full fmtm-text-md fmtm-px-1 fmtm-py-[0.18rem] fmtm-outline-none fmtm-border-[1px] fmtm-border-[#E7E2E2]"
/>
<div>
<div className="fmtm-relative">
Expand Down
22 changes: 12 additions & 10 deletions src/frontend/src/components/createnewproject/UploadArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -113,17 +113,19 @@ const UploadArea = ({ flag, geojsonFile, setGeojsonFile, setCustomLineUpload, se
};

useEffect(() => {
const isWGS84 = () => {
if (uploadAreaSelection === 'upload_file') {
const isWGS84Projection = checkWGS84Projection(drawnGeojson);
setIsGeojsonWG84(isWGS84Projection);
return isWGS84Projection;
if (drawnGeojson) {
const isWGS84 = () => {
if (uploadAreaSelection === 'upload_file') {
const isWGS84Projection = checkWGS84Projection(drawnGeojson);
setIsGeojsonWG84(isWGS84Projection);
return isWGS84Projection;
}
setIsGeojsonWG84(true);
return true;
};
if (!isWGS84() && drawnGeojson) {
showSpatialError();
}
setIsGeojsonWG84(true);
return true;
};
if (!isWGS84() && drawnGeojson) {
showSpatialError();
}
return () => {};
}, [drawnGeojson]);
Expand Down
47 changes: 28 additions & 19 deletions src/frontend/src/utilfunctions/checkWGS84Projection.js
Original file line number Diff line number Diff line change
@@ -1,26 +1,35 @@
function checkWGS84Projection(geojson) {
import OLVectorLayer from 'ol/layer/Vector';
import GeoJSON from 'ol/format/GeoJSON';
import { Vector as VectorSource } from 'ol/source';

function checkWGS84Projection(drawnGeojson) {
const vectorLyr = new OLVectorLayer({
source: new VectorSource({
features: new GeoJSON().readFeatures(drawnGeojson),
}),
declutter: true,
});

const extent = vectorLyr.getSource()?.getExtent();

try {
for (const feature of geojson.features) {
const coordinates = feature.geometry.coordinates;
for (const coord of coordinates[0]) {
const [longitude, latitude] = coord;
if (
isNaN(latitude) ||
isNaN(longitude) ||
latitude < -90 ||
latitude > 90 ||
longitude < -180 ||
longitude > 180
) {
// setIsGeojsonWG84(false);
return false; // Coordinates are out of WGS 84 range
}
if (extent?.length > 0) {
const longitude = extent[0];
const latitude = extent[1];
if (
isNaN(latitude) ||
isNaN(longitude) ||
latitude < -90 ||
latitude > 90 ||
longitude < -180 ||
longitude > 180
) {
return false;
}
return true; // All coordinates are within WGS 84 range
}
// setIsGeojsonWG84(true);
return true; // All coordinates are within WGS 84 range
return false;
} catch (error) {
// setIsGeojsonWG84(false);
return false;
}
}
Expand Down

0 comments on commit c5b1cad

Please sign in to comment.