<commit_before>package eu.nimble.core.infrastructure.identity.system;

import eu.nimble.core.infrastructure.identity.clients.CatalogueServiceClient;
import eu.nimble.core.infrastructure.identity.clients.IndexingClient;
import eu.nimble.core.infrastructure.identity.constants.GlobalConstants;
import eu.nimble.core.infrastructure.identity.entity.UaaUser;
import eu.nimble.core.infrastructure.identity.entity.UserInvitation;
import eu.nimble.core.infrastructure.identity.mail.EmailService;
import eu.nimble.core.infrastructure.identity.repository.*;
import eu.nimble.core.infrastructure.identity.service.AdminService;
import eu.nimble.core.infrastructure.identity.service.IdentityService;
import eu.nimble.core.infrastructure.identity.service.RocketChatService;
import eu.nimble.core.infrastructure.identity.uaa.KeycloakAdmin;
import eu.nimble.core.infrastructure.identity.uaa.OAuthClient;
import eu.nimble.core.infrastructure.identity.utils.DataModelUtils;
import eu.nimble.core.infrastructure.identity.clients.IndexingClientController;
import eu.nimble.core.infrastructure.identity.utils.LogEvent;
import eu.nimble.service.model.solr.Search;
import eu.nimble.service.model.ubl.commonaggregatecomponents.PartyType;
import eu.nimble.service.model.ubl.commonaggregatecomponents.PersonType;
import eu.nimble.service.model.ubl.commonaggregatecomponents.QualifyingPartyType;
import eu.nimble.utility.ExecutionContext;
import eu.nimble.utility.LoggerUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static eu.nimble.core.infrastructure.identity.uaa.OAuthClient.Role.PLATFORM_MANAGER;

/**
 * Created by <NAME> on 12.09.18.
 */
@Controller
@RequestMapping(path = "/admin")
@Api(value = "Admin API", description = "Administration services for managing identity on the platform.")
public class AdminController {

    private static final Logger logger = LoggerFactory.getLogger(AdminController.class);

    private static final String DEFAULT_PAGE_SIZE = "10";

    @Autowired
    private AdminService adminService;

    @Autowired
    private KeycloakAdmin keycloakAdmin;
    @Autowired
    private PersonRepository personRepository;
    @Autowired
    private UaaUserRepository uaaUserRepository;
    @Autowired
    private IdentityService identityService;
    @Autowired
    private UserInvitationRepository userInvitationRepository;

    @Autowired
    private ExecutionContext executionContext;

    @Autowired
    private IndexingClientController indexingController;

    @Autowired
    private CatalogueServiceClient catalogueServiceClient;
    @Autowired
    private PartyRepository partyRepository;
    @Autowired
    private QualifyingPartyRepository qualifyingPartyRepository;
    @Autowired
    private RocketChatService chatService;
    @Autowired
    private EmailService emailService;

    @ApiOperation(value = "Retrieve unverified companies", response = Page.class)
    @RequestMapping(value = "/unverified_companies", produces = {"application/json"}, method = RequestMethod.GET)
    ResponseEntity<Page<PartyType>> getUnverifiedCompanies(@RequestParam(value = "page", required = false, defaultValue = "1") int pageNumber,
                                                           @RequestParam(value = "size", required = false, defaultValue = DEFAULT_PAGE_SIZE) int pageSize,
                                                           @RequestParam(value = "sortBy", required = false, defaultValue = GlobalConstants.PARTY_NAME_STRING) String sortBy,
                                                           @RequestParam(value = "orderBy", required = false, defaultValue = GlobalConstants.ASCENDING_STRING) String orderBy){

        // ToDo: verify proper access policy (e.g. admin role)

        logger.info("Fetching unverified companies");
        List<PartyType> unverifiedCompanies = adminService.queryCompanies(AdminService.CompanyState.UNVERIFIED);

        if(!orderBy.isEmpty())
            adminService.sortCompanies(unverifiedCompanies, sortBy, orderBy);


        // paginate results
        return makePage(pageNumber, pageSize, unverifiedCompanies);
    }

    @ApiOperation(value = "Retrieve verified companies", response = Page.class)
    @RequestMapping(value = "/verified_companies", produces = {"application/json"}, method = RequestMethod.GET)
    ResponseEntity<Page<PartyType>> getVerifiedCompanies(@RequestParam(value = "page", required = false, defaultValue = "1") int pageNumber,
                                                         @RequestParam(value = "size", required = false, defaultValue = DEFAULT_PAGE_SIZE) int pageSize,
                                                         @RequestParam(value = "sortBy", required = false, defaultValue = GlobalConstants.PARTY_NAME_STRING) String sortBy,
                                                         @RequestParam(value = "orderBy", required = false, defaultValue = GlobalConstants.ASCENDING_STRING) String orderBy){
        // ToDo: verify proper access policy (e.g. admin role)

        logger.info("Fetching unverified companies");
        List<PartyType> verifiedCompanies = adminService.queryCompanies(AdminService.CompanyState.VERIFIED);

        if(!orderBy.isEmpty())
            adminService.sortCompanies(verifiedCompanies, sortBy, orderBy);
        // paginate results
        return makePage(pageNumber, pageSize, verifiedCompanies);
    }

