MS Graph API returns 500 when I try to request groups - sharepoint

So I am developing a sharepoint webpart where I need to check if a user is in an AD group. Now here is the odd part the MS Graph query I need to you for that is:
https://graph.microsoft.com/v1.0/me/transitiveMemberOf/microsoft.graph.group?$count=true
And that is the exact Query that my WP sends out, but it returns a 500 error message. Now I thought I had permissions missing, but the Explorer says I do not need any.
Here is my GraphService that handles MS Graph:
import { MSGraphClient } from '#microsoft/sp-http';
import * as MicrosoftGraph from '#microsoft/microsoft-graph-types';
import { WebPartContext } from "#microsoft/sp-webpart-base";
/**
* The class that handles the MS Graph API calls
*/
export default class GraphService {
/**
* The MS Graph client with does the calls
*/
private _client:MSGraphClient;
/**
* Sets the client for the Graph API, needs to be called before the class can be used
* #param context The context of the WP
*/
public async setClient(context:WebPartContext) {
this._client = await context.msGraphClientFactory.getClient();
}
/**
* Checks to see if a user belongs in a user group or not
* #param groupName The group name with we want to check
*/
public async checkCurrentUserGroup(groupName:string) {
const rawData = await this._client.api('/me/transitiveMemberOf/microsoft.graph.group').count(true).get();
const arr = rawData.value.filter(i => i.displayName == groupName);
return !!arr.length;
}
/**
* Returns the users from AD who have a manager and whom companyName is a specific company name
* #param companyName The company name to whom the users need to belong to
*/
public async getUsers(companyName:string):Promise<any[]> {
const rawData = await this._client.api('/users').filter('accountEnabled eq true').expand('manager').select('displayName,companyName,mail,department,jobTitle').get();
//need to do manual filtering, becuase you can't user filter on the "companyName" field and you can't search and expand at the same time without returing everything
const filteredData = rawData.value.filter(i => i.companyName == companyName && i.manager);
//remaps the data to IUserModel
const ret:any[] = filteredData.map(i => <any>{
name: i.displayName,
id: 0,
email: i.mail,
manager: i.manager.displayName,
managerEmail: i.manager.mail,
managerId: 0,
hasDiscussionForm: false,
department: i.department,
position: i.jobTitle
});
return ret;
}
}
The problem then is that the method checkCurrentUserGroup returns 500.
I've given the following permissions to the wp:
Group.Read.All
Directory.Read.All
User.Read
The getUsers method works as expected.
In the MS Graph Explorer the query works just fine. What am I missing?

According to the document the request header must have ConsistencyLevel and eventual header and please make sure to pass the request header and please refer to this document for more information
let res = await client.api('/users/{id}/transitiveMemberOf/microsoft.graph.group')
.header('ConsistencyLevel','eventual')
.search('displayName:tier')
.select('displayName,id')
.orderby('displayName ')
.get();

Related

On an afterSubmit when we creating a copy of one inventory item (name with '-c') ,The original ID of item link should come in a field on a copy order

