Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/Apps/W1/ExpenseAgent/app/app.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
},
{
"from": 7073,
"to": 7137
"to": 7147
}
],
"features": [
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------
namespace Microsoft.ExpenseAgent;

using Microsoft.Finance.RoleCenters;

pageextension 6905 "Exp. Acc. Payable Admin RC Ext" extends "Acc. Payable Administrator RC"
{
layout
{
addlast(rolecenter)
{
part("Expense Activities"; "Expense Activities")
Comment thread
v-rohangarg20 marked this conversation as resolved.
{
AccessByPermission = tabledata Expense = R;
ApplicationArea = Basic, Suite;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------
namespace Microsoft.ExpenseAgent;

using Microsoft.Finance.RoleCenters;

pageextension 6904 "Exp. Accountant RC Ext" extends "Accountant Role Center"
{
layout
{
addlast(rolecenter)
{
part("Expense Activities"; "Expense Activities")
Comment thread
v-rohangarg20 marked this conversation as resolved.
{
AccessByPermission = tabledata Expense = R;
ApplicationArea = Basic, Suite;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------
namespace Microsoft.ExpenseAgent;

using Microsoft.Finance.RoleCenters;

pageextension 6906 "Exp. Business Manager RC Ext" extends "Business Manager Role Center"
{
layout
{
addlast(rolecenter)
{
part("Expense Activities"; "Expense Activities")
Comment thread
v-rohangarg20 marked this conversation as resolved.
{
AccessByPermission = tabledata Expense = R;
ApplicationArea = Basic, Suite;
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,143 @@
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------
namespace Microsoft.ExpenseAgent;

page 7140 "Expense Activities"
{
Caption = 'Expense Activities';
PageType = CardPart;
RefreshOnActivate = true;
SourceTable = "Expense Activities Cue";

layout
{
area(Content)
{
cuegroup("Expense Reports")
{
Caption = 'Expense Reports';

field("Opened Expense Reports"; Rec."Opened Expense Reports")
{
ApplicationArea = Basic, Suite;
ToolTip = 'Specifies the number of open expense reports.';

trigger OnDrillDown()
begin
DrillDownExpenseReports("Expense Report Status"::Open);
end;
}
field("Released Expense Reports"; Rec."Released Expense Reports")
{
ApplicationArea = Basic, Suite;
ToolTip = 'Specifies the number of released expense reports.';

trigger OnDrillDown()
begin
DrillDownExpenseReports("Expense Report Status"::Released);
end;
}
field("Pending Approval Exp. Reports"; Rec."Pending Approval Exp. Reports")
{
ApplicationArea = Basic, Suite;
ToolTip = 'Specifies the number of expense reports that are pending approval.';

trigger OnDrillDown()
begin
DrillDownExpenseReports("Expense Report Status"::"Pending Approval");
end;
}
field("Approved Expense Reports"; Rec."Approved Expense Reports")
{
ApplicationArea = Basic, Suite;
ToolTip = 'Specifies the number of approved expense reports.';

trigger OnDrillDown()
begin
DrillDownExpenseReports("Expense Report Status"::Approved);
end;
}
field("Rejected Expense Reports"; Rec."Rejected Expense Reports")
{
ApplicationArea = Basic, Suite;
ToolTip = 'Specifies the number of rejected expense reports.';

trigger OnDrillDown()
begin
DrillDownExpenseReports("Expense Report Status"::Rejected);
end;
}
field("Processed for Payment Exp."; Rec."Processed for Payment Exp.")
{
ApplicationArea = Basic, Suite;
ToolTip = 'Specifies the number of expense reports that are processed for payment.';

trigger OnDrillDown()
begin
DrillDownExpenseReports("Expense Report Status"::"Processed for Payment");
end;
}
field("Completed Expense Reports"; Rec."Completed Expense Reports")
{
ApplicationArea = Basic, Suite;
ToolTip = 'Specifies the number of completed expense reports.';

trigger OnDrillDown()
begin
DrillDownExpenseReports("Expense Report Status"::Completed);
end;
}
}
cuegroup(Expenses)
{
Caption = 'Expenses';

field("Released Expenses"; Rec."Released Expenses")
{
ApplicationArea = Basic, Suite;
ToolTip = 'Specifies the number of released expenses.';

trigger OnDrillDown()
var
Expense: Record Expense;
begin
Expense.SetRange(Status, "Expense Status"::Released);
Page.Run(Page::Expenses, Expense);
end;
}
field("Policy Violated Expenses"; Rec."Policy Violated Expenses")
{
ApplicationArea = Basic, Suite;
ToolTip = 'Specifies the number of expenses with policy violations.';

trigger OnDrillDown()
var
Expense: Record Expense;
begin
Expense.SetRange("Rule Violations", true);
Page.Run(Page::Expenses, Expense);
end;
}
}
}
}

trigger OnOpenPage()
begin
Rec.Reset();
if not Rec.Get() then begin
Rec.Init();
Rec.Insert();
end;
end;

local procedure DrillDownExpenseReports(ReportStatus: Enum "Expense Report Status")
var
ExpenseReportHeader: Record "Expense Report Header";
begin
ExpenseReportHeader.SetRange(Status, ReportStatus);
Page.Run(Page::"Expense Reports", ExpenseReportHeader);
end;
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
// ------------------------------------------------------------------------------------------------
// Copyright (c) Microsoft Corporation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
// ------------------------------------------------------------------------------------------------
namespace Microsoft.ExpenseAgent;

table 6940 "Expense Activities Cue"
{
Access = Internal;
Caption = 'Expense Activities Cue';
DataClassification = CustomerContent;
ReplicateData = false;

fields
{
field(1; "Primary Key"; Code[10])
{
Caption = 'Primary Key';
DataClassification = SystemMetadata;
}
Comment thread
v-rohangarg20 marked this conversation as resolved.
field(2; "Opened Expense Reports"; Integer)
Comment thread
v-rohangarg20 marked this conversation as resolved.
{
Caption = 'Opened Expense Reports';
FieldClass = FlowField;
CalcFormula = count("Expense Report Header" where(Status = const(Open)));
Comment thread
v-rohangarg20 marked this conversation as resolved.
Editable = false;
}
field(3; "Released Expense Reports"; Integer)
{
Caption = 'Released Expense Reports';
FieldClass = FlowField;
CalcFormula = count("Expense Report Header" where(Status = const(Released)));
Editable = false;
}
field(4; "Pending Approval Exp. Reports"; Integer)
{
Caption = 'Expense Reports Pending Approvals';
FieldClass = FlowField;
CalcFormula = count("Expense Report Header" where(Status = const("Pending Approval")));
Editable = false;
}
field(5; "Approved Expense Reports"; Integer)
{
Caption = 'Approved Expense Reports';
FieldClass = FlowField;
CalcFormula = count("Expense Report Header" where(Status = const(Approved)));
Editable = false;
}
field(6; "Rejected Expense Reports"; Integer)
{
Caption = 'Rejected Expense Reports';
FieldClass = FlowField;
CalcFormula = count("Expense Report Header" where(Status = const(Rejected)));
Editable = false;
}
field(7; "Processed for Payment Exp."; Integer)
{
Caption = 'Processed for Payment Exp. Rep.';
FieldClass = FlowField;
CalcFormula = count("Expense Report Header" where(Status = const("Processed for Payment")));
Editable = false;
}
field(8; "Completed Expense Reports"; Integer)
{
Caption = 'Completed Expense Reports';
FieldClass = FlowField;
CalcFormula = count("Expense Report Header" where(Status = const(Completed)));
Editable = false;
}
field(9; "Released Expenses"; Integer)
Comment thread
v-rohangarg20 marked this conversation as resolved.
{
Caption = 'Released Expenses';
FieldClass = FlowField;
CalcFormula = count(Expense where(Status = const(Released)));
Editable = false;
}
field(10; "Policy Violated Expenses"; Integer)
{
Caption = 'Policy Violated Expenses';
FieldClass = FlowField;
CalcFormula = count(Expense where("Rule Violations" = const(true)));
Editable = false;
}
}

keys
{
key(PK; "Primary Key")
{
Clustered = true;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ permissionset 6904 "Expense Management - Objects"
table Traveler = X,
table "Expense Activity Log Entry" = X,
table "Expense Project Buf" = X,
table "Expense Activities Cue" = X,
table "Expense Vehicle Type" = X,
table "Mileage Rate Setup" = X,
page "EA Billing Overview" = X,
Expand Down Expand Up @@ -111,6 +112,7 @@ permissionset 6904 "Expense Management - Objects"
page "Expense Report SubPage" = X,
page "Expense Reports" = X,
page "Expense Management Role Center" = X,
page "Expense Activities" = X,
page "Manager Expense Reports" = X,
page "Expense Subcategories" = X,
page "Expense Vendors" = X,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,6 @@ permissionset 6906 "Expense Mgmt. Edit"
tabledata Traveler = IMD,
tabledata "Expense VAT Specification" = IMD,
tabledata "Expense Report Line VAT Spec." = IMD,
tabledata "Expense Activities Cue" = IMD,
Comment thread
v-rohangarg20 marked this conversation as resolved.
tabledata "Expense Vendor" = RIMD;
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,5 +64,6 @@ permissionset 6907 "Expense Mgmt. Read"
tabledata "Expense VAT Specification" = R,
tabledata "Expense Report Line VAT Spec." = R,
tabledata "Expense Activity Log Entry" = R,
tabledata "Expense Activities Cue" = RIMD,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

$\textbf{🟠\ High\ Severity\ —\ Security}$

"Expense Mgmt. Read" (permissionset 6907) grants tabledata "Expense Activities Cue" = RIMD, while every other tabledata grant in this same read-only permission set is R only. This is an inconsistent over-grant: a permission set named and captioned "Expense Management - Read" should not hand out Insert/Modify/Delete rights on a table, especially since the cue table's own OnOpenPage trigger (Rec.Init/Rec.Insert) is what actually needs write access. Either move the row-initialization logic behind a call that runs under a more privileged/system context, or scope the write rights to the Edit permission set (which is already granted IMD on the same table) and keep Read at R.

Knowledge:

👍 useful · ❤️ especially valuable · 👎 wrong - reply with why · AL review agent v1.35.4

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it should be Read Only

tabledata "Posted Exp. Rep. Line VAT Spec" = R;
}
Loading