Salesforce: Merge 3 Permission Sets into 1 - salesforce

I have 3 'old' Permission Sets (PS1, PS2 and PS3) which need to be merged into a Permission Set #4 (PS4).
PS1, PS2 and PS3 will be deprecated after adding its respective permissions into PS4. PS4 will remain as the future Permission Set which will gather ALL the permissions for a specific set of Users.
For now, I see that this is a very manual task ("Eye-ball" comparing each PS1, PS2, PS3 with PS4 and adding the missing permissions into PS4) and, as all manual tasks, it is prone to errors.
QUESTIONS:
Can you suggest a tool to COMPARE Permission Sets to make sure I am not missing any permission?
or (even better)
Can you suggest a tool to MERGE Permission Sets in a safe way (to mitigate risk of errors)?
or
Would you recommend a "best approach" or "best practice" for this task?
Thank you very much.

Developer way
You'd need a developer to connect with sfdx (if commandline is scary - there's VSCode editor) or similar tool and download "metadata". And then compare the XML files using something like WinMerge
https://trailhead.salesforce.com/content/learn/projects/quickstart-vscode-salesforce might help if you've never done it and don't have a developer handy.
Profiles and permission sets can be very big, what's being downloaded depends on what else you're downloading. Define "everything". If you indicate in "package.xml" that you want all objects, classes and permission sets - the permission set file should include checkboxes for "Apex Class Access", field level security, allowed record types etc - but might not include "Visualforce Page Access", tab visibilities etc because you didn't include them). There's cool plugin to VSCode for building the "package.xml" file for you, picking what you need.
Once you have that you could load them up in Winmerge (or any "diff tool" you like) and compare up to 3 files. It takes a while to get used to (you could start with comparing two, not 3).
You'll see an overview of changed lines on the left and you can decide to say make leftmost file the merged one. Go line by line and add permissions as you see them. You could then save the final file as 4th perm set and use same sfdx/vscode to deploy it.
Analyst way
If you feel like Excel guru... This data should be queryable so you could export it and crack some comparisons that way. Again - the checkboxes would be spread across different tables so you'd need to compare object rights, then field level security, then class access, then...
https://developer.salesforce.com/docs/atlas.en-us.api.meta/api/sforce_api_erd_profile_permissions.htm
This would be a start
SELECT Parent.Name, SobjectType, PermissionsRead, PermissionsCreate, PermissionsEdit, PermissionsDelete
FROM ObjectPermissions
WHERE SobjectType IN ('Account', 'Contact', 'Case') AND Parent.Name IN ('PS1', 'PS2', 'PS3')
ORDER BY SobjectType, Parent.Name
It's very ungrateful job because you'd need to write formulas across rows or pivot it somehow... Also note my PS2 didn't have access to Cases at all - SF doesn't bother holding a row with all false, it just isn't there.
¥€$ way
Money solves everything, eh? Deployment & backup tools like OwnBackup, Gearset, Copado etc have something for detecting changes between projects on disk and orgs... You could rename PS2 to PS1 in another sandbox and make the tool compare them? (I'm not affiliated with any such tool vendor)
There's also https://perm-comparator.herokuapp.com/ if you're not afraid 3rd party app will get sysadmin access to your org (haven't used personally, just Googled it)
Ages ago my colleague got promising exports out of Config Workbook. Again - haven't used personally, screenshots look nice.

Related

Obsfucation of code in commercial product

Yesterday, my manager asked me to find and remove all references to 'previous incarnation of company' that appear in the binaries we produce for a product that we're launching in a few weeks. This got me wondering why, in a compiled stand-alone binary, there's so much human-readable content, and whether there's a simple way to obsfucate it so that the program's internals aren't hanging out in the open, so to speak (at least to anyone who opens it with a text editor or greps the file contents). Here are some examples of what I mean:
"WGL_3DFX_multisample À # ð>Unknown OpenGL error
GL_INVALID_FRAMEBUFFER_OPERATION"
" Unable to close due to unfinalised statements not an error SQL logic error or missing database access permission denied callback requested query abort database is locked database table is locked out of memory attempt to write a readonly database interrupted disk I/O error database disk image is malformed database or disk is full unable to open database file table contains no data database schema has changed String or BLOB exceeded size limit constraint failed datatype mismatch"
"flowChartDelay flowChartDisplay flowChartDocument flowChartExtract flowChartInputOutput flowChartInternalStorage flowChartMagneticDisk"
The majority of the file is human incomprehensible stuff like this, which is more what I'd expect from a binary:
"âÀÿ? ‰•þÿÿÇ…”þÿÿ ë‹…”þÿÿƒÀ‰…”þÿÿ‹”þÿÿ;Mà}`‹U‹‚¨ ‹”þÿÿ¶ƒúuF‹E‹ˆ° ‹•”þÿÿ·Q¯…ŒþÿÿÁ艅Œþÿÿ‹M"
I figured out I could simply do a search and replace for 'string that we don't want' and replace it with random text of the same length and the program would run fine, which is possibly easier than making 500 edits to our source to bring it up to date with the current status of the company as a legal entity (there are a tonne of functions called name_of_previous_company_foo()), and also easier than trying to integrate some exotic obfuscation utility into our complex and propritary build system, but it's not an especially elegant solution, and I'd still like to know if there's a way to make our binaries into something more like a black box, where someone can't just open it with a text editor and see our function and class names.
People build source code obfuscator tools for "commercial software" that can scramble strings and identifiers so they aren't easily read out of the binary, but are still usuable as the strings they intend to be.
Such obfuscators tend to be language specific, because they have to handle the fine detail of the language structure.
Google "Source Code Obfuscators" and you'll find many.

Import Access database table design properties but not data

I've got a large amount of access databases that need to have the same table design changes (and a few new tables created) in each of them. Is there any way to take my most recent (properly designed) database, export the design properties, and import them to each of the other databases overwriting changes and creating any new fields, tables, etc. as needed?
My research has only led me to the Database documenter which seems to only be helpful in cases where I'd manually update the properties. I also know I could potentially copy each table over manually specifying 'Structure Only' for each case but that'd be a rather daunting task and I'm unsure what exactly would be copied using this method.
Let me see if I have the outline...
Open Proper.mdb
For each OtherMDB in Folder1
Open OtherMDB
for each ProperTable in Proper.mdb
If ProperTable is absent from OtherMDB
Add ProperTable to OtherMDB
Else
For each Field in ProperTable.Fields
If ProperField is absent from OtherTable.Fields
Add Field to OtherTable
Elseif ' is this a possibility?? wanting to change field type?
ProperField.Type <> OtherTable.Field("xx").Type Then
Change Field.Type
endif
Next Field
Endif
Next Table
Close OtherMDB
Next MDB
I found a utility called DBWeigher which is able to analyze and compare two access databases and automatically generate the necessary VBcode to update the changes between the two. From here I quickly ran through the changes manually and was able to see firsthand what changes would be made prior to running them through the DBConsole.
For anyone trying to update older access databases (especially when they're at different stages and could have some variances), I can't suggest checking this lightweight utility out.

How to attach and view pdf documents to access database

I have a very simple database in access, but for each record i need to attach a scanned in document (probably pdf). What is the best way to do this, the database should not just link to a file on the pc, but should copy and keep the file with it, meaning if the original file goes missing the database is moved or copied, the file should still be accessable from within the Database. Is This possible? and what is the easiest way of doing it? If is should i can write a macro, i just dont know where to start. and also when i display a report of the table, i would like to just see thumbnails of the documents.
Thank you.
As the other answerers have noted, storing file data inside a database table can be a questionable practice. That said, I wouldn't personally rule it out, though if you are going to take that option, I'd strongly suggest splitting out the file data into its own table in its own backend file. For example:
Create a new database file called Scanned files.mdb (or Scanned files.accdb).
Add a single table called Scans with fields such as FileID (AutoNumber, primary key), MainTableID (matches whatever is the primary key of the main table in the main database file), FileName (Text), FileExt (Text) and FileData ('OLE object', really just a BLOB - don't actually use OLE Objects because they will bloat the database horribly).
Back in the frontend, add a reference to Scans as a linked table.
Use a bit of VBA to upload and extract files from the Scans table (if you're interested in the mechanics of this, post a separate question).
Use the VBA Shell routine (if you must) or ShellExecute from the Windows API (= the better option IMO) to open extracted data.
If you are using the newer ACCDB format, then you have the 'attachment' field type available as smk081 suggests. This basically does most of the above steps for you, however doing things 'by hand' gives you greater flexibilty - for example, it allows giving each file a 'DateScanned' or 'DateEffective' field.
That said, your requirement for thumbnails will require explicit coding whatever option you take. It might be possible to leverage the Windows file previewing API, though I'd be certain thumbnails are a definite requirement before investigating this - Access VBA is powerful enough to encourage attempts at complex solutions, but frequently not clean and modern enough to allow fulfilling them in a particularly maintainable fashion.
There is an Attachment type under Data Type when you go into Design View of your table. You can add an attachment field here. When you go into the Datasheet view of the table you can select this field for a particular row and a window will open for you to specify the attachment. This will cause your database to quickly grow in size if you add a lot of large attachments.
You can use an OLE field in a table, but I would really suggest you not use this approach. The database is going to be HUGE in no time, and you're going to regret it.
Instead, you should consider adding a field that stores the path to the file, and keep the files in one folder on your network. Then you can use a SHELL() command to open the file. What's the difference between restoring an Access database and restoring PDF files if something goes wrong? This will keep your database at a manageable size and reduce the possibility of corruption.

How to add comments in SOQL

Is it possible to put comments in SOQL?
The Force.com explorer doesn't support basic operations like undo/redo and I can't find any way to enter comments so experimenting with queries is painful.
I've tried all the usual suspects --, #, /*, //
No, I don't think there's a way to use comments in SOQL. You can comment out pieces of queries you've issued in Apex though.
There are some tools that you might like more than the official Flash-based Explorer and the sluggish querying utility in Eclipse IDE.
My favorite is Real Force Explorer - has the searchable history of SOQL and Apex snippets, you can select the piece you want to run if you have several queries (like in Oracle's SQLDeveloper)...
I've heard some good stuff about BrainEngine too, didn't try it yet (basic version is free, cough up cash for more). The screenshots look tempting ;)
You might also like web-based tools like the official Workbench - if you're not a fan of providing the credentials in the officially hosted one you can download it and host it on your own machine.
Last but not least - JitterBit Data Loader got promoted some time ago to be listed in Setup pages. Haven't played with it either (might be it's just a data loader, not really suited for query editor tasks).
If you're SQL Server guy - have a look at DBAmp ($$$ again). I doubt it's the only connector to Salesforce, there have to be some more ODBC-like translation attempts. So you might be able to find a plugin for your favorite SQL editor after all.
(no, I'm not related to any of companies or projects behind these links)
If you are writing inline SOQL inside of Apex, you can add Apex comments. Both block and single-line comments work.
You can verify this in the Execute Anonymous Window in the Developer Console:
List<Account> accounts = [
SELECT ID From Account
// single line comment
WHERE Name = 'Test' /* block comment */
];
The Execution log shows that the comments are removed from the actual query:
SOQL_EXECUTE_BEGIN [1]|Aggregations:0|SELECT ID FROM Account WHERE Name = 'Test'
I use SOQL Studio from VisualSoftwareSystems.net. It supports line comments and block comments as well as full syntax highlighting.
OK, in SOQL you don't have the usual commenting mechanism. So now it's time for Boolean phantoms: appending an OR clause that can never be true, but contains comment info. Something like this:
SELECT id FROM Account WHERE Name = 'IBM' OR Name = 'This is the comment text explaining what this query is for'
This bit of hackery will slow down the query a little tiny bit...but if you simply must put the comment inside the SOQL (rather than at the end of the line invoking it), it does work.

Subsonic - How to use SQL Schema / Owner name as part of the namespace?

I've just started using Subsonic 2.2 and so far very impressed - think it'll save me some serious coding time.
Before I dive into using it full time though there is something bugging me that I'd like to sort out.
In my current database (a SQL2008 db) I have split the tables, views, sps etc. up into separate chunks by schema/owner name, so all the customer tables are in the customer. schema, products in the product. schema etc., so a to select from the customers address table i'd do a select * from customer.address
Unfortunately, Subsonic ignores the schema/owner name and just gives me the base table name. This is fine as I've no duplicates between schemas (e.g Customer.Address and Supplier.Address don't both exist) but I just feel the code could be clearer if I could split by schema.
Ideally I'd like to be able to alter the namespace by schema/owner - I think this would have least impact on SubSonic yet make the resulting code easier to read.
Problem is, I've crawled all over the Subsonic source and don't have a clue how to do this (doesn't help that I code in VB not C# = yes I know, blame the ZX Spectrum!!)
If anyone has tackled this before or has an idea on how to solve it, I'd be really grateful,
Thanks in advance.
Ed
I was going to suggest the multiple provider approach too.
But a lot of the plumbing is already in subsonic for ownership.
If you edit a couple of lines in CS_ClassTemplate.aspx you can create a namespace for each owner profile. Change around line 58 (I'm using v2.1) to
namespace <%=provider.GeneratedNamespace%><%=owner%>
where owner is
string owner = "." + tbl.SchemaName;
if(owner == ".dbo")
owner = "";
You put that up above, around line 14. This way you can have a namespace for every owner like:
Northwind.Suppliers, Northwind.Customers, etc.
I left dbo as just Northwind so all the tests would compile without a lot of editing.
I ran a simple select query and I think it will work the way you want.
You could do this in 3.0 as well using our t4 templates (but it's 3.5 only). This is a really good bit of feedback - we should build this in by default perhaps!
Glad you got some help here.
Just to let you know I have this now working - or at least, compiling! :-) To get the owner solution to work fully though you'll need to make more changes to the Class Template as otherwise the table/key functions sit within the wrong namespace.
I've also hacked around with the stored procedure template. I couldn't (in the short time I have) work out how to split into separate files/namespaces for each owner so instead i've prefixed each sp function with the owner and an underscore.
However, just in case you have the same problem you'll know its possible to fix.
Ed
You could try doing separate providers that have the same underlying database connection, like so:
<SubSonicService defaultProvider="DBData">
<providers>
<clear/>
<add name="DBData" type="Subsonic.SqlDataProvider, SubSonic" connectionStringName="LocalSqlServer" generatedNamespace="DBData" includeTableList="table_a,table_b" spStartsWith="app,get,set" viewStartsWith="v_" />
<!--CMS Provider-->
<add name="CMS" type="SubSonic.SqlDataProvider, SubSonic" connectionStringName="LocalSqlServer" generatedNamespace="CMS" stripTableText="CMS_" includeTableList="CMS_Content,CMS_Page" useSPs="false"/>
</providers>
</SubSonicService>
I don't think you can use the schema itself as a key in this way, but you could at least work around the issue with a combination of includeTableList and generatedNamespace. You said that you don't have duplicate table names across the different schemas, so it just might work.

Resources