I tried this above, here I am getting a null value only from my previous record.
Kindly give some guidance to solve my questions.
thanks in advance.
/**
*#NApiVersion 2.0
*#NScriptType UserEventScript
*/
define(["N/url", "N/record", "N/runtime"], function (url, record, runtime) {
function afterSubmit(context){
var recordobj = context.newRecord;
var prevItemrecord= context.oldRecord;
var Itemname = recordobj.getValue({fieldId:'itemid'});
var prevItemname = prevItemrecord.getValue({fieldId : 'itemid'});
var Type=context.type;
var checkbox=recordobj.getValue({fieldId:'custitem17'});
if(Type== context.UserEventType.CREATE)
if((Itemname=prevItemname+'-c')&&(checkbox=true))
record.submitFields({
type: recordobj.type,
id: recordobj.id,
values:{custitem_item_link:prevItemname}
});
}
return{
afterSubmit:afterSubmit
}
});
This is my code
On create there is no old record.
Since you are trying to update the same record as was just created you are better off having this in a beforeSubmit event script
if((Itemname=prevItemname+'-c')&&(checkbox=true)) this is an error
if((Itemname == prevItemname+'-c') && checkbox) is more what you need
If you are trying to capture a copy operation you can set that up in the beforeLoad event that you use in the beforeSubmit event.
function beforeLoad(ctx){
if(ctx.type == ctx.UserEventType.COPY){
if(ctx.form){
ctx.form.addField({
id:'custpage_original_item',
label:'Copied Item',
type:ui.FieldType.SELECT,
source:'item'
}).updateDisplayType({
displayType:ui.FieldDisplayType.HIDDEN
}).defaultValue = ctx.request.parameters.id;
// your naming makes me wonder if you are trying to link to the
// source item rather than just saving a reference to the source
// item's name
/*
* Using the original item's name like below is closer to what you
* posted but I think by the time the script runs the itemid field
* has been cleared.
* ctx.form.addField({
* id:'custpage_original_item_name',
* label:'Copied Item Name',
* type:ui.FieldType.TEXT
* }).updateDisplayType({
* displayType:ui.FieldDisplayType.HIDDEN
* }).defaultValue = ctx.newRecord.getValue({fieldId:'itemid'});
*/
}
}
}
function beforeSubmit(ctx){
if(ctx.type == ctx.UserEventType.CREATE){
const itemRec = ctx.newRecord;
if(itemRec.getValue({fieldId:'custitem17'})){
const sourceId = itemRec.getValue({fieldId:'custpage_original_item'})
if(sourceId){
itemRec.setValue({
fieldId:'custitem_item_link:prevItemname',
value:sourceId
});
/* or use a search function to look up the original item's name
* and then test the new item's name.
*/
}
}
}
}

Get list of version ids for a blob using node.js

I am trying to get list of version ids for a blob using node.js.
async function getBlobNameAndVersions() {
for await (const blob of containerClient.listBlobsFlat(includeVersions?: true)) {
const tempBlockBlobClient = containerClient.getBlockBlobClient(blob.name);
console.log(`\n\tname: ${blob.versionId}\n\tURL: ${tempBlockBlobClient.name}\n`);
}
}
getBlobNameAndVersions()
Received error saying "ReferenceError: inlcudeVersions is not defined"
When looked at the reference listBlobsFlat, below were options to include versions.
listBlobsFlat(options?: ContainerListBlobsOptions): PagedAsyncIterableIterator<BlobItem, ContainerListBlobFlatSegmentResponse>;
/**
* Returns an AsyncIterableIterator for ContainerListBlobHierarchySegmentResponse
*
* #param delimiter - The character or string used to define the virtual hierarchy
* #param marker - A string value that identifies the portion of
* the list of blobs to be returned with the next listing operation. The
* operation returns the ContinuationToken value within the response body if the
* listing operation did not return all blobs remaining to be listed
* with the current page. The ContinuationToken value can be used as the value for
* the marker parameter in a subsequent call to request the next page of list
* items. The marker value is opaque to the client.
* #param options - Options to list blobs operation.
Tried using options as below.
export declare interface ContainerListBlobsOptions extends CommonOptions {
* Specifies whether versions should be included in the enumeration. Versions are listed from oldest to newest in the response.
*/
includeVersions?: boolean;
}
You would need to pass the options as an object i.e. instead of passing includeVersions?: true, you would need to use {includeVersions: true}.
So your code would be something like:
async function getBlobNameAndVersions() {
for await (const blob of containerClient.listBlobsFlat({includeVersions: true})) {
const tempBlockBlobClient = containerClient.getBlockBlobClient(blob.name);
console.log(`\n\tname: ${blob.name}\n\tURL: ${tempBlockBlobClient.url}\n`);
}
}
Updated Code is working to get version ids of blobs and its URL's
async function getBlobNameAndVersions() {
for await (const blob of containerClient.listBlobsFlat({includeVersions: true})){
const tempBlockBlobClient = containerClient.getBlockBlobClient(blob.name);
console.log(`\n\tversion: ${blob.versionId}\n\tURL: ${tempBlockBlobClient.url}\n`);
}
}