    @ApiOperation(value = "Verify company")
    @RequestMapping(value = "/verify_company", method = RequestMethod.POST)
    ResponseEntity<?> verifyCompany(@RequestParam(value = "companyId") long companyId,
                                    @RequestHeader(value = "Authorization") String bearer) throws Exception {

        if (identityService.hasAnyRole(bearer, OAuthClient.Role.PLATFORM_MANAGER) == false)
            return new ResponseEntity<>("Only legal platform managers are allowed to verify companies", HttpStatus.UNAUTHORIZED);

        Map<String,String> paramMap = new HashMap<String, String>();
        paramMap.put("activity", LogEvent.VERIFY_COMPANY.getActivity());
        paramMap.put("companyId", String.valueOf(companyId));
        LoggerUtils.logWithMDC(logger, paramMap, LoggerUtils.LogLevel.INFO, "Verifying company with id {}", companyId);
        adminService.verifyCompany(companyId, bearer);

        return ResponseEntity.ok().build();
    }

    @ApiOperation(value = "Revert a deleted company back")
    @RequestMapping(value = "/revert_company/{companyId}", method = RequestMethod.POST)
    ResponseEntity<?> revertCompany(@PathVariable(value = "companyId") long companyId,
                                    @RequestHeader(value = "Authorization") String bearer) throws Exception {

        if (identityService.hasAnyRole(bearer, OAuthClient.Role.PLATFORM_MANAGER,OAuthClient.Role.COMPANY_ADMIN,
                OAuthClient.Role.INITIAL_REPRESENTATIVE,OAuthClient.Role.LEGAL_REPRESENTATIVE,OAuthClient.Role.EXTERNAL_REPRESENTATIVE) == false)
            return new ResponseEntity<>("Only platform managers,company_admin, external_representative, "
                    + "initial_representative, legal_representative are allowed to revert companies back", HttpStatus.UNAUTHORIZED);
        Map<String,String> paramMap = new HashMap<String, String>();
        paramMap.put("activity", LogEvent.REVERT_COMPANY.getActivity());
        paramMap.put("companyId", String.valueOf(companyId));
        LoggerUtils.logWithMDC(logger, paramMap, LoggerUtils.LogLevel.INFO, "Reverting company with id {}", companyId);
        boolean isCompanyReverted = adminService.revertCompany(companyId,bearer);
        if(isCompanyReverted){
            //index catalogues
            catalogueServiceClient.indexAllCatalogues(Long.toString(companyId),bearer);

            //index party
            PartyType company = partyRepository.findByHjid(companyId).stream().findFirst().orElseThrow(ControllerUtils.CompanyNotFoundException::new);
            // retrieve qualifying party
            QualifyingPartyType qualifyingParty = qualifyingPartyRepository.findByParty(company).stream().findFirst().get();
            eu.nimble.service.model.solr.party.PartyType newParty = DataModelUtils.toIndexParty(company,qualifyingParty);
            List<IndexingClient> indexingClients = indexingController.getClients();
            for (IndexingClient indexingClient : indexingClients) {
                indexingClient.setParty(newParty, bearer);
            }
            return ResponseEntity.ok().build();
        }else{
            return new ResponseEntity<>("Only company_admin, external_representative, "
                    + "initial_representative, legal_representative of company are allowed to revert companies back",
                    HttpStatus.UNAUTHORIZED);
        }


    }

