Dart Encapsulation - private data - dart

I know i can create a private property by prefixing its name with an underscore (_).
but if I put the class and the main function in the same file I can access to private properties
class User {
late String email;
late String _password;
User({required String email, required String password})
: email = email,
_password = password;
}
void main() {
User u = User(email: 'myemail#gmail.com', password: 'mypassword');
print(u._password); // I can access to this private property
}
if I move the User class to a separate file everything works like expected, and i can't access private properties
import 'user.dart';
void main() {
User u = User(email: 'myemail#gmail.com', password: 'mypassword');
print(u._password); // I can't access to this private property
}
I didn't understand the reason.

Unlike Java, Dart doesn’t have the keywords public, protected, and private. If an identifier starts with an underscore (_), it's private to its library.
https://dart.dev/guides/language/language-tour#important-concepts.
So basically the underscore does not make "variable private" the way we are used to (from languages like Java or C#) but it makes private to the library (which, roughly saying, is the same as a Java package).
That's why if you put the directive part of 'main.dart'; in the user.dart and the directive part 'user.dart'; in the main.dart file you will be able to access the private field, even the class being in a different file. The part of and part directives makes two files the same library.
If you are curious why Dart uses underscores instead of access modifier keywords like public or private, see SDK issue #33383 https://github.com/dart-lang/sdk/issues/33383.
In a nutshell, from what I have understood: since the Dart language supports dynamic member access, it's far more performant use library level visibility than class-based visibility, as #eernstg said:
I think it's important to note that this is actually not about syntax. You could choose lots of different syntactic forms for the same thing, but it's the underlying structure that matters.

If you want to access a variable from a class, use this
class User {
late String email;
late String _password;
User({required String email, required String password})
: email = email,
_password = password;
//this is called a get function, which you can call from class instance.
String get getUserPassword => _password;
}
import 'user.dart';
void main() {
User u = User(email: 'myemail#gmail.com', password: 'mypassword');
print(u.getUserPassword); // changes here
}
Happy coding!!

Related

Why is #AuthenticationPrincipal null in spring-native image?

I'm injecting #AuthenticationPrincipal in a #RestController method. It works as expected in the JVM, but I get a NPE at security SpEL evaluation when running native image.
Here is the method:
#PutMapping("/{proxiedUserSubject}/proxies/{grantedUserSubject}")
#PreAuthorize("#token.subject == #proxiedUserSubject")
public ResponseEntity<?> editUserProxy(
#PathVariable(name = "proxiedUserSubject") #NotEmpty String proxiedUserSubject,
#PathVariable(name = "grantedUserSubject") #NotEmpty String grantedUserSubject,
#RequestBody Collection<Long> grantIds,
#AuthenticationPrincipal Object token) {
final var proxiedUser = getOrCreateUser(proxiedUserSubject);
final var grantedUser = getOrCreateUser(grantedUserSubject);
final var grants = grantRepo.findAllById(grantIds);
grantedUser.setGrantsOn(proxiedUser, grants);
userRepo.save(grantedUser);
return ResponseEntity.accepted().build();
}
Any idea why token is null in native image only?
I suspect something with AOT plugin configuration, but could not isolate the issue yet.
If your principal is a custom type you will need to add a reflection hint so that it can be used in a SpEL expression.
#TypeHint(types = CustomToken.class)
The default Spring Security types already have reflection hints as part of Spring Native.

Smallrye open api interceptor

I am developing a rest application.
Some endpoints require a custom header parameter, not related to authorisation. I created a custom annotation using jax-rs NameBinding. Here is an usage example:
#GET
#RequiresBankHeader
public int get(
#HeaderParam("bank")
#Parameter(ref = "#/components/parameters/banks")
String bank) {
return someService.getSomeInformation();
}
There is a provider that intercepts this call and do some routine using the information in the header parameter.
The problem is that I have to repeat '#HeaderParam("bank") #Parameter(ref = "#/components/parameters/banks") String bank' everywhere, just so it appears in Swagger, even though the service classes do not need it. I was able to at least reuse the parameter definition with ref = "#/components/parameters/banks", and declaring it in the OpenAPI.yml file, that Quarkus merges with generated code very nicely.
But I also want to create and interceptor to dynamically add this do the OpenApi definition whenever RequiresBankHeader annotation is present.
Is there a way to do it?
I dont think you can use interceptors to modify the generated Openapi schema output.
If all methods on a given endpoint require some parameter, you can specify it on class level like so:
#Path("/someendpoint")
public class MyEndpoint {
#HeaderParam("bank")
#Parameter(name = "bank")
String bank;
#GET
public Response getAll() {return Response.ok().build()}
#GET
#Path("{id}")
public Response someMethod(#PathParam("id") String id) {return Response.ok().build();}
}
As mentioned by Roberto Cortez, the MP OpenAPI spec provides a programmatic way to contribute metadata to the openapi.yml file.
It is not possible to detect an annotation in the JAX-RS endpoint definition, but it was good enough to automate what I needed. Since all methods that had the RequiresBankHeader return the same Schema, I was able to hack it like this:
public class OpenApiConfigurator implements OASFilter {
#Override
public Operation filterOperation(Operation operation) {
operation.getResponses().getAPIResponses().values().stream().
map(APIResponse::getContent).
filter(Objects::nonNull).
map(Content::getMediaTypes).
flatMap(mediaTypes -> mediaTypes.values().stream()).
map(MediaType::getSchema).
filter(Objects::nonNull).
map(Schema::getRef).
filter(Objects::nonNull).
filter(ref -> ref.contains("the common response schema")).
findAny().
ifPresent(schema -> {
ParameterImpl parameter = new ParameterImpl();
parameter.setRef("#/components/parameters/banks");
operation.addParameter(parameter);
});
return operation;
}
OpenApiConfigurator should be configure in the application properties, using mp.openapi.filter=com.yourcompany.OpenApiConfigurator

Jenkins form validation with objects as parameters

I'm building a plugin for Jenkins and I'm trying to validate my form (connection test method). This worked fine when all #QueryParameter were Strings.
Now I'm trying to send my form validation method an Object like this:
public FormValidation doTestConnection(
#QueryParameter("url") final String url,
#QueryParameter("timeout") final String timeout,
#QueryParameter("bypassProxy") final boolean bypassProxy,
#QueryParameter("deployerCredentialsConfig") final CredentialsConfig deployerCredentialsConfig,
#QueryParameter("resolverCredentialsConfig") final CredentialsConfig resolverCredentialsConfig
) throws ServletException {
In my global.jelly file I have this:
<f:validateButton
title="${%Test Connection}" progress="${%Testing...}"
method="testConnection"
with="url,timeout,bypassProxy,deployerCredentialsConfig,resolverCredentialsConfig"/>
My CredentialConfig class implements Serializable but I guess that is not enough becuase I'm getting this when clicking the "Test Connection" button:
java.lang.IllegalArgumentException: Failed to invoke public hudson.util.FormValidation
org.jfrog.hudson.MyBuilder$DescriptorImpl.doTestConnection(java.lang.String,java.lang.String,boolean,org.jfrog.hudson.CredentialsConfig,org.jfrog.hudson.CredentialsConfig) throws javax.servlet.ServletException
Jenkins has no good documentation for using objects inside of FormValidation calls.
Looking at the Jenkins documentation and the code behind <f:validateButton/>, I believe it's impossible have objects bind in validation logic.
The docs say (https://wiki.jenkins-ci.org/display/JENKINS/Jelly+form+controls):
The 'with' attribute specifies the input fields sent to the server for
the validation. They are matched against the field attribute or the
name attribute of other input controls. The values of the nearest
input fields above the are sent to the server, so
this means the button has to come after the input fields. Multiple
fields can be specified by using ','.
The code simply gets fields by the names - there is no "object assembly" (I believe it's only done during actual config submission).
https://github.com/jenkinsci/jenkins/blob/96ec7a267e0efba2ec99590c871db0940e35920f/war/src/main/webapp/scripts/hudson-behavior.js#L2856
I bumped into a similar problem. Looking at the code, it seems stapler tries to convert your parameter to the type you provided in the doCheck function declaration.
class HandlerImpl extends AnnotationHandler<QueryParameter> {
public Object parse(StaplerRequest request, QueryParameter a, Class type, String parameterName) throws ServletException {
String name = a.value();
if(name.length()==0) name=parameterName;
if(name==null)
throw new IllegalArgumentException("Parameter name unavailable neither in the code nor in annotation");
String value = request.getParameter(name);
if(a.required() && value==null)
throw new ServletException("Required Query parameter "+name+" is missing");
if(a.fixEmpty() && value!=null && value.length()==0)
value = null;
return convert(type,value); // <--- HERE
}
}
As a workaround, I changed the type to boolean, like so:
public FormValidation doTestConnection(
#QueryParameter("url") final String url,
#QueryParameter("timeout") final String timeout,
#QueryParameter("bypassProxy") final boolean bypassProxy,
#QueryParameter("deployerCredentialsConfig") final boolean deployerCredentialsConfig,
#QueryParameter("resolverCredentialsConfig") final boolean resolverCredentialsConfig
) throws ServletException {
This allows me to at least check if the variable is set. It might not be enough for your use case, though.

Retrieve Jira LinkTypes via JIRA REST API

I need to get a complete list of all LinkTypes known by Jira. Since I couldn't find any documentation which provides this info, I would prefer to retrieve all types via the JIRA REST API. Is there a way to do that?
List<Type> types = jiraRestClient.runQuery("https://jira-host.com/rest/api/latest/<allLinkTypes>");
...
#JsonInclude(JsonInclude.Include.NON_NULL)
#Generated("org.jsonschema2pojo")
#JsonPropertyOrder({ "id", "name", "inward", "outward", "self" })
public class Type
{
#JsonProperty("id")
private String id;
#JsonProperty("name")
private String name;
#JsonProperty("inward")
private String inward;
#JsonProperty("outward")
private String outward;
#JsonProperty("self")
private String self;
The rest client is already up and running. I just need the URL for the retrieval.
I am not sure but I think you are looking for this REST request.
/rest/api/2/issueLinkType
Example :
https://jira.atlassian.com/rest/api/2/issueLinkType
Also you can find documentation here.
https://docs.atlassian.com/jira/REST/latest/
Thanks.

Manually validating a password reset token in ASP.NET Identity

I would like to manually validate a password reset token in ASP.NET Identity 2.0. I'm trying to create my own version of UserManager.ResetPasswordAsync(string userId, string token, string newPassword) that takes and IdentityUser instead of userId like this:
UserManager.ResetPasswordAsync(IdentityUser user, string token, string newPassword)
Not sure if I am doing this right, but here I am attempting to validate the code that was emailed to the user in an earlier step. I have not modified the code/token that sends the email to the user and generates the code. I am assuming this is the correct method to call, but the purpose argument is incorrect. (I tried passing "ASP.NET Identity" but no dice.)
if (await userManager.UserTokenProvider.ValidateAsync(purpose: "?", token: code, manager: userManager, user: user))
{
return IdentityResult.Success;
}
else
{
return new IdentityResult("Invalid code.");
}
If someone could fill me in on the details of how it works out of the box, or point me at Microsoft's source code for UserManager.ResetPasswordAsync(IdentityUser user, string token, string newPassword) that would be most appreciated!
I overcame my problem by setting the purpose to "ResetPassword".
Below is a snippet of the final result in case someone wants to do something similar. It is a method in my ApplicationUserManager class. Realize, though, that some of the exception handling that Microsoft implements is missing or not localized because certain private variables, methods, and resources used in their code are inaccessible. It's unfortunate they did not make that stuff protected so that I could have gotten at it. The missing ThrowIfDisposed method call in particular is interesting (and bazaar) to me. Apparently they are anticipating method calls after an instance has been disposed in order to provide a friendlier error message and avoid the unexpected.
public async Task<IdentityResult> ResetPasswordAsync(IdentityUser user,
string token, string newPassword)
{
if (user == null)
{
throw new ArgumentNullException("user");
}
// Make sure the token is valid and the stamp matches.
if (!await UserTokenProvider.ValidateAsync("ResetPassword", token,
this, user))
{
return IdentityResult.Failed("Invalid token.");
}
// Make sure the new password is valid.
var result = await PasswordValidator.ValidateAsync(newPassword)
.ConfigureAwait(false);
if (!result.Succeeded)
{
return result;
}
// Update the password hash and invalidate the current security stamp.
user.PasswordHash = PasswordHasher.HashPassword(newPassword);
user.SecurityStamp = Guid.NewGuid().ToString();
// Save the user and return the outcome.
return await UpdateAsync(user).ConfigureAwait(false);
}
It appears that the code for Microsoft.AspNet.Identity has not been Open Sourced according to the Codeplex repository located at:
https://aspnetidentity.codeplex.com/SourceControl/latest#Readme.markdown
At present, the ASP.NET Identity framework code is not public and
therefore will not be published on this site. However, we are planning
to change that, and as soon as we are able, the code will be published
in this repository.
However I did find this which might be the source for the UserManager based on the debug symbols:
UserManager Source Code
I also found these posts which might help:
Implementing custom password policy using ASP.NET Identity
UserManager Class Documentation
IUserTokenProvider Interface Documentation

Resources