Hyperledger Composer - can't find transaction error

I am making a blockchain application using hyperledger composer and have written my cto, with on transaction, and the script file with no visible errors. However, when i try submit a transaction it returns this error: Error: Could not find any transactions to execute for org.evidence.net.evidenceDeposit.
Here is my CTO file:
namespace org.evidence.net
enum type {
o storage
o device
o physical
}
enum status {
o collected
o stored
o withdrawn
}
asset EvidenceItem identified by evidenceItemId {
o String evidenceItemId
o String caseNo
o type Type
o status Status
o String optionalHash optional
--> person Holder
}
abstract participant person identified by id {
o String id
o String firstName
o String lastName
}
participant Investigator extends person {
}
participant EvidenceManager extends person {
}
participant FRT extends person {
}
transaction evidenceDeposit {
--> EvidenceItem EvidenceItem
--> EvidenceManager EvidenceManager
}
event FirstDeposit {
o String evidenceItemId
o String id
}
And here is my script file:
/*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
/**
* Transfer evidence from FRT to Evidence Manager
* #param (org.evidence.net.evidenceDeposit} tx - the evidenceDeposit transaction
* #transaction
*/
const NS = 'org.evidence.net';
async function evidenceDeposit(tx) {
// get asset registry for evidenceItem
const evidenceItemRegistry = await getAssetRegistry(NS + '.evidenceItem');
//Get participant registry for Evidence Manager
const EvidenceManagerRegistry = await getParticipantRegistry(NS + '.EvidenceManager');
const evidenceItem = await evidenceItemRegistry.get(tx.evidenceItem.getIdentifier());
//Make sure that the evidenceItem exists
if (!evidenceItem) {
throw new Error(' Evidence with id ${tx.evidenceItem.getIdentifier()} does not exist');
exit();
}
if (evidenceItem.status !== 'collected') {
throw new Error('Evidence with id ${tx.evidenceItem.getIdentifier()} is not in collected status');
}
// Get Evidence Manager ID
const EvidenceManagerID = tx.EvidenceManager.getIdentifier();
//Make sure Evidence Manager exists
const EvidenceManager = await EvidenceManagerRegistry.get(EvidenceManagerID);
if(!EvidenceManager) {
throw new Error('Evidence Manager with id ${EvidenceManagerID} does not exist');
}
//Update evidenceItem with new owner
tx.evidenceItem.holder = tx.EvidenceManager;
tx.evidenceItem.status = 'stored';
//Update the asset in the asset registry
await evidenceItemRegistry.update(tx.evidenceItem);
//Create deposit event
let FirstDepositEvent = getFactory().newEvent(NS, 'FirstDeposit');
FirstDepositEvent.evidenceItemId = tx.evidenceItem.evidenceItemId;
FirstDepositEvent.id = tx.EvidenceManager.id;
// Emit the Event
emit(FirstDepositEvent);
}
I have looked around and can't seem to find the problem. Any help is appreciated.
Please see the readme below as Hyperledger Composer has been deprecated for over a year.
https://github.com/hyperledger/composer/blob/master/README.md

while adding an asset to hyperledger got error that particular field is missing