    @ApiOperation(value = "Reject company")
    @RequestMapping(value = "/reject_company/{companyId}", method = RequestMethod.DELETE)
    ResponseEntity<?> rejectCompany(@PathVariable(value = "companyId") long companyId,
                                    @RequestHeader(value = "Authorization") String bearer) throws Exception {

        if (identityService.hasAnyRole(bearer, OAuthClient.Role.PLATFORM_MANAGER,OAuthClient.Role.COMPANY_ADMIN,
                OAuthClient.Role.INITIAL_REPRESENTATIVE,OAuthClient.Role.LEGAL_REPRESENTATIVE,OAuthClient.Role.EXTERNAL_REPRESENTATIVE) == false)<commit_msg>resolve NIMBLEFMP-1610<commit_after>package eu.nimble.core.infrastructure.identity.system;

import eu.nimble.core.infrastructure.identity.clients.CatalogueServiceClient;
import eu.nimble.core.infrastructure.identity.clients.IndexingClient;
import eu.nimble.core.infrastructure.identity.constants.GlobalConstants;
import eu.nimble.core.infrastructure.identity.entity.UaaUser;
import eu.nimble.core.infrastructure.identity.entity.UserInvitation;
import eu.nimble.core.infrastructure.identity.mail.EmailService;
import eu.nimble.core.infrastructure.identity.repository.*;
import eu.nimble.core.infrastructure.identity.service.AdminService;
import eu.nimble.core.infrastructure.identity.service.IdentityService;
import eu.nimble.core.infrastructure.identity.service.RocketChatService;
import eu.nimble.core.infrastructure.identity.uaa.KeycloakAdmin;
import eu.nimble.core.infrastructure.identity.uaa.OAuthClient;
import eu.nimble.core.infrastructure.identity.utils.DataModelUtils;
import eu.nimble.core.infrastructure.identity.clients.IndexingClientController;
import eu.nimble.core.infrastructure.identity.utils.LogEvent;
import eu.nimble.service.model.solr.Search;
import eu.nimble.service.model.ubl.commonaggregatecomponents.PartyType;
import eu.nimble.service.model.ubl.commonaggregatecomponents.PersonType;
import eu.nimble.service.model.ubl.commonaggregatecomponents.QualifyingPartyType;
import eu.nimble.utility.ExecutionContext;
import eu.nimble.utility.LoggerUtils;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageImpl;
import org.springframework.data.domain.PageRequest;
import org.springframework.http.HttpStatus;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;

import static eu.nimble.core.infrastructure.identity.uaa.OAuthClient.Role.PLATFORM_MANAGER;

/**
 * Created by <NAME> on 12.09.18.
 */
@Controller
@RequestMapping(path = "/admin")
@Api(value = "Admin API", description = "Administration services for managing identity on the platform.")
public class AdminController {

    private static final Logger logger = LoggerFactory.getLogger(AdminController.class);

    private static final String DEFAULT_PAGE_SIZE = "10";

    @Autowired
    private AdminService adminService;

    @Autowired
    private KeycloakAdmin keycloakAdmin;
    @Autowired
    private PersonRepository personRepository;
    @Autowired
    private UaaUserRepository uaaUserRepository;
    @Autowired
    private IdentityService identityService;
    @Autowired
    private UserInvitationRepository userInvitationRepository;

    @Autowired
    private ExecutionContext executionContext;

    @Autowired
    private IndexingClientController indexingController;

    @Autowired
    private CatalogueServiceClient catalogueServiceClient;
    @Autowired
    private PartyRepository partyRepository;
    @Autowired
    private QualifyingPartyRepository qualifyingPartyRepository;
    @Autowired
    private RocketChatService chatService;
    @Autowired
    private EmailService emailService;

    @ApiOperation(value = "Retrieve unverified companies", response = Page.class)
    @RequestMapping(value = "/unverified_companies", produces = {"application/json"}, method = RequestMethod.GET)
    ResponseEntity<Page<PartyType>> getUnverifiedCompanies(@RequestParam(value = "page", required = false, defaultValue = "1") int pageNumber,
                                                           @RequestParam(value = "size", required = false, defaultValue = DEFAULT_PAGE_SIZE) int pageSize,
                                                           @RequestParam(value = "sortBy", required = false, defaultValue = GlobalConstants.PARTY_NAME_STRING) String sortBy,
                                                           @RequestParam(value = "orderBy", required = false, defaultValue = GlobalConstants.ASCENDING_STRING) String orderBy){

        // ToDo: verify proper access policy (e.g. admin role)

        logger.info("Fetching unverified companies");
        List<PartyType> unverifiedCompanies = adminService.queryCompanies(AdminService.CompanyState.UNVERIFIED);

        if(!orderBy.isEmpty())
            adminService.sortCompanies(unverifiedCompanies, sortBy, orderBy);


        // paginate results
        return makePage(pageNumber, pageSize, unverifiedCompanies);
    }

    @ApiOperation(value = "Retrieve verified companies", response = Page.class)
    @RequestMapping(value = "/verified_companies", produces = {"application/json"}, method = RequestMethod.GET)
    ResponseEntity<Page<PartyType>> getVerifiedCompanies(@RequestParam(value = "page", required = false, defaultValue = "1") int pageNumber,
                                                         @RequestParam(value = "size", required = false, defaultValue = DEFAULT_PAGE_SIZE) int pageSize,
                                                         @RequestParam(value = "sortBy", required = false, defaultValue = GlobalConstants.PARTY_NAME_STRING) String sortBy,
                                                         @RequestParam(value = "orderBy", required = false, defaultValue = GlobalConstants.ASCENDING_STRING) String orderBy){
        // ToDo: verify proper access policy (e.g. admin role)

        logger.info("Fetching unverified companies");
        List<PartyType> verifiedCompanies = adminService.queryCompanies(AdminService.CompanyState.VERIFIED);

        if(!orderBy.isEmpty())
            adminService.sortCompanies(verifiedCompanies, sortBy, orderBy);
        // paginate results
        return makePage(pageNumber, pageSize, verifiedCompanies);
    }

    @ApiOperation(value = "Verify company")
    @RequestMapping(value = "/verify_company", method = RequestMethod.POST)
    ResponseEntity<?> verifyCompany(@RequestParam(value = "companyId") long companyId,
                                    @RequestHeader(value = "Authorization") String bearer) throws Exception {

        if (identityService.hasAnyRole(bearer, OAuthClient.Role.PLATFORM_MANAGER) == false)
            return new ResponseEntity<>("Only legal platform managers are allowed to verify companies", HttpStatus.UNAUTHORIZED);

        Map<String,String> paramMap = new HashMap<String, String>();
        paramMap.put("activity", LogEvent.VERIFY_COMPANY.getActivity());
        paramMap.put("companyId", String.valueOf(companyId));
        LoggerUtils.logWithMDC(logger, paramMap, LoggerUtils.LogLevel.INFO, "Verifying company with id {}", companyId);
        adminService.verifyCompany(companyId, bearer);

        return ResponseEntity.ok().build();
    }

    @ApiOperation(value = "Revert a deleted company back")
    @RequestMapping(value = "/revert_company/{companyId}", method = RequestMethod.POST)
    ResponseEntity<?> revertCompany(@PathVariable(value = "companyId") long companyId,
                                    @RequestHeader(value = "Authorization") String bearer) throws Exception {

        if (identityService.hasAnyRole(bearer, OAuthClient.Role.PLATFORM_MANAGER,OAuthClient.Role.COMPANY_ADMIN,
                OAuthClient.Role.INITIAL_REPRESENTATIVE,OAuthClient.Role.LEGAL_REPRESENTATIVE,OAuthClient.Role.EXTERNAL_REPRESENTATIVE) == false)
            return new ResponseEntity<>("Only platform managers,company_admin, external_representative, "
                    + "initial_representative, legal_representative are allowed to revert companies back", HttpStatus.UNAUTHORIZED);
        Map<String,String> paramMap = new HashMap<String, String>();
        paramMap.put("activity", LogEvent.REVERT_COMPANY.getActivity());
        paramMap.put("companyId", String.valueOf(companyId));
        LoggerUtils.logWithMDC(logger, paramMap, LoggerUtils.LogLevel.INFO, "Reverting company with id {}", companyId);
        boolean isCompanyReverted = adminService.revertCompany(companyId,bearer);
        if(isCompanyReverted){
            //index catalogues
            catalogueServiceClient.indexAllCatalogues(Long.toString(companyId),bearer);

            //index party
            PartyType company = partyRepository.findByHjid(companyId).stream().findFirst().orElseThrow(ControllerUtils.CompanyNotFoundException::new);
            // retrieve qualifying party
            QualifyingPartyType qualifyingParty = qualifyingPartyRepository.findByParty(company).stream().findFirst().get();
            eu.nimble.service.model.solr.party.PartyType newParty = DataModelUtils.toIndexParty(company,qualifyingParty);
            // the deleted companies are the ones which are already verified previously
            newParty.setVerified(true);
            List<IndexingClient> indexingClients = indexingController.getClients();
            for (IndexingClient indexingClient : indexingClients) {
                indexingClient.setParty(newParty, bearer);
            }
            return ResponseEntity.ok().build();
        }else{
            return new ResponseEntity<>("Only company_admin, external_representative, "
                    + "initial_representative, legal_representative of company are allowed to revert companies back",
                    HttpStatus.UNAUTHORIZED);
        }


    }

    @ApiOperation(value = "Reject company")
    @RequestMapping(value = "/reject_company/{companyId}", method = RequestMethod.DELETE)
    ResponseEntity<?> rejectCompany(@PathVariable(value = "companyId") long companyId,
                                    @RequestHeader(value = "Authorization") String bearer) throws Exception {

        if (identityService.hasAnyRole(bearer, OAuthClient.Role.PLATFORM_MANAGER,OAuthClient.Role.COMPANY_ADMIN,
                OAuthClient.Role.INITIAL_REPRESENTATIVE,OAuthClient.Role.LEGAL_REPRESENTATIVE,OAuthClient.Role.EXTERNAL_REPRESENTATIVE) == false)
{'fraction_non_alphanumeric': 0.09418323548275692, 'fraction_numerical': 0.0013814199023138784, 'mean_word_length': 3.7415204678362572, 'pattern_counts': {'":': 0, '<': 39, '<?xml version=': 0, '>': 39, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 30, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '7255090', 'n_tokens_mistral': 5368, 'n_tokens_neox': 5294, 'n_words': 1006}