i made a business network using hyperledger composer playground i want add an asset in the registry but while adding it is saying that t: Instance com.acn.hps.aops.ims.EvidenceDoc#4439 missing required field owner
.cto file
asset EvidenceDoc identified by evidenceId{
o String evidenceId
o Owner owner
}
participant Owner identified by AuthorityId{
o String AuthorityId
}
transaction addasset{
o EvidenceDoc evidenceDocJson
}
.qry file
.qry file
enter code here
query getOwnerbyId{
description: "Get owner of the evidence asset by its ID"
statement:
SELECT com.acn.hps.aops.ims.Superuser
WHERE (AuthorityId == _$AuthorityId)
}
logic.js file
/**
* #param {com.acn.hps.aops.ims.AddEvidence} addAsset
* #transaction
*/
function AddingEvidence(addAsset){
return getAssetRegistry('com.acn.hps.aops.ims.EvidenceDoc')
.then(function (AssetRegistry) {
// Get the factory for creating new asset instances.
var factory = getFactory();
var result = query('getOwnerbyId',
{AuthorityId:'1'/*addAsset.evidenceDocJson.owner.AuthorityId*/});
// Create the Evidence.
var evidence = factory.newResource('com.acn.hps.aops.ims', 'EvidenceDoc',
addAsset.evidenceDocJson.evidenceId);
evidence.owner = result[0]
// Add the asset to the asset registry.
return AssetRegistry.add(evidence);
})
}
I don't think the query is needed here. Try this.
.cto
namespace com.acn.hps.aops.ims
asset EvidenceDoc identified by evidenceId{
o String evidenceId
o Owner owner
}
participant Owner identified by AuthorityId{
o String AuthorityId
}
transaction addasset{
o EvidenceDoc evidenceDocJson
}
script.js
/**
* #param {com.acn.hps.aops.ims.addasset} addAsset
* #transaction
*/
function AddingEvidence(addAsset){
return getAssetRegistry('com.acn.hps.aops.ims.EvidenceDoc')
.then(function (AssetRegistry) {
// Get the factory for creating new asset instances.
var factory = getFactory();
// Create the Evidence.
var evidence = factory.newResource('com.acn.hps.aops.ims', 'EvidenceDoc',
addAsset.evidenceDocJson.evidenceId);
evidence.owner = addAsset.evidenceDocJson.owner
// Add the asset to the asset registry.
return AssetRegistry.add(evidence);
})
}
So your transaction name needs to match the param section ('addAsset' uppercase) in your transaction logic:
Also would suggest to pass owner as relationship to transaction
In your model
transaction addAsset {
o String evidenceId
--> Owner owner
}
In your transaction code (something like):
/**
* #param {com.acn.hps.aops.ims.addasset} addAsset
* #transaction
*/
function AddingEvidence(addAsset){
console.log('participant is ' + addAsset.owner.AuthorityID);
console.log('getCurrentparticipant is ' + getCurrentParticipant());
// Get the factory for creating new asset instances.
var factory = getFactory();
// Create the Evidence.
var evidence = factory.newResource('com.acn.hps.aops.ims', 'EvidenceDoc', addAsset.evidenceId);
evidence.owner.ID = addAsset.owner.AuthorityID;
return getAssetRegistry('com.acn.hps.aops.ims.EvidenceDoc')
.then(function (registry) {
return registry.add(evidence );
});
}

Drupal: How to differentiate between new user registration and user password update in hook_user validate operation?

I am using hook_user validate operation to validate user registration info against my business logic.
I want separate logics to run on registration and change password.
But I am unable to differentiate between the two - both pass through validation and same code is run for both.
How can I differentiate between the two inside the validate op in hook_user?
with $form_id
if ( ($form_id == 'user_profile_form' && arg(3) == NULL) {
// validation code for updating
}
elseif ($form_id == 'user_register') ) {
// validation code for registering
}
In Drupal 7 you may try something like:
/**
* Implements hook_form_FORM_ID_alter().
* Form ID: user_profile_form
*/
function foo_form_user_profile_form_alter($form, &$form_state) {
// Set a custom form validate and submit handlers.
$form['#validate'][] = 'foo_form_user_profile_form_validate';
$form['#submit'][] = 'foo_form_user_profile_form_submit';
}
/**
* Implements hook_form_FORM_ID_alter().
* Form ID: user_register_form
*/
function foo_form_user_register_form_alter($form, &$form_state) {
if ($form['#user_category'] == 'account') {
// Set a custom form validate and submit handlers.
$form['#validate'][] = 'foo_form_user_register_validate';
$form['#submit'][] = 'foo_form_user_register_submit';
}
}

Resources